forked from artix/calamares-extensions
		
	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"
 | 
			
		||||
AllowShortFunctionsOnASingleLine: Inline
 | 
			
		||||
AllowShortIfStatementsOnASingleLine: "false"
 | 
			
		||||
AllowShortLambdasOnASingleLine: All
 | 
			
		||||
AllowShortLoopsOnASingleLine: "false"
 | 
			
		||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
 | 
			
		||||
AlwaysBreakTemplateDeclarations: Yes
 | 
			
		||||
@@ -28,7 +29,6 @@ ReflowComments: "false"
 | 
			
		||||
SortIncludes: "true"
 | 
			
		||||
SpaceAfterCStyleCast: "false"
 | 
			
		||||
SpacesBeforeTrailingComments: "2"
 | 
			
		||||
# SpaceInEmptyBlock: "true"
 | 
			
		||||
SpacesInAngles: "true"
 | 
			
		||||
SpacesInParentheses: "true"
 | 
			
		||||
SpacesInSquareBrackets: "true"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								.clang-format.base
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								.clang-format.base
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: no
 | 
			
		||||
#   SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
---
 | 
			
		||||
BasedOnStyle: WebKit
 | 
			
		||||
 | 
			
		||||
AlignAfterOpenBracket: Align
 | 
			
		||||
AlignEscapedNewlines: DontAlign
 | 
			
		||||
AllowAllParametersOfDeclarationOnNextLine: "false"
 | 
			
		||||
AllowShortFunctionsOnASingleLine: Inline
 | 
			
		||||
AllowShortIfStatementsOnASingleLine: "false"
 | 
			
		||||
AllowShortLambdasOnASingleLine: All
 | 
			
		||||
AllowShortLoopsOnASingleLine: "false"
 | 
			
		||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
 | 
			
		||||
AlwaysBreakTemplateDeclarations: Yes
 | 
			
		||||
BinPackArguments: "false"
 | 
			
		||||
BinPackParameters: "false"
 | 
			
		||||
BreakBeforeBraces: Allman
 | 
			
		||||
BreakBeforeTernaryOperators: "true"
 | 
			
		||||
BreakConstructorInitializers: BeforeComma
 | 
			
		||||
ColumnLimit: 120
 | 
			
		||||
Cpp11BracedListStyle: "false"
 | 
			
		||||
FixNamespaceComments: "true"
 | 
			
		||||
IncludeBlocks: Preserve
 | 
			
		||||
IndentWidth: "4"
 | 
			
		||||
MaxEmptyLinesToKeep: "2"
 | 
			
		||||
NamespaceIndentation: None
 | 
			
		||||
PointerAlignment: Left
 | 
			
		||||
ReflowComments: "false"
 | 
			
		||||
SortIncludes: "true"
 | 
			
		||||
SpaceAfterCStyleCast: "false"
 | 
			
		||||
SpacesBeforeTrailingComments: "2"
 | 
			
		||||
SpacesInAngles: "true"
 | 
			
		||||
SpacesInParentheses: "true"
 | 
			
		||||
SpacesInSquareBrackets: "true"
 | 
			
		||||
Standard: Cpp11
 | 
			
		||||
							
								
								
									
										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/
 | 
			
		||||
build/
 | 
			
		||||
*.kdev4
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								.reuse/dep5
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								.reuse/dep5
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 | 
			
		||||
Upstream-Name: Calamares-Extensions
 | 
			
		||||
Source: https://github.com/calamares/calamares-extensions.git
 | 
			
		||||
 | 
			
		||||
### BUILD ARTIFACTS / NOT SOURCE
 | 
			
		||||
#
 | 
			
		||||
# QRC Files are basically build artifacts
 | 
			
		||||
#
 | 
			
		||||
FILES: modules/*/*.qrc
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
# GitHub issue templates are not part of the source
 | 
			
		||||
#
 | 
			
		||||
Files: .github/ISSUE_TEMPLATE/*
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
# GitHub actions are not part of the source
 | 
			
		||||
Files: .github/workflows/*.yml
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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> ===
 | 
			
		||||
#
 | 
			
		||||
#   Calamares is free software: you can redistribute it and/or modify
 | 
			
		||||
#   it under the terms of the GNU General Public License as published by
 | 
			
		||||
#   the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
#   (at your option) any later version.
 | 
			
		||||
#   SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
#
 | 
			
		||||
#   Calamares is distributed in the hope that it will be useful,
 | 
			
		||||
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | 
			
		||||
#   GNU General Public License for more details.
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
#   You should have received a copy of the GNU General Public License
 | 
			
		||||
#   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
#   Calamares-Examples is Free Software: see the License-Identifier above.
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-License-Identifier: GPL-3.0+
 | 
			
		||||
#   License-Filename: LICENSE
 | 
			
		||||
#   Individual files may have different licenses (like the CMake
 | 
			
		||||
#   infrastructure, which is BSD-2-Clause licensed). Check the SPDX
 | 
			
		||||
#   identifiers in each file.
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
@@ -24,15 +19,73 @@
 | 
			
		||||
# distro can use an unmodified (upstream) Calamares package and a local
 | 
			
		||||
# 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)
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    VERSION 1.0.0
 | 
			
		||||
    VERSION ${CALAMARES_EXTENSIONS_VERSION}
 | 
			
		||||
    LANGUAGES CXX
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
find_package(Calamares 3.2.26 REQUIRED)
 | 
			
		||||
set( CMAKE_CXX_STANDARD 17 )
 | 
			
		||||
set( CMAKE_CXX_STANDARD_REQUIRED ON )
 | 
			
		||||
 | 
			
		||||
# On developer's machine, the user package registry breaks
 | 
			
		||||
# consumers by loading the developer's config from a build
 | 
			
		||||
# directory (which doesn't have the rest of the config
 | 
			
		||||
# installed inside it).
 | 
			
		||||
set( CALAMARES_VERSION_REQUIRED 3.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
 | 
			
		||||
#
 | 
			
		||||
@@ -56,25 +109,16 @@ calamares_add_branding_subdirectory( branding/kaos_branding NAME kaos )
 | 
			
		||||
#
 | 
			
		||||
# Add one of more modules, either C++ or Python.
 | 
			
		||||
#
 | 
			
		||||
set(SKIPPED_MODULES "")
 | 
			
		||||
set(LIST_SKIPPED_MODULES "")
 | 
			
		||||
 | 
			
		||||
calamares_add_module_subdirectory( modules/filekeeper )  # C++ job
 | 
			
		||||
calamares_add_module_subdirectory( modules/freebsddisk )  # C++ viewmodule
 | 
			
		||||
calamares_add_module_subdirectory( modules/mobile )
 | 
			
		||||
calamares_add_module_subdirectory( modules/slowpython )  # Python job
 | 
			
		||||
calamares_add_module_subdirectory( modules/freebsddisk LIST_SKIPPED_MODULES )  # C++ viewmodule
 | 
			
		||||
calamares_add_module_subdirectory( modules/mobile LIST_SKIPPED_MODULES )
 | 
			
		||||
calamares_add_module_subdirectory( modules/os-freebsd LIST_SKIPPED_MODULES )
 | 
			
		||||
calamares_add_module_subdirectory( modules/os-nixos LIST_SKIPPED_MODULES )
 | 
			
		||||
calamares_add_module_subdirectory( modules/refind LIST_SKIPPED_MODULES )
 | 
			
		||||
calamares_add_module_subdirectory( modules/slowpython LIST_SKIPPED_MODULES )  # Python job
 | 
			
		||||
calamares_add_module_subdirectory( modules/unpackfsc LIST_SKIPPED_MODULES )
 | 
			
		||||
 | 
			
		||||
# If modules cannot be built, they usually call a macro
 | 
			
		||||
# which builds a list of explanations; show that list.
 | 
			
		||||
calamares_explain_skipped_modules( ${SKIPPED_MODULES} )
 | 
			
		||||
 | 
			
		||||
set( CALAMARES_VERSION ${calamares-extensions_VERSION_MAJOR}.${calamares-extensions_VERSION_MINOR}.${calamares-extensions_VERSION_PATCH} )
 | 
			
		||||
# In rare cases we have hotfix-releases with a tweak
 | 
			
		||||
if( calamares-extensions_VERSION_TWEAK )
 | 
			
		||||
    set( CALAMARES_VERSION "${calamares-extensions_VERSION}.${calamares-extensions_VERSION_TWEAK}" )
 | 
			
		||||
endif()
 | 
			
		||||
set( CALAMARES_VERSION_SHORT "${CALAMARES_VERSION}" )
 | 
			
		||||
 | 
			
		||||
add_custom_target(show-version
 | 
			
		||||
    ${CMAKE_COMMAND} -E echo CALAMARES_VERSION=${CALAMARES_VERSION_SHORT}
 | 
			
		||||
    USES_TERMINAL
 | 
			
		||||
)
 | 
			
		||||
calamares_explain_skipped_modules( ${LIST_SKIPPED_MODULES} )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										90
									
								
								CMakeModules/ExtendedVersion.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								CMakeModules/ExtendedVersion.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
 | 
			
		||||
#   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# This file defines one function for extending a VERSION-like value
 | 
			
		||||
# with date and git information (if desired).
 | 
			
		||||
#
 | 
			
		||||
# - extend_version( version-string short_var long_var )
 | 
			
		||||
#   Calling this function will copy *version-string* (which would typically
 | 
			
		||||
#   be a semver-style string, like "3.2.40") into the variable *short_var*.
 | 
			
		||||
#   The *version-string* plus date and git information (if git is available),
 | 
			
		||||
#   is copied into the varialbe *long_var*, in the format {version}-{date}-{hash}
 | 
			
		||||
#
 | 
			
		||||
# A helper function that may be used independently:
 | 
			
		||||
#
 | 
			
		||||
# - get_git_version_info( out_var )
 | 
			
		||||
#   If relevant and possible (e.g. it is a git checkout and git is availablle
 | 
			
		||||
#   in the environment), put git versioning information in *out_var*.
 | 
			
		||||
#
 | 
			
		||||
# A convenience function for use from script-mode for version reporting:
 | 
			
		||||
#
 | 
			
		||||
# - report_version( version top_dir )
 | 
			
		||||
#   Call this with an intended version string (e.g. "1.1") and
 | 
			
		||||
#   the top-level source directory (e.g. `${CMAKE_CURRENT_LIST_DIR}`
 | 
			
		||||
#   or `${CMAKE_SOURCE_DIR}` .. in script mode, the latter is not defined).
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
function( get_git_version_info out_var )
 | 
			
		||||
    set(CMAKE_VERSION_SOURCE "")
 | 
			
		||||
    if(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD)
 | 
			
		||||
        find_program(GIT_EXECUTABLE NAMES git git.cmd)
 | 
			
		||||
        mark_as_advanced(GIT_EXECUTABLE)
 | 
			
		||||
        if(GIT_EXECUTABLE)
 | 
			
		||||
            execute_process(
 | 
			
		||||
                COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=8 HEAD
 | 
			
		||||
                OUTPUT_VARIABLE head
 | 
			
		||||
                OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
                WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
            )
 | 
			
		||||
            if(head)
 | 
			
		||||
                set(CMAKE_VERSION_SOURCE "${head}")
 | 
			
		||||
                execute_process(
 | 
			
		||||
                    COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
 | 
			
		||||
                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
                )
 | 
			
		||||
                execute_process(
 | 
			
		||||
                    COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
 | 
			
		||||
                    OUTPUT_VARIABLE dirty
 | 
			
		||||
                    OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
                )
 | 
			
		||||
                if(dirty)
 | 
			
		||||
                    set(CMAKE_VERSION_SOURCE "${CMAKE_VERSION_SOURCE}-dirty")
 | 
			
		||||
                endif()
 | 
			
		||||
            endif()
 | 
			
		||||
        endif()
 | 
			
		||||
    endif()
 | 
			
		||||
    set( ${out_var} "${CMAKE_VERSION_SOURCE}" PARENT_SCOPE )
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
function( extend_version version short_var long_var )
 | 
			
		||||
    set( ${short_var} "${version}" PARENT_SCOPE )
 | 
			
		||||
 | 
			
		||||
    # Additional info for non-release builds which want "long" version info
 | 
			
		||||
    # with date and git information (commit, dirty status).
 | 
			
		||||
    set( _v "${version}" )
 | 
			
		||||
    string( TIMESTAMP CALAMARES_VERSION_DATE "%Y%m%d" )
 | 
			
		||||
    if( CALAMARES_VERSION_DATE GREATER 0 )
 | 
			
		||||
        set( _v ${_v}.${CALAMARES_VERSION_DATE} )
 | 
			
		||||
    endif()
 | 
			
		||||
    get_git_version_info( _gitv )
 | 
			
		||||
    if( _gitv )
 | 
			
		||||
        set( _v "${_v}-${_gitv}" )
 | 
			
		||||
    endif()
 | 
			
		||||
    set( ${long_var} "${_v}" PARENT_SCOPE )
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
function( report_version version top_dir )
 | 
			
		||||
    set( CMAKE_SOURCE_DIR ${top_dir} )
 | 
			
		||||
    extend_version( ${version} _vshort _vlong )
 | 
			
		||||
    if ( "x${VERSION_STYLE}" STREQUAL "xshort" )
 | 
			
		||||
        message( "${_vshort}" )
 | 
			
		||||
    else()
 | 
			
		||||
        message( "${_vlong}" )
 | 
			
		||||
    endif()
 | 
			
		||||
endfunction()
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||
> 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.
 | 
			
		||||
> 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++)
 | 
			
		||||
> if there is one. Both C++ and Python allow a full control over the
 | 
			
		||||
> target system during the installation.
 | 
			
		||||
@@ -13,13 +18,9 @@ This repository contains complete examples of branding and some
 | 
			
		||||
modules for Calamares.
 | 
			
		||||
 | 
			
		||||
- [Branding](#branding) documentation
 | 
			
		||||
  - [default](branding/default/branding.desc) branding example
 | 
			
		||||
  - [fancy](branding/fancy/branding.desc) branding example
 | 
			
		||||
  - [KaOS](branding/kaos_branding/branding.desc) branding example
 | 
			
		||||
  - [SameGame](branding/samegame/branding.desc) branding example
 | 
			
		||||
- [Module](#module) documentation
 | 
			
		||||
  
 | 
			
		||||
## Branding 
 | 
			
		||||
- [Module](#modules) documentation
 | 
			
		||||
 | 
			
		||||
## Branding
 | 
			
		||||
 | 
			
		||||
> 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
 | 
			
		||||
and documentation for the framework that Calamares ships with.
 | 
			
		||||
 | 
			
		||||
 - `default/` is a copy of the default branding included with Calamares.
 | 
			
		||||
 - `fancy/` has navigation buttons and a slide counter.
 | 
			
		||||
 - `kaos_branding/` is a copy of the KaOS branding component, which
 | 
			
		||||
 - [`default/`](branding/default/branding.desc)
 | 
			
		||||
   is a copy of the default branding included with Calamares.
 | 
			
		||||
 - [`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.
 | 
			
		||||
 - `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.
 | 
			
		||||
 | 
			
		||||
### Writing your own Branding
 | 
			
		||||
@@ -62,7 +72,7 @@ and documentation for the framework that Calamares ships with.
 | 
			
		||||
  parts of Calamares.
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
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
 | 
			
		||||
build the translations first (using Qt Linguist `lrelease`, or by
 | 
			
		||||
using the normal build system for branding components).
 | 
			
		||||
@@ -87,7 +97,7 @@ qmlscene \
 | 
			
		||||
    -translation build/calamares-fancy_nl.qm \
 | 
			
		||||
    -I /usr/local/share/calamares/qml \
 | 
			
		||||
    -geometry 600x400 \
 | 
			
		||||
    fancy/show.qml 
 | 
			
		||||
    fancy/show.qml
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This starts the viewer with the Dutch (nl) translation, using the
 | 
			
		||||
@@ -104,25 +114,39 @@ every time.
 | 
			
		||||
### Calamares Branding API
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
  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
 | 
			
		||||
  started. This may delay startup a little, but may appear more
 | 
			
		||||
  started. This may delay startup a little, but appears more
 | 
			
		||||
  responsive overall.
 | 
			
		||||
 | 
			
		||||
If the slideshow QML defines functions
 | 
			
		||||
`onActivate()` and `onLeave()` then those functions
 | 
			
		||||
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
 | 
			
		||||
whatever. 
 | 
			
		||||
whatever.
 | 
			
		||||
 | 
			
		||||
In addition, if the slideshow QML defines a property
 | 
			
		||||
`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
 | 
			
		||||
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
 | 
			
		||||
@@ -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*
 | 
			
		||||
phase).
 | 
			
		||||
 | 
			
		||||
### Example Modules
 | 
			
		||||
 | 
			
		||||
- [filekeeper](modules/filekeeper/CMakeLists.txt) is a C++ **job** module
 | 
			
		||||
  to copy files from the host (live) system to the target system at
 | 
			
		||||
  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
 | 
			
		||||
  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
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
[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 )
 | 
			
		||||
   list( APPEND TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/calamares-${COMPONENT_NAME}_${lang}.ts" )
 | 
			
		||||
endforeach()
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@
 | 
			
		||||
# NOTE: this is largely a copy of the release script for Calamares,
 | 
			
		||||
#       with not-applicable parts (such as translation-freeze) either
 | 
			
		||||
#       commented-out, or skipped with if(false).
 | 
			
		||||
# NOTE: this script contains Linuxisms (in particular, expects GNU mktemp(1))
 | 
			
		||||
#
 | 
			
		||||
# This attempts to perform the different steps of the RELEASE.md
 | 
			
		||||
# document automatically. It's not tested on other machines or
 | 
			
		||||
@@ -31,6 +32,7 @@
 | 
			
		||||
#   * `-B` do not build (before tagging)
 | 
			
		||||
#   * `-P` do not package (tag, sign, tarball)
 | 
			
		||||
#   * `-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:
 | 
			
		||||
#   * BUILD_DEFAULT set to `false` to avoid first build with gcc
 | 
			
		||||
@@ -138,24 +140,28 @@ fi
 | 
			
		||||
### Get version number for this release
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
V=$( cd "$BUILDDIR" && make show-version | grep ^CALAMARES_VERSION | sed s/^[A-Z_]*=// )
 | 
			
		||||
V=$( cmake -DVERSION_STYLE=short -P CMakeLists.txt 2>&1 )
 | 
			
		||||
test -n "$V" || { echo "Could not obtain version in $BUILDDIR ." ; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
### Create signed tag
 | 
			
		||||
#
 | 
			
		||||
# This is the signing key ID associated with the GitHub account adriaandegroot,
 | 
			
		||||
# which is used to create all "verified" tags in the Calamares repo.
 | 
			
		||||
#
 | 
			
		||||
KEY_ID="CFDDC96F12B1915C"
 | 
			
		||||
git tag -u "$KEY_ID" -m "Release v$V" "v$V" || { echo "Could not sign tag v$V." ; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
### Create the tarball
 | 
			
		||||
#
 | 
			
		||||
# Create the tarball, compute SHA256 for later reporting, and
 | 
			
		||||
# sign the tarball so the signature can be uploaded separately.
 | 
			
		||||
#
 | 
			
		||||
TAR_V="$TARBALL_PREFIX-$V"
 | 
			
		||||
TAR_FILE="$TAR_V.tar.gz"
 | 
			
		||||
git archive -o "$TAR_FILE" --prefix "$TAR_V/" "v$V" || { echo "Could not create tarball." ; exit 1 ; }
 | 
			
		||||
test -f "$TAR_FILE" || { echo "Tarball was not created." ; exit 1 ; }
 | 
			
		||||
SHA256=$(sha256sum "$TAR_FILE" | cut -d" " -f1)
 | 
			
		||||
gpg -s -u $KEY_ID --detach --armor $TAR_FILE  # Sign the tarball
 | 
			
		||||
 | 
			
		||||
### Build the tarball
 | 
			
		||||
#
 | 
			
		||||
@@ -181,7 +187,6 @@ rm -rf "$TMPDIR"  # From tarball
 | 
			
		||||
cat <<EOF
 | 
			
		||||
# Next steps for this release:
 | 
			
		||||
  git push origin v$V
 | 
			
		||||
  gpg -s -u $KEY_ID --detach --armor $TAR_FILE  # Sign the tarball
 | 
			
		||||
  # Upload tarball $TAR_FILE and the signature $TAR_FILE.asc
 | 
			
		||||
  # Announce via https://github.com/calamares/$PROJECT_NAME/releases/new
 | 
			
		||||
  # SHA256: $SHA256
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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 )
 | 
			
		||||
    calamares_skip_module( "freebsddisk (QML is not supported in this build)" )
 | 
			
		||||
    return()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,6 @@
 | 
			
		||||
# SPDX-FileCopyrightText: no
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
# The *freebsddisk* module can be used to pick a disk
 | 
			
		||||
# as an installer step. This module supports ZFSroot
 | 
			
		||||
# on one whole disk, and UFSroot on one whole disk.
 | 
			
		||||
 
 | 
			
		||||
@@ -6,13 +6,9 @@ calamares_add_plugin( mobile
 | 
			
		||||
    EXPORT_MACRO PLUGINDLLEXPORT_PRO
 | 
			
		||||
    SOURCES
 | 
			
		||||
        Config.cpp
 | 
			
		||||
        Config.h
 | 
			
		||||
        MobileQmlViewStep.cpp
 | 
			
		||||
        MobileQmlViewStep.h
 | 
			
		||||
        PartitionJob.cpp
 | 
			
		||||
        PartitionJob.h
 | 
			
		||||
        UsersJob.cpp
 | 
			
		||||
        UsersJob.h
 | 
			
		||||
    RESOURCES
 | 
			
		||||
        mobile.qrc
 | 
			
		||||
    SHARED_LIB
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,13 @@
 | 
			
		||||
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
 | 
			
		||||
 * SPDX-License-Identifier: GPL-3.0-or-later */
 | 
			
		||||
#include "Config.h"
 | 
			
		||||
#include "PartitionJob.h"
 | 
			
		||||
#include "UsersJob.h"
 | 
			
		||||
 | 
			
		||||
#include "ViewManager.h"
 | 
			
		||||
#include "utils/Logger.h"
 | 
			
		||||
#include "utils/Variant.h"
 | 
			
		||||
 | 
			
		||||
#include <QVariant>
 | 
			
		||||
 | 
			
		||||
Config::Config( QObject* parent )
 | 
			
		||||
@@ -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
 | 
			
		||||
Config::setConfigurationMap( const QVariantMap& cfgMap )
 | 
			
		||||
{
 | 
			
		||||
    m_osName = cfgStr( cfgMap, "osName", "(unknown)" );
 | 
			
		||||
    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" );
 | 
			
		||||
    using namespace CalamaresUtils;
 | 
			
		||||
 | 
			
		||||
    m_cmdLuksFormat = cfgStr( cfgMap, "cmdLuksFormat", "cryptsetup luksFormat --use-random" );
 | 
			
		||||
    m_cmdLuksOpen = cfgStr( cfgMap, "cmdLuksOpen", "cryptsetup luksOpen" );
 | 
			
		||||
    m_cmdMkfsRoot = cfgStr( cfgMap, "cmdMkfsRoot", "mkfs.ext4 -L 'unknownOS_root'" );
 | 
			
		||||
    m_cmdMount = cfgStr( cfgMap, "cmdMount", "mount" );
 | 
			
		||||
    m_targetDeviceRoot = cfgStr( cfgMap, "targetDeviceRoot", "/dev/unknown" );
 | 
			
		||||
    if ( getBool( cfgMap, "bogus", false ) )
 | 
			
		||||
    {
 | 
			
		||||
        cWarning() << "Configuration key \"bogus\" is still set for *mobile*";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_cmdPasswd = cfgStr( cfgMap, "cmdPasswd", "passwd" );
 | 
			
		||||
    m_cmdSshdEnable = cfgStr( cfgMap, "cmdSshdEnable", "systemctl enable sshd.service" );
 | 
			
		||||
    m_cmdSshdDisable = cfgStr( cfgMap, "cmdSshdDisable", "systemctl disable sshd.service" );
 | 
			
		||||
    m_cmdSshdUseradd = cfgStr( cfgMap, "cmdSshdUseradd", "useradd -G wheel -m" );
 | 
			
		||||
    m_osName = getString( cfgMap, "osName", "(unknown)" );
 | 
			
		||||
    m_arch = getString( cfgMap, "arch", "(unknown)" );
 | 
			
		||||
    m_device = getString( cfgMap, "device", "(unknown)" );
 | 
			
		||||
    m_userInterface = getString( cfgMap, "userInterface", "(unknown)" );
 | 
			
		||||
    m_version = getString( cfgMap, "version", "(unknown)" );
 | 
			
		||||
    m_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
 | 
			
		||||
@@ -80,3 +171,34 @@ Config::setIsFdeEnabled( const bool isFdeEnabled )
 | 
			
		||||
{
 | 
			
		||||
    m_isFdeEnabled = isFdeEnabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Config::setInstallFromExternalToInternal( const bool val )
 | 
			
		||||
{
 | 
			
		||||
    m_installFromExternalToInternal = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Config::setFsType( int idx )
 | 
			
		||||
{
 | 
			
		||||
    if ( idx >= 0 && idx < m_fsList.length() )
 | 
			
		||||
    {
 | 
			
		||||
        setFsType( m_fsList[ idx ] );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
void
 | 
			
		||||
Config::setFsType( const QString& fsType )
 | 
			
		||||
{
 | 
			
		||||
    if ( fsType != m_fsType )
 | 
			
		||||
    {
 | 
			
		||||
        m_fsType = fsType;
 | 
			
		||||
        emit fsTypeChanged( m_fsType );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Config::setFsIndex( const int fsIndex )
 | 
			
		||||
{
 | 
			
		||||
    m_fsIndex = fsIndex;
 | 
			
		||||
    emit fsIndexChanged( m_fsIndex );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,18 @@
 | 
			
		||||
/* SPDX-FileCopyrightText: 2020 Oliver Smith <ollieparanoid@postmarketos.org>
 | 
			
		||||
 * SPDX-License-Identifier: GPL-3.0-or-later */
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Job.h"
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
class Config : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
    /* installer UI */
 | 
			
		||||
    Q_PROPERTY( bool builtinVirtualKeyboard READ builtinVirtualKeyboard CONSTANT FINAL )
 | 
			
		||||
 | 
			
		||||
    /* welcome */
 | 
			
		||||
    Q_PROPERTY( QString osName READ osName CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString arch READ arch CONSTANT FINAL )
 | 
			
		||||
@@ -17,8 +23,10 @@ class Config : public QObject
 | 
			
		||||
    /* default user */
 | 
			
		||||
    Q_PROPERTY( QString username READ username CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString userPassword READ userPassword WRITE setUserPassword NOTIFY userPasswordChanged )
 | 
			
		||||
    Q_PROPERTY( bool userPasswordNumeric READ userPasswordNumeric CONSTANT FINAL )
 | 
			
		||||
 | 
			
		||||
    /* ssh server + credentials */
 | 
			
		||||
    Q_PROPERTY( bool featureSshd READ featureSshd CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString sshdUsername READ sshdUsername WRITE setSshdUsername NOTIFY sshdUsernameChanged )
 | 
			
		||||
    Q_PROPERTY( QString sshdPassword READ sshdPassword WRITE setSshdPassword NOTIFY sshdPasswordChanged )
 | 
			
		||||
    Q_PROPERTY( bool isSshEnabled READ isSshEnabled WRITE setIsSshEnabled )
 | 
			
		||||
@@ -27,12 +35,23 @@ class Config : public QObject
 | 
			
		||||
    Q_PROPERTY( QString fdePassword READ fdePassword WRITE setFdePassword NOTIFY fdePasswordChanged )
 | 
			
		||||
    Q_PROPERTY( bool isFdeEnabled READ isFdeEnabled WRITE setIsFdeEnabled )
 | 
			
		||||
 | 
			
		||||
    /* filesystem selection */
 | 
			
		||||
    Q_PROPERTY( QString fsType READ fsType WRITE setFsType NOTIFY fsTypeChanged )
 | 
			
		||||
    Q_PROPERTY( bool featureFsType READ featureFsType CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QStringList fsList READ fsList CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString defaultFs READ defaultFs CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( int fsIndex READ fsIndex WRITE setFsIndex NOTIFY fsIndexChanged )
 | 
			
		||||
 | 
			
		||||
    /* partition job */
 | 
			
		||||
    Q_PROPERTY( bool runPartitionJobThenLeave READ runPartitionJobThenLeaveDummy WRITE runPartitionJobThenLeave )
 | 
			
		||||
    Q_PROPERTY( QString cmdInternalStoragePrepare READ cmdInternalStoragePrepare CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString cmdLuksFormat READ cmdLuksFormat CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString cmdLuksOpen READ cmdLuksOpen CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString cmdMkfsRoot READ cmdMkfsRoot CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString cmdMount READ cmdMount CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString targetDeviceRoot READ targetDeviceRoot CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString targetDeviceRootInternal READ targetDeviceRootInternal CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY(
 | 
			
		||||
        bool installFromExternalToInternal READ installFromExternalToInternal WRITE setInstallFromExternalToInternal )
 | 
			
		||||
 | 
			
		||||
    /* users job */
 | 
			
		||||
    Q_PROPERTY( QString cmdSshdEnable READ cmdSshdEnable CONSTANT FINAL )
 | 
			
		||||
@@ -41,6 +60,10 @@ class Config : public QObject
 | 
			
		||||
public:
 | 
			
		||||
    Config( QObject* parent = nullptr );
 | 
			
		||||
    void setConfigurationMap( const QVariantMap& );
 | 
			
		||||
    Calamares::JobList createJobs();
 | 
			
		||||
 | 
			
		||||
    /* installer UI */
 | 
			
		||||
    bool builtinVirtualKeyboard() { return m_builtinVirtualKeyboard; }
 | 
			
		||||
 | 
			
		||||
    /* welcome */
 | 
			
		||||
    QString osName() const { return m_osName; }
 | 
			
		||||
@@ -53,8 +76,10 @@ public:
 | 
			
		||||
    QString username() const { return m_username; }
 | 
			
		||||
    QString userPassword() const { return m_userPassword; }
 | 
			
		||||
    void setUserPassword( const QString& userPassword );
 | 
			
		||||
    bool userPasswordNumeric() const { return m_userPasswordNumeric; }
 | 
			
		||||
 | 
			
		||||
    /* ssh server + credetials */
 | 
			
		||||
    bool featureSshd() { return m_featureSshd; }
 | 
			
		||||
    QString sshdUsername() const { return m_sshdUsername; }
 | 
			
		||||
    QString sshdPassword() const { return m_sshdPassword; }
 | 
			
		||||
    bool isSshEnabled() { return m_isSshEnabled; }
 | 
			
		||||
@@ -68,12 +93,30 @@ public:
 | 
			
		||||
    void setFdePassword( const QString& fdePassword );
 | 
			
		||||
    void setIsFdeEnabled( bool isFdeEnabled );
 | 
			
		||||
 | 
			
		||||
    /* filesystem selection */
 | 
			
		||||
    bool featureFsType() { return m_featureFsType; };
 | 
			
		||||
    QString fsType() const { return m_fsType; };
 | 
			
		||||
    void setFsType( int idx );
 | 
			
		||||
    void setFsType( const QString& fsType );
 | 
			
		||||
    QStringList fsList() const { return m_fsList; };
 | 
			
		||||
    int fsIndex() const { return m_fsIndex; };
 | 
			
		||||
    void setFsIndex( const int fsIndex );
 | 
			
		||||
    QString defaultFs() const { return m_defaultFs; };
 | 
			
		||||
 | 
			
		||||
    /* partition job */
 | 
			
		||||
    bool runPartitionJobThenLeaveDummy() { return 0; }
 | 
			
		||||
    void runPartitionJobThenLeave( bool b );
 | 
			
		||||
    QString cmdInternalStoragePrepare() const { return m_cmdInternalStoragePrepare; }
 | 
			
		||||
    QString cmdLuksFormat() const { return m_cmdLuksFormat; }
 | 
			
		||||
    QString cmdLuksOpen() const { return m_cmdLuksOpen; }
 | 
			
		||||
    QString 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 targetDeviceRoot() const { return m_targetDeviceRoot; }
 | 
			
		||||
    QString targetDeviceRootInternal() const { return m_targetDeviceRootInternal; }
 | 
			
		||||
    bool installFromExternalToInternal() { return m_installFromExternalToInternal; }
 | 
			
		||||
    void setInstallFromExternalToInternal( const bool val );
 | 
			
		||||
 | 
			
		||||
    /* users job */
 | 
			
		||||
    QString cmdPasswd() const { return m_cmdPasswd; }
 | 
			
		||||
@@ -82,6 +125,9 @@ public:
 | 
			
		||||
    QString cmdSshdUseradd() const { return m_cmdSshdUseradd; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    /* installer UI */
 | 
			
		||||
    bool m_builtinVirtualKeyboard;
 | 
			
		||||
 | 
			
		||||
    /* welcome */
 | 
			
		||||
    QString m_osName;
 | 
			
		||||
    QString m_arch;
 | 
			
		||||
@@ -92,22 +138,37 @@ private:
 | 
			
		||||
    /* default user */
 | 
			
		||||
    QString m_username;
 | 
			
		||||
    QString m_userPassword;
 | 
			
		||||
    bool m_userPasswordNumeric;
 | 
			
		||||
 | 
			
		||||
    /* ssh server + credetials */
 | 
			
		||||
    /* ssh server + credentials */
 | 
			
		||||
    bool m_featureSshd = false;
 | 
			
		||||
    QString m_sshdUsername;
 | 
			
		||||
    QString m_sshdPassword;
 | 
			
		||||
    bool m_isSshEnabled;
 | 
			
		||||
    bool m_isSshEnabled = false;
 | 
			
		||||
 | 
			
		||||
    /* full disk encryption */
 | 
			
		||||
    QString m_fdePassword = "";
 | 
			
		||||
    QString m_fdePassword;
 | 
			
		||||
    bool m_isFdeEnabled = false;
 | 
			
		||||
 | 
			
		||||
    /* filesystem selection */
 | 
			
		||||
    bool m_featureFsType = false;
 | 
			
		||||
    QString m_defaultFs;
 | 
			
		||||
    QString m_fsType;
 | 
			
		||||
    // Index of the currently selected filesystem in UI.
 | 
			
		||||
    int m_fsIndex = -1;
 | 
			
		||||
    QStringList m_fsList;
 | 
			
		||||
 | 
			
		||||
    /* partition job */
 | 
			
		||||
    QString m_cmdInternalStoragePrepare;
 | 
			
		||||
    QString m_cmdLuksFormat;
 | 
			
		||||
    QString m_cmdLuksOpen;
 | 
			
		||||
    QString m_cmdMkfsRoot;
 | 
			
		||||
    QString m_cmdMkfsRootBtrfs;
 | 
			
		||||
    QString m_cmdMkfsRootExt4;
 | 
			
		||||
    QString m_cmdMkfsRootF2fs;
 | 
			
		||||
    QString m_cmdMount;
 | 
			
		||||
    QString m_targetDeviceRoot;
 | 
			
		||||
    QString m_targetDeviceRootInternal;
 | 
			
		||||
    bool m_installFromExternalToInternal = false;
 | 
			
		||||
 | 
			
		||||
    /* users job */
 | 
			
		||||
    QString m_cmdPasswd;
 | 
			
		||||
@@ -116,14 +177,18 @@ private:
 | 
			
		||||
    QString m_cmdSshdUseradd;
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    /* booleans we don't read from QML (like isSshEnabled) don't need a signal */
 | 
			
		||||
 | 
			
		||||
    /* default user */
 | 
			
		||||
    void userPasswordChanged( QString userPassword );
 | 
			
		||||
 | 
			
		||||
    /* ssh server + credetials */
 | 
			
		||||
    /* ssh server + credentials */
 | 
			
		||||
    void sshdUsernameChanged( QString sshdUsername );
 | 
			
		||||
    void sshdPasswordChanged( QString sshdPassword );
 | 
			
		||||
    /* isSshEnabled doesn't need a signal, we don't read it from QML */
 | 
			
		||||
 | 
			
		||||
    /* full disk encryption */
 | 
			
		||||
    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-License-Identifier: GPL-3.0-or-later */
 | 
			
		||||
#include "MobileQmlViewStep.h"
 | 
			
		||||
#include "PartitionJob.h"
 | 
			
		||||
#include "UsersJob.h"
 | 
			
		||||
 | 
			
		||||
#include "Branding.h"
 | 
			
		||||
#include "GlobalStorage.h"
 | 
			
		||||
#include "JobQueue.h"
 | 
			
		||||
 | 
			
		||||
#include "locale/LabelModel.h"
 | 
			
		||||
#include "locale/TranslationsModel.h"
 | 
			
		||||
#include "modulesystem/ModuleManager.h"
 | 
			
		||||
#include "utils/Dirs.h"
 | 
			
		||||
#include "utils/Logger.h"
 | 
			
		||||
#include "utils/Variant.h"
 | 
			
		||||
 | 
			
		||||
#include "Branding.h"
 | 
			
		||||
#include "modulesystem/ModuleManager.h"
 | 
			
		||||
 | 
			
		||||
#include <QProcess>
 | 
			
		||||
 | 
			
		||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( MobileQmlViewStepFactory, registerPlugin< MobileQmlViewStep >(); )
 | 
			
		||||
@@ -35,34 +30,7 @@ MobileQmlViewStep::MobileQmlViewStep( QObject* parent )
 | 
			
		||||
void
 | 
			
		||||
MobileQmlViewStep::onLeave()
 | 
			
		||||
{
 | 
			
		||||
    Calamares::Job *partition, *users;
 | 
			
		||||
 | 
			
		||||
    /* 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 ) );
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
@@ -95,7 +63,7 @@ MobileQmlViewStep::isAtEnd() const
 | 
			
		||||
Calamares::JobList
 | 
			
		||||
MobileQmlViewStep::jobs() const
 | 
			
		||||
{
 | 
			
		||||
    return m_jobs;
 | 
			
		||||
    return m_config->createJobs();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QObject*
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,6 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Config* m_config;
 | 
			
		||||
    QList< Calamares::job_ptr > m_jobs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( MobileQmlViewStepFactory )
 | 
			
		||||
 
 | 
			
		||||
@@ -12,19 +12,25 @@
 | 
			
		||||
#include <QFileInfo>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PartitionJob::PartitionJob( QString cmdLuksFormat,
 | 
			
		||||
                            QString cmdLuksOpen,
 | 
			
		||||
                            QString cmdMkfsRoot,
 | 
			
		||||
                            QString cmdMount,
 | 
			
		||||
                            QString targetDeviceRoot,
 | 
			
		||||
PartitionJob::PartitionJob( const QString& cmdInternalStoragePrepare,
 | 
			
		||||
                            const QString& cmdLuksFormat,
 | 
			
		||||
                            const QString& cmdLuksOpen,
 | 
			
		||||
                            const QString& cmdMkfsRoot,
 | 
			
		||||
                            const QString& cmdMount,
 | 
			
		||||
                            const QString& targetDeviceRoot,
 | 
			
		||||
                            const QString& targetDeviceRootInternal,
 | 
			
		||||
                            bool installFromExternalToInternal,
 | 
			
		||||
                            bool isFdeEnabled,
 | 
			
		||||
                            const QString& password )
 | 
			
		||||
    : Calamares::Job()
 | 
			
		||||
    , m_cmdInternalStoragePrepare( cmdInternalStoragePrepare )
 | 
			
		||||
    , m_cmdLuksFormat( cmdLuksFormat )
 | 
			
		||||
    , m_cmdLuksOpen( cmdLuksOpen )
 | 
			
		||||
    , m_cmdMkfsRoot( cmdMkfsRoot )
 | 
			
		||||
    , m_cmdMount( cmdMount )
 | 
			
		||||
    , m_targetDeviceRoot( targetDeviceRoot )
 | 
			
		||||
    , m_targetDeviceRootInternal( targetDeviceRootInternal )
 | 
			
		||||
    , m_installFromExternalToInternal( installFromExternalToInternal )
 | 
			
		||||
    , m_isFdeEnabled( isFdeEnabled )
 | 
			
		||||
    , m_password( password )
 | 
			
		||||
{
 | 
			
		||||
@@ -77,10 +83,18 @@ PartitionJob::exec()
 | 
			
		||||
    QString cryptDev = "/dev/mapper/" + cryptName;
 | 
			
		||||
    QString passwordStdin = m_password + "\n";
 | 
			
		||||
    QString dev = m_targetDeviceRoot;
 | 
			
		||||
    QList< QPair< QStringList, QString > > commands = {};
 | 
			
		||||
 | 
			
		||||
    QList< QPair< QStringList, QString > > commands = {
 | 
			
		||||
        { { "mkdir", "-p", pathMount }, QString() },
 | 
			
		||||
    };
 | 
			
		||||
    if ( m_installFromExternalToInternal )
 | 
			
		||||
    {
 | 
			
		||||
        dev = m_targetDeviceRootInternal;
 | 
			
		||||
 | 
			
		||||
        commands.append( {
 | 
			
		||||
            { { "sh", "-c", m_cmdInternalStoragePrepare }, QString() },
 | 
			
		||||
        } );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    commands.append( { { { "mkdir", "-p", pathMount }, QString() } } );
 | 
			
		||||
 | 
			
		||||
    if ( m_isFdeEnabled )
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,11 +8,14 @@ class PartitionJob : public Calamares::Job
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    PartitionJob( QString cmdLuksFormat,
 | 
			
		||||
                  QString cmdLuksOpen,
 | 
			
		||||
                  QString cmdMkfsRoot,
 | 
			
		||||
                  QString cmdMount,
 | 
			
		||||
                  QString targetDeviceRoot,
 | 
			
		||||
    PartitionJob( const QString& cmdInternalStoragePrepare,
 | 
			
		||||
                  const QString& cmdLuksFormat,
 | 
			
		||||
                  const QString& cmdLuksOpen,
 | 
			
		||||
                  const QString& cmdMkfsRoot,
 | 
			
		||||
                  const QString& cmdMount,
 | 
			
		||||
                  const QString& targetDeviceRoot,
 | 
			
		||||
                  const QString& targetDeviceRootInternal,
 | 
			
		||||
                  bool installFromExternalToInternal,
 | 
			
		||||
                  bool isFdeEnabled,
 | 
			
		||||
                  const QString& password );
 | 
			
		||||
 | 
			
		||||
@@ -22,11 +25,14 @@ public:
 | 
			
		||||
    Calamares::JobList createJobs();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QString m_cmdInternalStoragePrepare;
 | 
			
		||||
    QString m_cmdLuksFormat;
 | 
			
		||||
    QString m_cmdLuksOpen;
 | 
			
		||||
    QString m_cmdMkfsRoot;
 | 
			
		||||
    QString m_cmdMount;
 | 
			
		||||
    QString m_targetDeviceRoot;
 | 
			
		||||
    QString m_targetDeviceRootInternal;
 | 
			
		||||
    bool m_installFromExternalToInternal;
 | 
			
		||||
    bool m_isFdeEnabled;
 | 
			
		||||
    QString m_password;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -12,15 +12,17 @@
 | 
			
		||||
#include <QFileInfo>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
UsersJob::UsersJob( QString cmdPasswd,
 | 
			
		||||
                    QString cmdSshd,
 | 
			
		||||
                    QString cmdSshdUseradd,
 | 
			
		||||
UsersJob::UsersJob( bool featureSshd,
 | 
			
		||||
                    const QString& cmdPasswd,
 | 
			
		||||
                    const QString& cmdSshd,
 | 
			
		||||
                    const QString& cmdSshdUseradd,
 | 
			
		||||
                    bool isSshEnabled,
 | 
			
		||||
                    QString username,
 | 
			
		||||
                    QString password,
 | 
			
		||||
                    QString sshdUsername,
 | 
			
		||||
                    QString sshdPassword )
 | 
			
		||||
                    const QString& username,
 | 
			
		||||
                    const QString& password,
 | 
			
		||||
                    const QString& sshdUsername,
 | 
			
		||||
                    const QString& sshdPassword )
 | 
			
		||||
    : Calamares::Job()
 | 
			
		||||
    , m_featureSshd( featureSshd )
 | 
			
		||||
    , m_cmdPasswd( cmdPasswd )
 | 
			
		||||
    , m_cmdSshd( cmdSshd )
 | 
			
		||||
    , m_cmdSshdUseradd( cmdSshdUseradd )
 | 
			
		||||
@@ -48,14 +50,18 @@ UsersJob::exec()
 | 
			
		||||
 | 
			
		||||
    QList< QPair< QStringList, QString > > commands = {
 | 
			
		||||
        { { "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_cmdPasswd + " " + m_sshdUsername }, m_sshdPassword + "\n" + m_sshdPassword + "\n" } );
 | 
			
		||||
        commands.append( { { "sh", "-c", m_cmdSshd }, QString() } );
 | 
			
		||||
 | 
			
		||||
        if ( m_isSshEnabled )
 | 
			
		||||
        {
 | 
			
		||||
            commands.append( { { "sh", "-c", m_cmdSshdUseradd + " " + m_sshdUsername }, QString() } );
 | 
			
		||||
            commands.append(
 | 
			
		||||
                { { "sh", "-c", m_cmdPasswd + " " + m_sshdUsername }, m_sshdPassword + "\n" + m_sshdPassword + "\n" } );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    foreach ( auto command, commands )
 | 
			
		||||
 
 | 
			
		||||
@@ -8,14 +8,15 @@ class UsersJob : public Calamares::Job
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    UsersJob( QString cmdPasswd,
 | 
			
		||||
              QString cmdSshd,
 | 
			
		||||
              QString cmdSshdUseradd,
 | 
			
		||||
    UsersJob( bool featureSshd,
 | 
			
		||||
              const QString& cmdPasswd,
 | 
			
		||||
              const QString& cmdSshd,
 | 
			
		||||
              const QString& cmdSshdUseradd,
 | 
			
		||||
              bool isSshEnabled,
 | 
			
		||||
              QString username,
 | 
			
		||||
              QString password,
 | 
			
		||||
              QString sshdUsername,
 | 
			
		||||
              QString sshdPassword );
 | 
			
		||||
              const QString& username,
 | 
			
		||||
              const QString& password,
 | 
			
		||||
              const QString& sshdUsername,
 | 
			
		||||
              const QString& sshdPassword );
 | 
			
		||||
 | 
			
		||||
    QString prettyName() const override;
 | 
			
		||||
    Calamares::JobResult exec() override;
 | 
			
		||||
@@ -23,6 +24,7 @@ public:
 | 
			
		||||
    Calamares::JobList createJobs();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool m_featureSshd;
 | 
			
		||||
    QString m_cmdPasswd;
 | 
			
		||||
    QString m_cmdSshd;
 | 
			
		||||
    QString m_cmdSshdUseradd;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ Item {
 | 
			
		||||
    height: parent.height
 | 
			
		||||
 | 
			
		||||
    Text {
 | 
			
		||||
        id: welcomeText
 | 
			
		||||
        id: mainText
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: parent.top
 | 
			
		||||
        anchors.topMargin: 30
 | 
			
		||||
@@ -37,29 +37,29 @@ Item {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Button {
 | 
			
		||||
        id: enableButton
 | 
			
		||||
        id: firstButton
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: welcomeText.bottom
 | 
			
		||||
        anchors.top: mainText.bottom
 | 
			
		||||
        anchors.topMargin: 40
 | 
			
		||||
        width: 500
 | 
			
		||||
 | 
			
		||||
        text: qsTr("Enable")
 | 
			
		||||
        onClicked: {
 | 
			
		||||
            config.isFdeEnabled = true;
 | 
			
		||||
            navTo("fde_pass");
 | 
			
		||||
            navNext();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Button {
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: enableButton.bottom
 | 
			
		||||
        anchors.top: firstButton.bottom
 | 
			
		||||
        anchors.topMargin: 40
 | 
			
		||||
        width: 500
 | 
			
		||||
 | 
			
		||||
        text: qsTr("Disable")
 | 
			
		||||
        onClicked: {
 | 
			
		||||
            config.isFdeEnabled = false;
 | 
			
		||||
            navTo("install_confirm");
 | 
			
		||||
            navNextFeature();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ Item {
 | 
			
		||||
        onClicked: {
 | 
			
		||||
            if (validatePassword(password, passwordRepeat, errorText)) {
 | 
			
		||||
                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
 | 
			
		||||
 | 
			
		||||
    Text {
 | 
			
		||||
        id: welcomeText
 | 
			
		||||
        id: mainText
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: parent.top
 | 
			
		||||
        anchors.topMargin: 30
 | 
			
		||||
        wrapMode: Text.WordWrap
 | 
			
		||||
 | 
			
		||||
        text: "Once you hit 'install', the installation will begin. It will" +
 | 
			
		||||
              " typically take a few minutes. Do not power off the device" +
 | 
			
		||||
              " until it is done. Afterwards, it will reboot into the" +
 | 
			
		||||
              " installed system."
 | 
			
		||||
        text: (function() {
 | 
			
		||||
            var ret = "Once you hit 'install', the installation will begin." +
 | 
			
		||||
                " It will typically take a few minutes. Do not power off the" +
 | 
			
		||||
                " device until it is done.<br><br>";
 | 
			
		||||
 | 
			
		||||
            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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Button {
 | 
			
		||||
        id: enableButton
 | 
			
		||||
        id: firstButton
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: welcomeText.bottom
 | 
			
		||||
        anchors.top: mainText.bottom
 | 
			
		||||
        anchors.topMargin: 40
 | 
			
		||||
        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.
 | 
			
		||||
# All commands are running with 'sh -c'.
 | 
			
		||||
---
 | 
			
		||||
# This entry exists only to keep the tests happy, remove it in
 | 
			
		||||
# any production configuration.
 | 
			
		||||
bogus: true
 | 
			
		||||
 | 
			
		||||
#######
 | 
			
		||||
### Target OS information
 | 
			
		||||
#######
 | 
			
		||||
@@ -11,6 +18,10 @@
 | 
			
		||||
## User Interface name (e.g. Plasma Mobile)
 | 
			
		||||
# userInterface: "(unknown)"
 | 
			
		||||
 | 
			
		||||
## User Interface assumes that the password is numeric (as of writing, this is
 | 
			
		||||
## the case with Plasma Mobile and Phosh)
 | 
			
		||||
# userPasswordNumeric: true
 | 
			
		||||
 | 
			
		||||
## OS version
 | 
			
		||||
# version: "(unknown)"
 | 
			
		||||
 | 
			
		||||
@@ -27,9 +38,47 @@
 | 
			
		||||
## Name of the device (e.g. PinePhone)
 | 
			
		||||
# 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"
 | 
			
		||||
 | 
			
		||||
## 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
 | 
			
		||||
#######
 | 
			
		||||
@@ -46,12 +95,25 @@
 | 
			
		||||
 | 
			
		||||
## Format the rootfs with a file system
 | 
			
		||||
## 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
 | 
			
		||||
## Arguments: <device> <mountpoint>
 | 
			
		||||
# cmdMount: "mount"
 | 
			
		||||
 | 
			
		||||
## When user selects installation from external storage to internal storage
 | 
			
		||||
## (see targetDeviceRootInternal above), use this command to prepare the
 | 
			
		||||
## internal storage medium. The command must create a partition table with
 | 
			
		||||
## two partitions (boot, root) and fill the boot partition. See the
 | 
			
		||||
## ondev-internal-storage-prepare.sh in postmarketos-ondev as example.
 | 
			
		||||
# cmdInternalStoragePrepare: "ondev-internal-storage-prepare"
 | 
			
		||||
 | 
			
		||||
#######
 | 
			
		||||
### Commands running in the target OS (chroot)
 | 
			
		||||
#######
 | 
			
		||||
 
 | 
			
		||||
@@ -17,16 +17,46 @@ Page
 | 
			
		||||
    property var screenPrevious: []
 | 
			
		||||
    property var titles: {
 | 
			
		||||
        "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_credentials": "SSH credentials",
 | 
			
		||||
        "fs_selection": "Root filesystem",
 | 
			
		||||
        "fde_confirm": "Full disk encryption",
 | 
			
		||||
        "fde_pass": "Full disk encryption",
 | 
			
		||||
        "install_confirm": "Ready to install",
 | 
			
		||||
        "wait": null
 | 
			
		||||
    }
 | 
			
		||||
    /* Only allow characters, that can be typed in with the initramfs on-screen keyboard
 | 
			
		||||
     * (osk-sdl: see src/keyboard.cpp). FIXME: make configurable, but keep this as default? */
 | 
			
		||||
    property var features: [
 | 
			
		||||
        {"name": "welcome",
 | 
			
		||||
         "screens": ["welcome"]},
 | 
			
		||||
        {"name": "installTarget",
 | 
			
		||||
         "screens": ["install_target", "install_target_confirm"]},
 | 
			
		||||
        {"name": "userPassword",
 | 
			
		||||
         "screens": ["user_pass"]},
 | 
			
		||||
        {"name": "sshd",
 | 
			
		||||
         "screens": ["ssh_confirm", "ssh_credentials"]},
 | 
			
		||||
        {"name": "fsType",
 | 
			
		||||
         "screens": ["fs_selection"]},
 | 
			
		||||
        {"name": "fde",
 | 
			
		||||
         "screens": ["fde_confirm", "fde_pass"]},
 | 
			
		||||
        {"name": "installConfirm",
 | 
			
		||||
         "screens": ["install_confirm", "wait"]}
 | 
			
		||||
    ]
 | 
			
		||||
    property var featureIdByScreen: (function() {
 | 
			
		||||
        /* Put "features" above into an index of screen name -> feature id:
 | 
			
		||||
         * featureIdByScreen = {"welcome": 0, "user_pass": 1, ...} */
 | 
			
		||||
        var ret = {};
 | 
			
		||||
        for (var i=0; i<features.length; i++) {
 | 
			
		||||
            for (var j=0; j<features[i]["screens"].length; j++) {
 | 
			
		||||
                ret[ features[i]["screens"][j] ] = i;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return ret;
 | 
			
		||||
    }())
 | 
			
		||||
    /* Only allow characters, that can be typed in with osk-sdl
 | 
			
		||||
     * (src/keyboard.cpp). Details in big comment in validatePassword(). */
 | 
			
		||||
     property var allowed_chars:
 | 
			
		||||
        /* layer 0 */ "abcdefghijklmnopqrstuvwxyz" +
 | 
			
		||||
        /* layer 1 */ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
 | 
			
		||||
@@ -112,6 +142,7 @@ Page
 | 
			
		||||
    InputPanel {
 | 
			
		||||
        id: inputPanel
 | 
			
		||||
        y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height
 | 
			
		||||
        visible: config.builtinVirtualKeyboard
 | 
			
		||||
        anchors.left: parent.left
 | 
			
		||||
        anchors.right: parent.right
 | 
			
		||||
    }
 | 
			
		||||
@@ -120,8 +151,13 @@ Page
 | 
			
		||||
        id: timer
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function skipFeatureInstallTarget() {
 | 
			
		||||
        return config.targetDeviceRootInternal == "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Navigation related */
 | 
			
		||||
    function navTo(name, historyPush=true) {
 | 
			
		||||
        console.log("Navigating to screen: " + name);
 | 
			
		||||
        if (historyPush)
 | 
			
		||||
            screenPrevious.push(screen);
 | 
			
		||||
        screen = name;
 | 
			
		||||
@@ -131,15 +167,71 @@ Page
 | 
			
		||||
        Qt.inputMethod.hide();
 | 
			
		||||
    }
 | 
			
		||||
    function navFinish() {
 | 
			
		||||
        /* Show a waiting screen and wait a second (so it can render), then let
 | 
			
		||||
         * MobileQmlViewStep.cpp::onLeave() create the (encrypted) partition
 | 
			
		||||
         * and mount it. We can't have this as proper job due to ondev#18. */
 | 
			
		||||
        /* Show a waiting screen and wait a second (so it can render). The big
 | 
			
		||||
         * comment in Config.cpp::runPartitionJobThenLeave() explains why this
 | 
			
		||||
         * is necessary. */
 | 
			
		||||
        navTo("wait");
 | 
			
		||||
        timer.interval = 1000;
 | 
			
		||||
        timer.repeat = false;
 | 
			
		||||
        timer.triggered.connect(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();
 | 
			
		||||
    }
 | 
			
		||||
    function navNextFeature() {
 | 
			
		||||
        var id;
 | 
			
		||||
 | 
			
		||||
        /* Skip disabled features */
 | 
			
		||||
        for (id = featureIdByScreen[screen] + 1; id < features.length; id++) {
 | 
			
		||||
            /* First letter uppercase */
 | 
			
		||||
            var name = features[id]["name"];
 | 
			
		||||
            var nameUp = name.charAt(0).toUpperCase() + name.slice(1);
 | 
			
		||||
 | 
			
		||||
            /* Check config.Feature<Name> */
 | 
			
		||||
            var configOption = "feature" + nameUp;
 | 
			
		||||
            if (config[configOption] === false) {
 | 
			
		||||
                console.log("Skipping feature (disabled in config): " + name);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Check skipFeature<Name>() */
 | 
			
		||||
            var funcName = "skipFeature" + nameUp;
 | 
			
		||||
            if (eval("typeof " + funcName) === "function"
 | 
			
		||||
                && eval(funcName + "()")) {
 | 
			
		||||
                console.log("Skipping feature (skip function): " + name);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        console.log("Navigating to feature: " + features[id]["name"]);
 | 
			
		||||
        return navTo(features[id]["screens"][0]);
 | 
			
		||||
    }
 | 
			
		||||
    function navNext() {
 | 
			
		||||
        var featureId = featureIdByScreen[screen];
 | 
			
		||||
        var featureScreens = features[featureId]["screens"];
 | 
			
		||||
        for (var i = 0; i<featureScreens.length; i++) {
 | 
			
		||||
            /* Seek ahead until i is current screen */
 | 
			
		||||
            if (featureScreens[i] != screen)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            /* Navigate to next screen in same feature */
 | 
			
		||||
            if (i + 1 < featureScreens.length) {
 | 
			
		||||
                var screenNext = featureScreens[i + 1];
 | 
			
		||||
                return navTo(screenNext);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Screen is last in feature */
 | 
			
		||||
            return navNextFeature();
 | 
			
		||||
        }
 | 
			
		||||
        console.log("ERROR: navNext() failed for screen: " + screen);
 | 
			
		||||
    }
 | 
			
		||||
    function navBack() {
 | 
			
		||||
        if (screenPrevious.length)
 | 
			
		||||
            return navTo(screenPrevious.pop(), false);
 | 
			
		||||
@@ -161,7 +253,7 @@ Page
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Input validation: user-screens (default_pin, ssh_credentials) */
 | 
			
		||||
    /* Input validation: user-screens (user_pass, ssh_credentials) */
 | 
			
		||||
    function validatePin(userPin, userPinRepeat, errorText) {
 | 
			
		||||
        var pin = userPin.text;
 | 
			
		||||
        var repeat = userPinRepeat.text;
 | 
			
		||||
@@ -183,7 +275,7 @@ Page
 | 
			
		||||
        if (repeat != pin)
 | 
			
		||||
            return validationFailure(errorText,
 | 
			
		||||
                                     "The PINs don't match.");
 | 
			
		||||
                             
 | 
			
		||||
 | 
			
		||||
        return validationFailureClear(errorText);
 | 
			
		||||
    }
 | 
			
		||||
    function validateSshdUsername(username, errorText) {
 | 
			
		||||
@@ -297,11 +389,21 @@ Page
 | 
			
		||||
        if (pass == "")
 | 
			
		||||
            return validationFailure(errorText);
 | 
			
		||||
 | 
			
		||||
        /* This function gets called for the FDE password and for the user
 | 
			
		||||
         * password. As of writing, all distributions shipping the mobile
 | 
			
		||||
         * module are using osk-sdl to type in the FDE password after the
 | 
			
		||||
         * installation, and another keyboard after booting up, to type in the
 | 
			
		||||
         * user password. The osk-sdl password has the same keys as
 | 
			
		||||
         * squeekboard's default layout, and other keyboards should be able to
 | 
			
		||||
         * type these characters in as well. For now, verify that the password
 | 
			
		||||
         * only contains characters that can be typed in by osk-sdl. If you
 | 
			
		||||
         * need this to be more sophisticated, feel free to submit patches to
 | 
			
		||||
         * make this more configurable. */
 | 
			
		||||
        if (!check_chars(pass))
 | 
			
		||||
            return validationFailure(errorText,
 | 
			
		||||
                                     "The password must only contain" +
 | 
			
		||||
                                     " these characters, others cannot be" +
 | 
			
		||||
                                     " typed in at boot time:\n" +
 | 
			
		||||
                                     " these characters, others can possibly" +
 | 
			
		||||
                                     " not be typed in after installation:\n" +
 | 
			
		||||
                                     "\n" +
 | 
			
		||||
                                     allowed_chars_multiline());
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,13 @@
 | 
			
		||||
 | 
			
		||||
  <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_credentials.qml</file> <!-- sshd user: username, password -->
 | 
			
		||||
  <file>fs_selection.qml</file> <!-- filesystem selection -->
 | 
			
		||||
 | 
			
		||||
  <file>fde_confirm.qml</file> <!-- enable FDE or not? -->
 | 
			
		||||
  <file>fde_pass.qml</file> <!-- FDE password (optional) -->
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ Item {
 | 
			
		||||
    height: parent.height
 | 
			
		||||
 | 
			
		||||
    Text {
 | 
			
		||||
        id: welcomeText
 | 
			
		||||
        id: mainText
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: parent.top
 | 
			
		||||
        anchors.topMargin: 30
 | 
			
		||||
@@ -40,29 +40,29 @@ Item {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Button {
 | 
			
		||||
        id: enableButton
 | 
			
		||||
        id: firstButton
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: welcomeText.bottom
 | 
			
		||||
        anchors.top: mainText.bottom
 | 
			
		||||
        anchors.topMargin: 40
 | 
			
		||||
        width: 500
 | 
			
		||||
 | 
			
		||||
        text: qsTr("Enable")
 | 
			
		||||
        onClicked: {
 | 
			
		||||
            config.isSshEnabled = true;
 | 
			
		||||
            navTo("ssh_credentials");
 | 
			
		||||
            navNext();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Button {
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: enableButton.bottom
 | 
			
		||||
        anchors.top: firstButton.bottom
 | 
			
		||||
        anchors.topMargin: 40
 | 
			
		||||
        width: 500
 | 
			
		||||
 | 
			
		||||
        text: qsTr("Disable")
 | 
			
		||||
        onClicked: {
 | 
			
		||||
            config.isSshEnabled = false;
 | 
			
		||||
            navTo("fde_confirm");
 | 
			
		||||
            navNextFeature();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -100,7 +100,7 @@ Item {
 | 
			
		||||
                config.sshdUsername = username.text;
 | 
			
		||||
                config.sshdPassword = password.text;
 | 
			
		||||
 | 
			
		||||
                navTo("fde_confirm");
 | 
			
		||||
                navNext();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,17 @@ import QtQuick.Window 2.3
 | 
			
		||||
import QtQuick.VirtualKeyboard 2.1
 | 
			
		||||
 | 
			
		||||
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.top: parent.top
 | 
			
		||||
    anchors.right: parent.right
 | 
			
		||||
@@ -25,23 +36,31 @@ Item {
 | 
			
		||||
        anchors.topMargin: 30
 | 
			
		||||
        wrapMode: Text.WordWrap
 | 
			
		||||
 | 
			
		||||
        text: "Set the numeric password of your user. The lockscreen will" +
 | 
			
		||||
              " ask for this PIN. This is <i>not</i> the PIN of your SIM" +
 | 
			
		||||
              " card. Make sure to remember it."
 | 
			
		||||
        text: (function() {
 | 
			
		||||
            if (config.userPasswordNumeric) {
 | 
			
		||||
                return "Set the numeric password of your user. The" +
 | 
			
		||||
                       " lockscreen will ask for this PIN. This is" +
 | 
			
		||||
                       " <i>not</i> the PIN of your SIM card. Make sure to" +
 | 
			
		||||
                       " remember it.";
 | 
			
		||||
            } else {
 | 
			
		||||
                return "Set the password of your user. The lockscreen will" +
 | 
			
		||||
                      " ask for this password. Make sure to remember it.";
 | 
			
		||||
            }
 | 
			
		||||
        }())
 | 
			
		||||
 | 
			
		||||
        width: 500
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    TextField {
 | 
			
		||||
        id: userPin
 | 
			
		||||
        id: userPass
 | 
			
		||||
        anchors.top: description.bottom
 | 
			
		||||
        placeholderText: qsTr("PIN")
 | 
			
		||||
        placeholderText: qsTr(placeholder)
 | 
			
		||||
        echoMode: TextInput.Password
 | 
			
		||||
        onTextChanged: validatePin(userPin, userPinRepeat, errorText)
 | 
			
		||||
        onTextChanged: validateFunc(userPass, userPassRepeat, errorText)
 | 
			
		||||
        text: config.userPassword
 | 
			
		||||
 | 
			
		||||
        /* Let the virtual keyboard change to digits only */
 | 
			
		||||
        inputMethodHints: Qt.ImhDigitsOnly
 | 
			
		||||
        inputMethodHints: hints
 | 
			
		||||
        onActiveFocusChanged: {
 | 
			
		||||
            if(activeFocus) {
 | 
			
		||||
                Qt.inputMethod.update(Qt.ImQueryInput)
 | 
			
		||||
@@ -54,12 +73,12 @@ Item {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    TextField {
 | 
			
		||||
        id: userPinRepeat
 | 
			
		||||
        anchors.top: userPin.bottom
 | 
			
		||||
        placeholderText: qsTr("PIN (repeat)")
 | 
			
		||||
        inputMethodHints: Qt.ImhDigitsOnly
 | 
			
		||||
        id: userPassRepeat
 | 
			
		||||
        anchors.top: userPass.bottom
 | 
			
		||||
        placeholderText: qsTr(placeholder + " (repeat)")
 | 
			
		||||
        inputMethodHints: hints
 | 
			
		||||
        echoMode: TextInput.Password
 | 
			
		||||
        onTextChanged: validatePin(userPin, userPinRepeat, errorText)
 | 
			
		||||
        onTextChanged: validateFunc(userPass, userPassRepeat, errorText)
 | 
			
		||||
        text: config.userPassword
 | 
			
		||||
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
@@ -68,7 +87,7 @@ Item {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Text {
 | 
			
		||||
        anchors.top: userPinRepeat.bottom
 | 
			
		||||
        anchors.top: userPassRepeat.bottom
 | 
			
		||||
        id: errorText
 | 
			
		||||
        visible: false
 | 
			
		||||
        wrapMode: Text.WordWrap
 | 
			
		||||
@@ -86,9 +105,9 @@ Item {
 | 
			
		||||
 | 
			
		||||
        text: qsTr("Continue")
 | 
			
		||||
        onClicked: {
 | 
			
		||||
            if (validatePin(userPin, userPinRepeat, errorText)) {
 | 
			
		||||
                config.userPassword = userPin.text;
 | 
			
		||||
                navTo("ssh_confirm");
 | 
			
		||||
            if (validateFunc(userPass, userPassRepeat, errorText)) {
 | 
			
		||||
                config.userPassword = userPass.text;
 | 
			
		||||
                navNext();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -38,7 +38,7 @@ Page
 | 
			
		||||
            anchors.topMargin: 150
 | 
			
		||||
            wrapMode: Text.WordWrap
 | 
			
		||||
            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
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ Page
 | 
			
		||||
                source: "file:///usr/share/calamares/branding/default-mobile/logo.png"
 | 
			
		||||
            }
 | 
			
		||||
            Text {
 | 
			
		||||
                id: welcomeText
 | 
			
		||||
                id: mainText
 | 
			
		||||
                anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
                anchors.top: logo.bottom
 | 
			
		||||
                anchors.topMargin: 50
 | 
			
		||||
@@ -53,12 +53,12 @@ Page
 | 
			
		||||
 | 
			
		||||
            Button {
 | 
			
		||||
                anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
                anchors.top: welcomeText.bottom
 | 
			
		||||
                anchors.top: mainText.bottom
 | 
			
		||||
                anchors.topMargin: 50
 | 
			
		||||
                width: 500
 | 
			
		||||
 | 
			
		||||
                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
 | 
			
		||||
# in testing to allow the slideshow time to run.
 | 
			
		||||
---
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,6 @@
 | 
			
		||||
# SPDX-FileCopyrightText: no
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
# This is an example module for Python Job Modules.
 | 
			
		||||
#
 | 
			
		||||
# The slowpython module is just slow. It does produce
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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