forked from artix/calamares-extensions
		
	Compare commits
	
		
			109 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					e08d687061 | ||
| 
						 | 
					15f6369537 | ||
| 
						 | 
					f01b4ed2f8 | ||
| 
						 | 
					ea762b0945 | ||
| 
						 | 
					cae8acb4a4 | ||
| 
						 | 
					ae204d0108 | ||
| 
						 | 
					a2fae600c4 | ||
| 
						 | 
					349acad491 | ||
| 
						 | 
					9b4c4876bc | ||
| 
						 | 
					cc02baed9a | ||
| 
						 | 
					dfab089938 | ||
| 
						 | 
					2dd9a7ba8a | ||
| 
						 | 
					82f31f3cd9 | ||
| 
						 | 
					c5b01a574d | ||
| 
						 | 
					bc4789d57f | ||
| 
						 | 
					0962b98494 | ||
| 
						 | 
					108476c025 | ||
| 
						 | 
					04a1bc9e2c | ||
| 
						 | 
					bff5e485f4 | ||
| 
						 | 
					3c838436c2 | ||
| 
						 | 
					644c9cf4f3 | ||
| 
						 | 
					dcaa378ddd | ||
| 
						 | 
					14fd23dcef | ||
| 
						 | 
					f4bc7052e0 | ||
| 
						 | 
					4f0f48d99d | ||
| 
						 | 
					1344880f2e | ||
| 
						 | 
					5704e146a0 | ||
| 
						 | 
					85eb434b57 | ||
| 
						 | 
					4b2ea61aa3 | ||
| 
						 | 
					39d25eef1c | ||
| 
						 | 
					e82d32fe66 | ||
| 
						 | 
					a50ab49c22 | ||
| 
						 | 
					a66ab99ce8 | ||
| 
						 | 
					c3170a9dfb | ||
| 
						 | 
					88437d3612 | ||
| 
						 | 
					6db52a904e | ||
| 
						 | 
					8f0403a3f8 | ||
| 
						 | 
					caf231b0d1 | ||
| 
						 | 
					9ad86f81bb | ||
| 
						 | 
					4d601f2e6a | ||
| 
						 | 
					69f68d82e6 | ||
| 
						 | 
					572a94e493 | ||
| 
						 | 
					90454be1b9 | ||
| 
						 | 
					6144404bd0 | ||
| 
						 | 
					8f4d8d119c | ||
| 
						 | 
					e8c870205d | ||
| 
						 | 
					081d7d47d1 | ||
| 
						 | 
					e92ecea3f5 | ||
| 
						 | 
					e158402478 | ||
| 
						 | 
					d242d077db | ||
| 
						 | 
					5f9b46a820 | ||
| 
						 | 
					9151d0fcee | ||
| 
						 | 
					282f5bfade | ||
| 
						 | 
					eeb264f32e | ||
| 
						 | 
					83606aaf9d | ||
| 
						 | 
					322a7a212f | ||
| 
						 | 
					40c7496f85 | ||
| 
						 | 
					f1fd52e790 | ||
| 
						 | 
					12f6068622 | ||
| 
						 | 
					16a3e2edb2 | ||
| 
						 | 
					8fc9b907af | ||
| 
						 | 
					ecaf2c3076 | ||
| 
						 | 
					ea97927997 | ||
| 
						 | 
					6795190216 | ||
| 
						 | 
					51149e34d7 | ||
| 
						 | 
					a2674c652d | ||
| 
						 | 
					d4d6d17efe | ||
| 
						 | 
					b74d77a9c5 | ||
| 
						 | 
					5074bebd32 | ||
| 
						 | 
					76be9988fe | ||
| 
						 | 
					c85daf8f7b | ||
| 
						 | 
					13e8b1e9b5 | ||
| 
						 | 
					e6ddf30512 | ||
| 
						 | 
					9938d11ad1 | ||
| 
						 | 
					def4ee5c7e | ||
| 
						 | 
					718f73c9c8 | ||
| 
						 | 
					720415d8b7 | ||
| 
						 | 
					0f0b9aa776 | ||
| 
						 | 
					19d508ca2e | ||
| 
						 | 
					7af1aeb132 | ||
| 
						 | 
					3f7cabe832 | ||
| 
						 | 
					341c9f4a7f | ||
| 
						 | 
					03260efb3a | ||
| 
						 | 
					18060db82d | ||
| 
						 | 
					b978f03618 | ||
| 
						 | 
					a4a6194a5d | ||
| 
						 | 
					93cf06da82 | ||
| 
						 | 
					901211c12d | ||
| 
						 | 
					e89a58a34b | ||
| 
						 | 
					fb36765982 | ||
| 
						 | 
					f1d2bfacce | ||
| 
						 | 
					9703bd9058 | ||
| 
						 | 
					0e2a178436 | ||
| 
						 | 
					fb70e29e29 | ||
| 
						 | 
					fbfa9d8038 | ||
| 
						 | 
					59ab728502 | ||
| 
						 | 
					476224d34e | ||
| 
						 | 
					2aaf440fec | ||
| 
						 | 
					b416caa462 | ||
| 
						 | 
					0c11b864e5 | ||
| 
						 | 
					0f9ffb9e35 | ||
| 
						 | 
					813d26ec4e | ||
| 
						 | 
					5d44118b4b | ||
| 
						 | 
					833e33f011 | ||
| 
						 | 
					ea3a03a8cc | ||
| 
						 | 
					05bbeae2c3 | ||
| 
						 | 
					b9b923e69c | ||
| 
						 | 
					809491c969 | ||
| 
						 | 
					febeb3281e | 
@@ -8,6 +8,7 @@ AlignEscapedNewlines: DontAlign
 | 
			
		||||
AllowAllParametersOfDeclarationOnNextLine: "false"
 | 
			
		||||
AllowShortFunctionsOnASingleLine: Inline
 | 
			
		||||
AllowShortIfStatementsOnASingleLine: "false"
 | 
			
		||||
AllowShortLambdasOnASingleLine: All
 | 
			
		||||
AllowShortLoopsOnASingleLine: "false"
 | 
			
		||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
 | 
			
		||||
AlwaysBreakTemplateDeclarations: Yes
 | 
			
		||||
@@ -28,7 +29,6 @@ ReflowComments: "false"
 | 
			
		||||
SortIncludes: "true"
 | 
			
		||||
SpaceAfterCStyleCast: "false"
 | 
			
		||||
SpacesBeforeTrailingComments: "2"
 | 
			
		||||
# SpaceInEmptyBlock: "true"
 | 
			
		||||
SpacesInAngles: "true"
 | 
			
		||||
SpacesInParentheses: "true"
 | 
			
		||||
SpacesInSquareBrackets: "true"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								.clang-format.base
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								.clang-format.base
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: no
 | 
			
		||||
#   SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
---
 | 
			
		||||
BasedOnStyle: WebKit
 | 
			
		||||
 | 
			
		||||
AlignAfterOpenBracket: Align
 | 
			
		||||
AlignEscapedNewlines: DontAlign
 | 
			
		||||
AllowAllParametersOfDeclarationOnNextLine: "false"
 | 
			
		||||
AllowShortFunctionsOnASingleLine: Inline
 | 
			
		||||
AllowShortIfStatementsOnASingleLine: "false"
 | 
			
		||||
AllowShortLambdasOnASingleLine: All
 | 
			
		||||
AllowShortLoopsOnASingleLine: "false"
 | 
			
		||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
 | 
			
		||||
AlwaysBreakTemplateDeclarations: Yes
 | 
			
		||||
BinPackArguments: "false"
 | 
			
		||||
BinPackParameters: "false"
 | 
			
		||||
BreakBeforeBraces: Allman
 | 
			
		||||
BreakBeforeTernaryOperators: "true"
 | 
			
		||||
BreakConstructorInitializers: BeforeComma
 | 
			
		||||
ColumnLimit: 120
 | 
			
		||||
Cpp11BracedListStyle: "false"
 | 
			
		||||
FixNamespaceComments: "true"
 | 
			
		||||
IncludeBlocks: Preserve
 | 
			
		||||
IndentWidth: "4"
 | 
			
		||||
MaxEmptyLinesToKeep: "2"
 | 
			
		||||
NamespaceIndentation: None
 | 
			
		||||
PointerAlignment: Left
 | 
			
		||||
ReflowComments: "false"
 | 
			
		||||
SortIncludes: "true"
 | 
			
		||||
SpaceAfterCStyleCast: "false"
 | 
			
		||||
SpacesBeforeTrailingComments: "2"
 | 
			
		||||
SpacesInAngles: "true"
 | 
			
		||||
SpacesInParentheses: "true"
 | 
			
		||||
SpacesInSquareBrackets: "true"
 | 
			
		||||
Standard: Cpp11
 | 
			
		||||
							
								
								
									
										74
									
								
								.github/workflows/nightly-neon.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										74
									
								
								.github/workflows/nightly-neon.yml
									
									
									
									
										vendored
									
									
								
							@@ -31,70 +31,30 @@ jobs:
 | 
			
		||||
          path: ${{ env.BUILDDIR }}
 | 
			
		||||
          repo: calamares/calamares
 | 
			
		||||
      - name: "prepare env"
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo apt-get update
 | 
			
		||||
          sudo apt-get -y install git-core
 | 
			
		||||
          sudo apt-get -y install \
 | 
			
		||||
            build-essential \
 | 
			
		||||
            cmake \
 | 
			
		||||
            extra-cmake-modules \
 | 
			
		||||
            gettext \
 | 
			
		||||
            kio-dev \
 | 
			
		||||
            libatasmart-dev \
 | 
			
		||||
            libboost-python-dev \
 | 
			
		||||
            libkf5config-dev \
 | 
			
		||||
            libkf5coreaddons-dev \
 | 
			
		||||
            libkf5i18n-dev \
 | 
			
		||||
            libkf5iconthemes-dev \
 | 
			
		||||
            libkf5parts-dev \
 | 
			
		||||
            libkf5service-dev \
 | 
			
		||||
            libkf5solid-dev \
 | 
			
		||||
            libkpmcore-dev \
 | 
			
		||||
            libparted-dev \
 | 
			
		||||
            libpolkit-qt5-1-dev \
 | 
			
		||||
            libqt5svg5-dev \
 | 
			
		||||
            libqt5webkit5-dev \
 | 
			
		||||
            libyaml-cpp-dev \
 | 
			
		||||
            os-prober \
 | 
			
		||||
            pkg-config \
 | 
			
		||||
            python3-dev \
 | 
			
		||||
            qtbase5-dev \
 | 
			
		||||
            qtdeclarative5-dev \
 | 
			
		||||
            qttools5-dev \
 | 
			
		||||
            qttools5-dev-tools
 | 
			
		||||
        uses: calamares/actions/prepare-neon@v2
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      - name: "prepare artifacts"
 | 
			
		||||
        run: tar xvzf "$BUILDDIR/calamares.tar.gz" -C / --strip-components 1
 | 
			
		||||
      - name: "prepare build"
 | 
			
		||||
        id: pre_build
 | 
			
		||||
        run: |
 | 
			
		||||
          test -n "$BUILDDIR" || { echo "! \$BUILDDIR not set" ; exit 1 ; }
 | 
			
		||||
          mkdir -p $BUILDDIR
 | 
			
		||||
          test -f $SRCDIR/CMakeLists.txt || { echo "! Missing $SRCDIR/CMakeLists.txt" ; exit 1 ; }
 | 
			
		||||
          echo "::set-output name=message::"`git log -1 --abbrev-commit --pretty=oneline --no-decorate ${{ github.event.head_commit.id }}`
 | 
			
		||||
      - name: "Calamares-Extensions: cmake"
 | 
			
		||||
        working-directory: ${{ env.BUILDDIR }}
 | 
			
		||||
        run: cmake $CMAKE_ARGS $SRCDIR
 | 
			
		||||
      - name: "Calamares-Extensions: make"
 | 
			
		||||
        working-directory: ${{ env.BUILDDIR }}
 | 
			
		||||
        run: make -j2 VERBOSE=1
 | 
			
		||||
      - name: "Calamares-Extensions: install"
 | 
			
		||||
        working-directory: ${{ env.BUILDDIR }}
 | 
			
		||||
        run: make install VERBOSE=1
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        id: build
 | 
			
		||||
        uses: calamares/actions/generic-build@v2
 | 
			
		||||
      - name: "notify: ok"
 | 
			
		||||
        uses: rectalogic/notify-irc@v1
 | 
			
		||||
        if: ${{ success() && github.repository == 'calamares/calamares-extensions' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v2
 | 
			
		||||
        with:
 | 
			
		||||
          server: chat.freenode.net
 | 
			
		||||
          nickname: cala-ci
 | 
			
		||||
          channel: "#calamares"
 | 
			
		||||
          message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.pre_build.outputs.message }}"
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git_summary }}"
 | 
			
		||||
      - name: "notify: fail"
 | 
			
		||||
        uses: rectalogic/notify-irc@v1
 | 
			
		||||
        if: ${{ failure() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v2
 | 
			
		||||
        with:
 | 
			
		||||
          server: chat.freenode.net
 | 
			
		||||
          nickname: cala-ci
 | 
			
		||||
          channel: "#calamares"
 | 
			
		||||
          message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.pre_build.outputs.message }}"
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git_summary}}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										76
									
								
								.github/workflows/push.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								.github/workflows/push.yml
									
									
									
									
										vendored
									
									
								
							@@ -37,70 +37,30 @@ jobs:
 | 
			
		||||
          path: ${{ env.BUILDDIR }}
 | 
			
		||||
          repo: calamares/calamares
 | 
			
		||||
      - name: "prepare env"
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo apt-get update
 | 
			
		||||
          sudo apt-get -y install git-core
 | 
			
		||||
          sudo apt-get -y install \
 | 
			
		||||
            build-essential \
 | 
			
		||||
            cmake \
 | 
			
		||||
            extra-cmake-modules \
 | 
			
		||||
            gettext \
 | 
			
		||||
            kio-dev \
 | 
			
		||||
            libatasmart-dev \
 | 
			
		||||
            libboost-python-dev \
 | 
			
		||||
            libkf5config-dev \
 | 
			
		||||
            libkf5coreaddons-dev \
 | 
			
		||||
            libkf5i18n-dev \
 | 
			
		||||
            libkf5iconthemes-dev \
 | 
			
		||||
            libkf5parts-dev \
 | 
			
		||||
            libkf5service-dev \
 | 
			
		||||
            libkf5solid-dev \
 | 
			
		||||
            libkpmcore-dev \
 | 
			
		||||
            libparted-dev \
 | 
			
		||||
            libpolkit-qt5-1-dev \
 | 
			
		||||
            libqt5svg5-dev \
 | 
			
		||||
            libqt5webkit5-dev \
 | 
			
		||||
            libyaml-cpp-dev \
 | 
			
		||||
            os-prober \
 | 
			
		||||
            pkg-config \
 | 
			
		||||
            python3-dev \
 | 
			
		||||
            qtbase5-dev \
 | 
			
		||||
            qtdeclarative5-dev \
 | 
			
		||||
            qttools5-dev \
 | 
			
		||||
            qttools5-dev-tools
 | 
			
		||||
        uses: calamares/actions/prepare-neon@v2
 | 
			
		||||
      - name: "prepare source"
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      - name: "prepare artifacts"
 | 
			
		||||
        run: tar xvzf "$BUILDDIR/calamares.tar.gz" -C / --strip-components 1
 | 
			
		||||
      - name: "prepare build"
 | 
			
		||||
        id: pre_build
 | 
			
		||||
        run: |
 | 
			
		||||
          test -n "$BUILDDIR" || { echo "! \$BUILDDIR not set" ; exit 1 ; }
 | 
			
		||||
          mkdir -p $BUILDDIR
 | 
			
		||||
          test -f $SRCDIR/CMakeLists.txt || { echo "! Missing $SRCDIR/CMakeLists.txt" ; exit 1 ; }
 | 
			
		||||
          echo "::set-output name=message::"`git log -1 --abbrev-commit --pretty=oneline --no-decorate ${{ github.event.head_commit.id }}`
 | 
			
		||||
      - name: "Calamares-Extensions: cmake"
 | 
			
		||||
        working-directory: ${{ env.BUILDDIR }}
 | 
			
		||||
        run: cmake $CMAKE_ARGS $SRCDIR
 | 
			
		||||
      - name: "Calamares-Extensions: make"
 | 
			
		||||
        working-directory: ${{ env.BUILDDIR }}
 | 
			
		||||
        run: make -j2 VERBOSE=1
 | 
			
		||||
      - name: "Calamares-Extensions: install"
 | 
			
		||||
        working-directory: ${{ env.BUILDDIR }}
 | 
			
		||||
        run: make install VERBOSE=1
 | 
			
		||||
      - name: "build"
 | 
			
		||||
        id: build
 | 
			
		||||
        uses: calamares/actions/generic-build@v2
 | 
			
		||||
      - name: "notify: ok"
 | 
			
		||||
        uses: rectalogic/notify-irc@v1
 | 
			
		||||
        if: ${{ success() && github.repository == 'calamares/calamares-extensions' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v2
 | 
			
		||||
        with:
 | 
			
		||||
          server: chat.freenode.net
 | 
			
		||||
          nickname: cala-ci
 | 
			
		||||
          channel: "#calamares"
 | 
			
		||||
          message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ github.actor }} on ${{ github.event.ref }}\n.. ${{ steps.pre_build.outputs.message }}"
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: |
 | 
			
		||||
            OK ${{ github.workflow }} in ${{ github.repository }} by ${{ github.actor }} on ${{ github.event.ref }}
 | 
			
		||||
            .. ${{ steps.build.outputs.git-summary }}
 | 
			
		||||
      - name: "notify: fail"
 | 
			
		||||
        uses: rectalogic/notify-irc@v1
 | 
			
		||||
        if: ${{ failure() && github.repository == 'calamares/calamares' }}
 | 
			
		||||
        if: ${{ failure() && github.repository == 'calamares/calamares-extensions' }}
 | 
			
		||||
        uses: calamares/actions/matrix-notify@v2
 | 
			
		||||
        with:
 | 
			
		||||
          server: chat.freenode.net
 | 
			
		||||
          nickname: cala-ci
 | 
			
		||||
          channel: "#calamares"
 | 
			
		||||
          message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ github.actor }} on ${{ github.event.ref }}\n.. ${{ steps.pre_build.outputs.message }}\n.. DIFF ${{ github.event.compare }}"
 | 
			
		||||
          token: ${{ secrets.MATRIX_TOKEN }}
 | 
			
		||||
          room: ${{ secrets.MATRIX_ROOM }}
 | 
			
		||||
          message: |
 | 
			
		||||
            FAIL ${{ github.workflow }} in ${{ github.repository }} by ${{ github.actor }} on ${{ github.event.ref }}
 | 
			
		||||
              .. ${{ steps.build.outputs.git-summary }}
 | 
			
		||||
              .. ${{ github.event.compare }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,6 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: no
 | 
			
		||||
#   SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
.kdev4/
 | 
			
		||||
build/
 | 
			
		||||
*.kdev4
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								.reuse/dep5
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								.reuse/dep5
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 | 
			
		||||
Upstream-Name: Calamares-Extensions
 | 
			
		||||
Source: https://github.com/calamares/calamares-extensions.git
 | 
			
		||||
 | 
			
		||||
### BUILD ARTIFACTS / NOT SOURCE
 | 
			
		||||
#
 | 
			
		||||
# QRC Files are basically build artifacts
 | 
			
		||||
#
 | 
			
		||||
FILES: modules/*/*.qrc
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
# GitHub issue templates are not part of the source
 | 
			
		||||
#
 | 
			
		||||
Files: .github/ISSUE_TEMPLATE/*
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
# GitHub actions are not part of the source
 | 
			
		||||
Files: .github/workflows/*.yml
 | 
			
		||||
License: CC0-1.0
 | 
			
		||||
Copyright: no
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								CHANGES
									
									
									
									
									
								
							@@ -6,6 +6,49 @@ This is the changelog for Calamares-Extensions. For each release, the major
 | 
			
		||||
changes and contributors are listed. Note that Calamares-Extensions does not
 | 
			
		||||
have a historical changelog -- this log starts with version 1.0.0.
 | 
			
		||||
 | 
			
		||||
# 1.3.2 (2023-08-28)
 | 
			
		||||
 | 
			
		||||
We skipped a couple of releases in the release-notes, then tagged
 | 
			
		||||
1.3.1 without a version bump or release-notes. So 1.3.2 brings us
 | 
			
		||||
back to "regular releases".
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Nathan Schulte
 | 
			
		||||
 - Oliver Smith
 | 
			
		||||
 - stravanpannala
 | 
			
		||||
 - undef
 | 
			
		||||
 | 
			
		||||
Changes and new modules in this release:
 | 
			
		||||
 - *mobile* Has new configuration options. (Thanks Nathan, Oliver)
 | 
			
		||||
 - *unpackfsc* Uses a more portable invocation of tar. (Thanks sravanpannala)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 1.2.1 (2021-11-16)
 | 
			
		||||
 | 
			
		||||
The 1.2.0 release had no release-notes for that version, and failed to
 | 
			
		||||
credit Anke and Otus.
 | 
			
		||||
 | 
			
		||||
Changes and new modules in this release:
 | 
			
		||||
 - *unpackfsc* can use `fsarchiver` and unpack that, instead of squashfs;
 | 
			
		||||
   a distro might choose one tool or the other. Currently, only *savedir* /
 | 
			
		||||
   *restdir* mode (i.e. directories, not block-devices) are supported.
 | 
			
		||||
 | 
			
		||||
# 1.2.0 (2021-11-16)
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 - Anke Boersma
 | 
			
		||||
 - Otus9051
 | 
			
		||||
 | 
			
		||||
Changes and new modules in this release:
 | 
			
		||||
 - *refind* is a new module that installs the rEFInd bootloader. It can
 | 
			
		||||
   be used instead of the *bootloader* module from core Calamares. (Thanks Anke)
 | 
			
		||||
 - *unpackfsc* is a new module that uses `unsquashfs` directly. This may
 | 
			
		||||
   be faster or more convenient than the *unpackfs* module from core Calamares.
 | 
			
		||||
   The configuration file supports only one entry, but is otherwise easy to
 | 
			
		||||
   adapt from an existing `unpackfs.conf`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# 1.1.2 (2021-05-14)
 | 
			
		||||
 | 
			
		||||
This release contains contributions from (alphabetically by first name):
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
@@ -36,23 +31,41 @@
 | 
			
		||||
#   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.3.2 )
 | 
			
		||||
 | 
			
		||||
include( ${CMAKE_CURRENT_LIST_DIR}/CMakeModules/ExtendedVersion.cmake )
 | 
			
		||||
if ( CMAKE_SCRIPT_MODE_FILE )
 | 
			
		||||
    report_version( ${CALAMARES_EXTENSIONS_VERSION} ${CMAKE_CURRENT_LIST_DIR} )
 | 
			
		||||
    return()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
project(calamares-extensions
 | 
			
		||||
    VERSION 1.1.2
 | 
			
		||||
    VERSION ${CALAMARES_EXTENSIONS_VERSION}
 | 
			
		||||
    LANGUAGES CXX
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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).
 | 
			
		||||
find_package(Calamares 3.2.26 REQUIRED NO_CMAKE_PACKAGE_REGISTRY)
 | 
			
		||||
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)
 | 
			
		||||
    message(FATAL_ERROR "Calamares found with missing CMake targets")
 | 
			
		||||
    find_package(Calamares ${CALAMARES_VERSION_REQUIRED} REQUIRED)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_package(YAMLCPP REQUIRED)  # Needed to untangle some dependencies before Calamares 3.2.36
 | 
			
		||||
 | 
			
		||||
### CMAKE SETUP
 | 
			
		||||
#
 | 
			
		||||
# Enable IN_LIST
 | 
			
		||||
@@ -71,6 +84,7 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.10.0")
 | 
			
		||||
        "K_EXPORT_PLASMA_RUNNER"
 | 
			
		||||
    )
 | 
			
		||||
endif()
 | 
			
		||||
include( CTest )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### BRANDING
 | 
			
		||||
@@ -97,28 +111,14 @@ calamares_add_branding_subdirectory( branding/kaos_branding NAME kaos )
 | 
			
		||||
#
 | 
			
		||||
set(LIST_SKIPPED_MODULES "")
 | 
			
		||||
 | 
			
		||||
calamares_add_module_subdirectory( modules/filekeeper LIST_SKIPPED_MODULES )  # C++ 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( ${LIST_SKIPPED_MODULES} )
 | 
			
		||||
 | 
			
		||||
### RELEASE SUPPORT
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
set( CALAMARES_VERSION ${calamares-extensions_VERSION_MAJOR}.${calamares-extensions_VERSION_MINOR}.${calamares-extensions_VERSION_PATCH} )
 | 
			
		||||
# In rare cases we have hotfix-releases with a tweak
 | 
			
		||||
if( calamares-extensions_VERSION_TWEAK )
 | 
			
		||||
    set( CALAMARES_VERSION "${calamares-extensions_VERSION}.${calamares-extensions_VERSION_TWEAK}" )
 | 
			
		||||
endif()
 | 
			
		||||
set( CALAMARES_VERSION_SHORT "${CALAMARES_VERSION}" )
 | 
			
		||||
 | 
			
		||||
add_custom_target(show-version
 | 
			
		||||
    ${CMAKE_COMMAND} -E echo CALAMARES_VERSION=${CALAMARES_VERSION_SHORT}
 | 
			
		||||
    USES_TERMINAL
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										90
									
								
								CMakeModules/ExtendedVersion.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								CMakeModules/ExtendedVersion.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
 | 
			
		||||
#   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
###
 | 
			
		||||
#
 | 
			
		||||
# This file defines one function for extending a VERSION-like value
 | 
			
		||||
# with date and git information (if desired).
 | 
			
		||||
#
 | 
			
		||||
# - extend_version( version-string short_var long_var )
 | 
			
		||||
#   Calling this function will copy *version-string* (which would typically
 | 
			
		||||
#   be a semver-style string, like "3.2.40") into the variable *short_var*.
 | 
			
		||||
#   The *version-string* plus date and git information (if git is available),
 | 
			
		||||
#   is copied into the varialbe *long_var*, in the format {version}-{date}-{hash}
 | 
			
		||||
#
 | 
			
		||||
# A helper function that may be used independently:
 | 
			
		||||
#
 | 
			
		||||
# - get_git_version_info( out_var )
 | 
			
		||||
#   If relevant and possible (e.g. it is a git checkout and git is availablle
 | 
			
		||||
#   in the environment), put git versioning information in *out_var*.
 | 
			
		||||
#
 | 
			
		||||
# A convenience function for use from script-mode for version reporting:
 | 
			
		||||
#
 | 
			
		||||
# - report_version( version top_dir )
 | 
			
		||||
#   Call this with an intended version string (e.g. "1.1") and
 | 
			
		||||
#   the top-level source directory (e.g. `${CMAKE_CURRENT_LIST_DIR}`
 | 
			
		||||
#   or `${CMAKE_SOURCE_DIR}` .. in script mode, the latter is not defined).
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
function( get_git_version_info out_var )
 | 
			
		||||
    set(CMAKE_VERSION_SOURCE "")
 | 
			
		||||
    if(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD)
 | 
			
		||||
        find_program(GIT_EXECUTABLE NAMES git git.cmd)
 | 
			
		||||
        mark_as_advanced(GIT_EXECUTABLE)
 | 
			
		||||
        if(GIT_EXECUTABLE)
 | 
			
		||||
            execute_process(
 | 
			
		||||
                COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=8 HEAD
 | 
			
		||||
                OUTPUT_VARIABLE head
 | 
			
		||||
                OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
                WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
            )
 | 
			
		||||
            if(head)
 | 
			
		||||
                set(CMAKE_VERSION_SOURCE "${head}")
 | 
			
		||||
                execute_process(
 | 
			
		||||
                    COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
 | 
			
		||||
                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
                )
 | 
			
		||||
                execute_process(
 | 
			
		||||
                    COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
 | 
			
		||||
                    OUTPUT_VARIABLE dirty
 | 
			
		||||
                    OUTPUT_STRIP_TRAILING_WHITESPACE
 | 
			
		||||
                    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
 | 
			
		||||
                )
 | 
			
		||||
                if(dirty)
 | 
			
		||||
                    set(CMAKE_VERSION_SOURCE "${CMAKE_VERSION_SOURCE}-dirty")
 | 
			
		||||
                endif()
 | 
			
		||||
            endif()
 | 
			
		||||
        endif()
 | 
			
		||||
    endif()
 | 
			
		||||
    set( ${out_var} "${CMAKE_VERSION_SOURCE}" PARENT_SCOPE )
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
function( extend_version version short_var long_var )
 | 
			
		||||
    set( ${short_var} "${version}" PARENT_SCOPE )
 | 
			
		||||
 | 
			
		||||
    # Additional info for non-release builds which want "long" version info
 | 
			
		||||
    # with date and git information (commit, dirty status).
 | 
			
		||||
    set( _v "${version}" )
 | 
			
		||||
    string( TIMESTAMP CALAMARES_VERSION_DATE "%Y%m%d" )
 | 
			
		||||
    if( CALAMARES_VERSION_DATE GREATER 0 )
 | 
			
		||||
        set( _v ${_v}.${CALAMARES_VERSION_DATE} )
 | 
			
		||||
    endif()
 | 
			
		||||
    get_git_version_info( _gitv )
 | 
			
		||||
    if( _gitv )
 | 
			
		||||
        set( _v "${_v}-${_gitv}" )
 | 
			
		||||
    endif()
 | 
			
		||||
    set( ${long_var} "${_v}" PARENT_SCOPE )
 | 
			
		||||
endfunction()
 | 
			
		||||
 | 
			
		||||
function( report_version version top_dir )
 | 
			
		||||
    set( CMAKE_SOURCE_DIR ${top_dir} )
 | 
			
		||||
    extend_version( ${version} _vshort _vlong )
 | 
			
		||||
    if ( "x${VERSION_STYLE}" STREQUAL "xshort" )
 | 
			
		||||
        message( "${_vshort}" )
 | 
			
		||||
    else()
 | 
			
		||||
        message( "${_vlong}" )
 | 
			
		||||
    endif()
 | 
			
		||||
endfunction()
 | 
			
		||||
							
								
								
									
										40
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
<!-- SPDX-FileCopyrightText: no
 | 
			
		||||
     SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
# Contributing to Calamares Extensions
 | 
			
		||||
 | 
			
		||||
Welcome to Calamares! We're happy that you would like to add
 | 
			
		||||
something to Calamares -- by extending it!
 | 
			
		||||
This contribution guide is minimal:
 | 
			
		||||
all the **technical** parts of contributing to
 | 
			
		||||
Calamares Extensions are the same as [contributing to Calamares](https://github.com/calamares/calamares/CONTRIBUTING.md).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Code of Conduct
 | 
			
		||||
 | 
			
		||||
The Calamares community -- of developers, translators, and downstream (distro) users --
 | 
			
		||||
aims to be courteous, professional, and inclusive. Harrassment, discriminatory
 | 
			
		||||
statements and abuse are not tolerated. In general, we apply the
 | 
			
		||||
[KDE Code of Conduct](https://www.kde.org/code-of-conduct/) and the
 | 
			
		||||
[GNOME Code of Conduct](https://wiki.gnome.org/Foundation/CodeOfConduct) (the
 | 
			
		||||
rules of decent behavior in both communities are pretty much the same).
 | 
			
		||||
 | 
			
		||||
> See the [CoC section on the wiki](https://github.com/calamares/calamares/wiki#code-of-conduct)
 | 
			
		||||
> for a longer text. To report a problem, please contact the maintainer,
 | 
			
		||||
> Adriaan de Groot, or the KDE Community Working Group.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Join the Conversation
 | 
			
		||||
 | 
			
		||||
GitHub Issues are **one** place for discussing Calamares and its extensions if there are concrete
 | 
			
		||||
problems or a new feature to discuss.
 | 
			
		||||
Issues are not a help channel.
 | 
			
		||||
Visit Matrix for help with configuration or compilation.
 | 
			
		||||
 | 
			
		||||
Regular Calamares development chit-chat happens in a [Matrix](https://matrix.org/)
 | 
			
		||||
room, `#calamares:kde.org`. Responsiveness is best during the day
 | 
			
		||||
in Europe, but feel free to idle.
 | 
			
		||||
Matrix is persistent, and we'll see your message eventually.
 | 
			
		||||
 | 
			
		||||
* [](https://webchat.kde.org/#/room/%23calamares:kde.org)
 | 
			
		||||
							
								
								
									
										24
									
								
								LICENSES/BSD-2-Clause.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								LICENSES/BSD-2-Clause.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
 | 
			
		||||
 Copyright 2019 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 | 
			
		||||
 Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 modification, are permitted provided that the following conditions
 | 
			
		||||
 are met:
 | 
			
		||||
 | 
			
		||||
   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 | 
			
		||||
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
 POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
							
								
								
									
										119
									
								
								LICENSES/CC0-1.0.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								LICENSES/CC0-1.0.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
Creative Commons Legal Code
 | 
			
		||||
 | 
			
		||||
CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES
 | 
			
		||||
NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE
 | 
			
		||||
AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
 | 
			
		||||
ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE
 | 
			
		||||
OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS
 | 
			
		||||
LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION
 | 
			
		||||
OR WORKS PROVIDED HEREUNDER.
 | 
			
		||||
 | 
			
		||||
Statement of Purpose
 | 
			
		||||
 | 
			
		||||
The laws of most jurisdictions throughout the world automatically confer exclusive
 | 
			
		||||
Copyright and Related Rights (defined below) upon the creator and subsequent
 | 
			
		||||
owner(s) (each and all, an "owner") of an original work of authorship and/or
 | 
			
		||||
a database (each, a "Work").
 | 
			
		||||
 | 
			
		||||
Certain owners wish to permanently relinquish those rights to a Work for the
 | 
			
		||||
purpose of contributing to a commons of creative, cultural and scientific
 | 
			
		||||
works ("Commons") that the public can reliably and without fear of later claims
 | 
			
		||||
of infringement build upon, modify, incorporate in other works, reuse and
 | 
			
		||||
redistribute as freely as possible in any form whatsoever and for any purposes,
 | 
			
		||||
including without limitation commercial purposes. These owners may contribute
 | 
			
		||||
to the Commons to promote the ideal of a free culture and the further production
 | 
			
		||||
of creative, cultural and scientific works, or to gain reputation or greater
 | 
			
		||||
distribution for their Work in part through the use and efforts of others.
 | 
			
		||||
 | 
			
		||||
For these and/or other purposes and motivations, and without any expectation
 | 
			
		||||
of additional consideration or compensation, the person associating CC0 with
 | 
			
		||||
a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
 | 
			
		||||
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
 | 
			
		||||
and publicly distribute the Work under its terms, with knowledge of his or
 | 
			
		||||
her Copyright and Related Rights in the Work and the meaning and intended
 | 
			
		||||
legal effect of CC0 on those rights.
 | 
			
		||||
 | 
			
		||||
1. Copyright and Related Rights. A Work made available under CC0 may be protected
 | 
			
		||||
by copyright and related or neighboring rights ("Copyright and Related Rights").
 | 
			
		||||
Copyright and Related Rights include, but are not limited to, the following:
 | 
			
		||||
 | 
			
		||||
i. the right to reproduce, adapt, distribute, perform, display, communicate,
 | 
			
		||||
and translate a Work;
 | 
			
		||||
 | 
			
		||||
      ii. moral rights retained by the original author(s) and/or performer(s);
 | 
			
		||||
 | 
			
		||||
iii. publicity and privacy rights pertaining to a person's image or likeness
 | 
			
		||||
depicted in a Work;
 | 
			
		||||
 | 
			
		||||
iv. rights protecting against unfair competition in regards to a Work, subject
 | 
			
		||||
to the limitations in paragraph 4(a), below;
 | 
			
		||||
 | 
			
		||||
v. rights protecting the extraction, dissemination, use and reuse of data
 | 
			
		||||
in a Work;
 | 
			
		||||
 | 
			
		||||
vi. database rights (such as those arising under Directive 96/9/EC of the
 | 
			
		||||
European Parliament and of the Council of 11 March 1996 on the legal protection
 | 
			
		||||
of databases, and under any national implementation thereof, including any
 | 
			
		||||
amended or successor version of such directive); and
 | 
			
		||||
 | 
			
		||||
vii. other similar, equivalent or corresponding rights throughout the world
 | 
			
		||||
based on applicable law or treaty, and any national implementations thereof.
 | 
			
		||||
 | 
			
		||||
2. Waiver. To the greatest extent permitted by, but not in contravention of,
 | 
			
		||||
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
 | 
			
		||||
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
 | 
			
		||||
and Related Rights and associated claims and causes of action, whether now
 | 
			
		||||
known or unknown (including existing as well as future claims and causes of
 | 
			
		||||
action), in the Work (i) in all territories worldwide, (ii) for the maximum
 | 
			
		||||
duration provided by applicable law or treaty (including future time extensions),
 | 
			
		||||
(iii) in any current or future medium and for any number of copies, and (iv)
 | 
			
		||||
for any purpose whatsoever, including without limitation commercial, advertising
 | 
			
		||||
or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the
 | 
			
		||||
benefit of each member of the public at large and to the detriment of Affirmer's
 | 
			
		||||
heirs and successors, fully intending that such Waiver shall not be subject
 | 
			
		||||
to revocation, rescission, cancellation, termination, or any other legal or
 | 
			
		||||
equitable action to disrupt the quiet enjoyment of the Work by the public
 | 
			
		||||
as contemplated by Affirmer's express Statement of Purpose.
 | 
			
		||||
 | 
			
		||||
3. Public License Fallback. Should any part of the Waiver for any reason be
 | 
			
		||||
judged legally invalid or ineffective under applicable law, then the Waiver
 | 
			
		||||
shall be preserved to the maximum extent permitted taking into account Affirmer's
 | 
			
		||||
express Statement of Purpose. In addition, to the extent the Waiver is so
 | 
			
		||||
judged Affirmer hereby grants to each affected person a royalty-free, non
 | 
			
		||||
transferable, non sublicensable, non exclusive, irrevocable and unconditional
 | 
			
		||||
license to exercise Affirmer's Copyright and Related Rights in the Work (i)
 | 
			
		||||
in all territories worldwide, (ii) for the maximum duration provided by applicable
 | 
			
		||||
law or treaty (including future time extensions), (iii) in any current or
 | 
			
		||||
future medium and for any number of copies, and (iv) for any purpose whatsoever,
 | 
			
		||||
including without limitation commercial, advertising or promotional purposes
 | 
			
		||||
(the "License"). The License shall be deemed effective as of the date CC0
 | 
			
		||||
was applied by Affirmer to the Work. Should any part of the License for any
 | 
			
		||||
reason be judged legally invalid or ineffective under applicable law, such
 | 
			
		||||
partial invalidity or ineffectiveness shall not invalidate the remainder of
 | 
			
		||||
the License, and in such case Affirmer hereby affirms that he or she will
 | 
			
		||||
not (i) exercise any of his or her remaining Copyright and Related Rights
 | 
			
		||||
in the Work or (ii) assert any associated claims and causes of action with
 | 
			
		||||
respect to the Work, in either case contrary to Affirmer's express Statement
 | 
			
		||||
of Purpose.
 | 
			
		||||
 | 
			
		||||
   4. Limitations and Disclaimers.
 | 
			
		||||
 | 
			
		||||
a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered,
 | 
			
		||||
licensed or otherwise affected by this document.
 | 
			
		||||
 | 
			
		||||
b. Affirmer offers the Work as-is and makes no representations or warranties
 | 
			
		||||
of any kind concerning the Work, express, implied, statutory or otherwise,
 | 
			
		||||
including without limitation warranties of title, merchantability, fitness
 | 
			
		||||
for a particular purpose, non infringement, or the absence of latent or other
 | 
			
		||||
defects, accuracy, or the present or absence of errors, whether or not discoverable,
 | 
			
		||||
all to the greatest extent permissible under applicable law.
 | 
			
		||||
 | 
			
		||||
c. Affirmer disclaims responsibility for clearing rights of other persons
 | 
			
		||||
that may apply to the Work or any use thereof, including without limitation
 | 
			
		||||
any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims
 | 
			
		||||
responsibility for obtaining any necessary consents, permissions or other
 | 
			
		||||
rights required for any use of the Work.
 | 
			
		||||
 | 
			
		||||
d. Affirmer understands and acknowledges that Creative Commons is not a party
 | 
			
		||||
to this document and has no duty or obligation with respect to this CC0 or
 | 
			
		||||
use of the Work.
 | 
			
		||||
							
								
								
									
										24
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								README.md
									
									
									
									
									
								
							@@ -1,3 +1,7 @@
 | 
			
		||||
<!-- SPDX-FileCopyrightText: no
 | 
			
		||||
     SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
-->
 | 
			
		||||
 | 
			
		||||
# Calamares Branding and Module Examples
 | 
			
		||||
 | 
			
		||||
> A *branding component* in Calamares is a description of the
 | 
			
		||||
@@ -36,7 +40,10 @@ and documentation for the framework that Calamares ships with.
 | 
			
		||||
   (probably moreso than the default slideshow).
 | 
			
		||||
 - [`kaos_branding/`](branding/kaos_branding/branding.desc)
 | 
			
		||||
   is a copy of the KaOS branding component, which
 | 
			
		||||
   has translations and a bunch of fancy graphics.
 | 
			
		||||
   has translations and a bunch of fancy graphics for the
 | 
			
		||||
   slideshow. Plus it includes examples of using different
 | 
			
		||||
   QML options for a vertical navigation bar and horizontal
 | 
			
		||||
   sidebar.
 | 
			
		||||
 - [`samegame/` ](branding/default/branding.desc)
 | 
			
		||||
   is a copy of the Qt Company "Same Game" QML demo. It
 | 
			
		||||
   shows that **any** QML can be used for branding purposes.
 | 
			
		||||
@@ -207,3 +214,18 @@ usually called `main.py` which defines a `run()` function.
 | 
			
		||||
 | 
			
		||||
The API is loosely documented in the
 | 
			
		||||
[developer guide](https://github.com/calamares/calamares/wiki/Develop-Guide).
 | 
			
		||||
 | 
			
		||||
# Join the Conversation
 | 
			
		||||
 | 
			
		||||
GitHub Issues are **one** place for discussing Calamares (and Calamares Extensions)
 | 
			
		||||
if there are concrete
 | 
			
		||||
problems or a new feature to discuss.
 | 
			
		||||
Issues are not a help channel.
 | 
			
		||||
Visit Matrix for help with configuration or compilation.
 | 
			
		||||
 | 
			
		||||
Regular Calamares development chit-chat happens in a [Matrix](https://matrix.org/)
 | 
			
		||||
room, `#calamares:kde.org`. Responsiveness is best during the day
 | 
			
		||||
in Europe, but feel free to idle.
 | 
			
		||||
Matrix is persistent, and we'll see your message eventually.
 | 
			
		||||
 | 
			
		||||
* [](https://webchat.kde.org/#/room/%23calamares:kde.org)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										101
									
								
								branding/kaos_branding/about.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								branding/kaos_branding/about.qml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2020 2022 Anke Boersma <demm@kaosx.us>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import io.calamares.core 1.0
 | 
			
		||||
import io.calamares.ui 1.0
 | 
			
		||||
 | 
			
		||||
import QtQuick 2.7
 | 
			
		||||
import QtQuick.Controls 2.0
 | 
			
		||||
import QtQuick.Layouts 1.3
 | 
			
		||||
import QtQuick.Window 2.3
 | 
			
		||||
 | 
			
		||||
ApplicationWindow {
 | 
			
		||||
    id: about
 | 
			
		||||
    visible: true
 | 
			
		||||
    width: 760
 | 
			
		||||
    height: 400
 | 
			
		||||
    title: qsTr("About Calamares")
 | 
			
		||||
 | 
			
		||||
    property var appName: "Calamares"
 | 
			
		||||
    property var appVersion: "3.3 RC"
 | 
			
		||||
 | 
			
		||||
    Rectangle {
 | 
			
		||||
        id: textArea
 | 
			
		||||
        anchors.fill: parent
 | 
			
		||||
        color: "#f2f2f2"
 | 
			
		||||
 | 
			
		||||
        Column {
 | 
			
		||||
            id: column
 | 
			
		||||
            anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            Rectangle {
 | 
			
		||||
                width: 560
 | 
			
		||||
                height: 250
 | 
			
		||||
                radius: 10
 | 
			
		||||
                border.width: 0
 | 
			
		||||
 | 
			
		||||
                Text {
 | 
			
		||||
                    width: 400
 | 
			
		||||
                    height: 250
 | 
			
		||||
                    anchors.centerIn: parent
 | 
			
		||||
                    text: qsTr("<h1>%1</h1><br/>
 | 
			
		||||
                        <strong>%2<br/>
 | 
			
		||||
                        for %3</strong><br/><br/>
 | 
			
		||||
                        Copyright 2014-2017 Teo Mrnjavac <teo@kde.org><br/>
 | 
			
		||||
                        Copyright 2017-2022 Adriaan de Groot <groot@kde.org><br/>
 | 
			
		||||
                        Thanks to <a href='https://calamares.io/team/'>the Calamares team</a>
 | 
			
		||||
                        and the <a href=\"https://www.transifex.com/kaos/kaos/\">KaOS
 | 
			
		||||
                        translators team</a>.<br/><br/>
 | 
			
		||||
                        <a href='https://calamares.io/'>Calamares</a>
 | 
			
		||||
                        development is sponsored by <br/>
 | 
			
		||||
                        <a href='http://www.blue-systems.com/'>Blue Systems</a> -
 | 
			
		||||
                        Liberating Software." )
 | 
			
		||||
                        .arg(appName)
 | 
			
		||||
                        .arg(appVersion)
 | 
			
		||||
                        .arg(Branding.string(Branding.VersionedName))
 | 
			
		||||
 | 
			
		||||
                        onLinkActivated: Qt.openUrlExternally(link)
 | 
			
		||||
 | 
			
		||||
                        MouseArea {
 | 
			
		||||
                            anchors.fill: parent
 | 
			
		||||
                            acceptedButtons: Qt.NoButton
 | 
			
		||||
                            cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    font.pointSize: 10
 | 
			
		||||
                    anchors.verticalCenterOffset: 10
 | 
			
		||||
                    anchors.horizontalCenterOffset: 40
 | 
			
		||||
                    wrapMode: Text.WordWrap
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Image {
 | 
			
		||||
                    id: image
 | 
			
		||||
                    x: 8
 | 
			
		||||
                    y: 12
 | 
			
		||||
                    height: 100
 | 
			
		||||
                    fillMode: Image.PreserveAspectFit
 | 
			
		||||
                    source: "squid.png"
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Button {
 | 
			
		||||
            anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
            anchors.bottom: parent.bottom
 | 
			
		||||
            icon.name: "window-close"
 | 
			
		||||
            text: qsTr("Close")
 | 
			
		||||
            hoverEnabled: true
 | 
			
		||||
            onClicked: about.close();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,22 +1,32 @@
 | 
			
		||||
---
 | 
			
		||||
componentName:  kaos
 | 
			
		||||
 | 
			
		||||
welcomeStyleCalamares:   false
 | 
			
		||||
 | 
			
		||||
# Should the welcome image (productWelcome, below) be scaled
 | 
			
		||||
# up beyond its natural size?
 | 
			
		||||
welcomeExpandingLogo:   true
 | 
			
		||||
 | 
			
		||||
windowExpanding:    normal
 | 
			
		||||
windowSize: 920px,630px
 | 
			
		||||
windowPlacement: center
 | 
			
		||||
 | 
			
		||||
sidebar: qml,bottom
 | 
			
		||||
navigation: qml,right
 | 
			
		||||
 | 
			
		||||
strings:
 | 
			
		||||
    productName:         KaOS
 | 
			
		||||
    shortProductName:    KaOS
 | 
			
		||||
    version:             2018.03
 | 
			
		||||
    version:             2022.08
 | 
			
		||||
    shortVersion:        KaOS
 | 
			
		||||
    versionedName:       KaOS 2018.03
 | 
			
		||||
    versionedName:       KaOS 2022.08
 | 
			
		||||
    shortVersionedName:  KaOS 2018.03
 | 
			
		||||
    bootloaderEntryName: KaOS
 | 
			
		||||
    productUrl:          https://kaosx.us/
 | 
			
		||||
    supportUrl:          https://kaosx.us/docs/
 | 
			
		||||
    knownIssuesUrl:      https://kaosx.us/pages/download/#known-issues
 | 
			
		||||
    releaseNotesUrl:     https://kaosx.us/pages/release_notes
 | 
			
		||||
    donateUrl:           https://kaosx.us/about/donors
 | 
			
		||||
 | 
			
		||||
images:
 | 
			
		||||
    productLogo:         "kaos.png"
 | 
			
		||||
@@ -27,6 +37,7 @@ slideshow:               "show.qml"
 | 
			
		||||
slideshowAPI:            1
 | 
			
		||||
 | 
			
		||||
style:
 | 
			
		||||
   sidebarBackground:    "#bdc3c7"
 | 
			
		||||
   sidebarText:          "#1F1F1F"
 | 
			
		||||
   sidebarTextSelect:    "#3498DB"
 | 
			
		||||
   SidebarBackground:    "#bdc3c7"
 | 
			
		||||
   SidebarText:          "#1F1F1F"
 | 
			
		||||
   SidebarTextCurrent:    "#3498DB"
 | 
			
		||||
   SidebarBackgroundCurrent: "#eff0f1"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										224
									
								
								branding/kaos_branding/calamares-navigation.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								branding/kaos_branding/calamares-navigation.qml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,224 @@
 | 
			
		||||
/* Sample of QML navigation.
 | 
			
		||||
 | 
			
		||||
   SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
   SPDX-FileCopyrightText: 2021 - 2022 Anke Boersma <demm@kaosx.us>
 | 
			
		||||
   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   This navigation panel is for a "vertical" layout, with
 | 
			
		||||
   mouse areas for next and previous and it includes the logo
 | 
			
		||||
   plus About & Debug buttons.
 | 
			
		||||
*/
 | 
			
		||||
import io.calamares.ui 1.0
 | 
			
		||||
import io.calamares.core 1.0
 | 
			
		||||
 | 
			
		||||
import QtQuick 2.3
 | 
			
		||||
import QtQuick.Controls 2.10
 | 
			
		||||
import QtQuick.Layouts 1.3
 | 
			
		||||
 | 
			
		||||
Rectangle {
 | 
			
		||||
    id: navigationBar;
 | 
			
		||||
    color: Branding.styleString( Branding.SidebarBackground );
 | 
			
		||||
    height: parent.height;
 | 
			
		||||
    width:64;
 | 
			
		||||
 | 
			
		||||
    ColumnLayout {
 | 
			
		||||
        id: buttonBar
 | 
			
		||||
        anchors.fill: parent;
 | 
			
		||||
        spacing: 1
 | 
			
		||||
 | 
			
		||||
        Image {
 | 
			
		||||
            Layout.topMargin: 1;
 | 
			
		||||
            Layout.bottomMargin:parent.height / 7;
 | 
			
		||||
            Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
 | 
			
		||||
            id: logo;
 | 
			
		||||
            width: 62;
 | 
			
		||||
            height: width;  // square
 | 
			
		||||
            source: "file:/" + Branding.imagePath(Branding.ProductLogo);
 | 
			
		||||
            sourceSize.width: width;
 | 
			
		||||
            sourceSize.height: height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle {
 | 
			
		||||
            id: backArea
 | 
			
		||||
            Layout.fillWidth: true;
 | 
			
		||||
            Layout.preferredHeight: parent.height / 7;
 | 
			
		||||
            color: mouseBack.containsMouse ? "#e6e9ea" : "#d9dcde";
 | 
			
		||||
            enabled: ViewManager.backEnabled;
 | 
			
		||||
            visible: ViewManager.backAndNextVisible;
 | 
			
		||||
 | 
			
		||||
            MouseArea {
 | 
			
		||||
                id: mouseBack
 | 
			
		||||
                anchors.fill: parent;
 | 
			
		||||
                cursorShape: Qt.PointingHandCursor
 | 
			
		||||
                hoverEnabled: true
 | 
			
		||||
 | 
			
		||||
                Text {
 | 
			
		||||
                    anchors.centerIn: parent
 | 
			
		||||
                    text: qsTr("Back")
 | 
			
		||||
                    color: Branding.styleString( !backArea.enabled ? Branding.SidebarBackground : (mouseBack.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarText ));
 | 
			
		||||
                    font.pointSize : 8
 | 
			
		||||
                }
 | 
			
		||||
                Image {
 | 
			
		||||
                    source: "pan-start-symbolic.svg"
 | 
			
		||||
                    anchors.centerIn: parent
 | 
			
		||||
                    anchors.verticalCenterOffset : 18
 | 
			
		||||
                    fillMode: Image.PreserveAspectFit
 | 
			
		||||
                    height: 32
 | 
			
		||||
                    opacity: backArea.enabled ? 1 : 0.2
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                onClicked: { ViewManager.back(); }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle {
 | 
			
		||||
            id: nextArea
 | 
			
		||||
            Layout.preferredHeight: parent.height / 7;
 | 
			
		||||
            Layout.fillWidth: true
 | 
			
		||||
            color: mouseNext.containsMouse ? "#f4f5f6" : "#e6e9ea";
 | 
			
		||||
            enabled: ViewManager.nextEnabled;
 | 
			
		||||
            visible: ViewManager.backAndNextVisible;
 | 
			
		||||
 | 
			
		||||
            MouseArea {
 | 
			
		||||
                id: mouseNext
 | 
			
		||||
                anchors.fill: parent;
 | 
			
		||||
                cursorShape: Qt.PointingHandCursor
 | 
			
		||||
                hoverEnabled: true
 | 
			
		||||
                Text {
 | 
			
		||||
                    anchors.centerIn: parent
 | 
			
		||||
                    text: qsTr("Next")
 | 
			
		||||
                    color: Branding.styleString( !nextArea.enabled ? Branding.SidebarBackground : (mouseNext.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarText ));
 | 
			
		||||
                    font.pointSize : 8
 | 
			
		||||
                }
 | 
			
		||||
                Image {
 | 
			
		||||
                    source: "pan-end-symbolic.svg"
 | 
			
		||||
                    anchors.centerIn: parent
 | 
			
		||||
                    anchors.verticalCenterOffset : 18
 | 
			
		||||
                    fillMode: Image.PreserveAspectFit
 | 
			
		||||
                    height: 32
 | 
			
		||||
                    opacity: nextArea.enabled ? 1 : 0.2
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                onClicked: { ViewManager.next(); }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle {
 | 
			
		||||
            id: cancelArea
 | 
			
		||||
            height: parent.height / 7;
 | 
			
		||||
            Layout.fillWidth: true
 | 
			
		||||
            color: mouseCancel.containsMouse ? "#e6e9ea" : "#d9dcde";
 | 
			
		||||
 | 
			
		||||
             /*
 | 
			
		||||
             * The ViewManager has settings -- user-controlled via the
 | 
			
		||||
             * branding component, and party based on program state --
 | 
			
		||||
             * whether the quit button should be enabled and visible.
 | 
			
		||||
             *
 | 
			
		||||
             * QML navigation *should* follow this pattern, but can also
 | 
			
		||||
             * add other qualifications. For instance, you may have a
 | 
			
		||||
             * "finished" module that handles quit in its own way, and
 | 
			
		||||
             * want to hide the quit button then. The ViewManager has a
 | 
			
		||||
             * current step and a total count, so compare them:
 | 
			
		||||
             *
 | 
			
		||||
             * visible: ViewManager.quitVisible && ( ViewManager.currentStepIndex < ViewManager.rowCount()-1);
 | 
			
		||||
             */
 | 
			
		||||
 | 
			
		||||
             enabled: ViewManager.quitEnabled;
 | 
			
		||||
             visible: ViewManager.quitVisible && ( ViewManager.currentStepIndex < ViewManager.rowCount()-1);
 | 
			
		||||
 | 
			
		||||
            ToolTip {
 | 
			
		||||
                width: 59
 | 
			
		||||
                visible: mouseCancel.containsMouse
 | 
			
		||||
                timeout: 5000
 | 
			
		||||
                delay: 1000
 | 
			
		||||
                text: ViewManager.quitTooltip;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            MouseArea {
 | 
			
		||||
                id: mouseCancel
 | 
			
		||||
                anchors.fill: parent;
 | 
			
		||||
                cursorShape: Qt.PointingHandCursor
 | 
			
		||||
                hoverEnabled: true
 | 
			
		||||
                Text {
 | 
			
		||||
                    anchors.centerIn: parent
 | 
			
		||||
                    text: qsTr("Cancel")
 | 
			
		||||
                    color: Branding.styleString( !cancelArea.enabled ? Branding.SidebarBackground : (mouseCancel.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarText ));
 | 
			
		||||
                    font.pointSize : 8
 | 
			
		||||
                }
 | 
			
		||||
                Image {
 | 
			
		||||
                    source: "draw-rectangle.svg"
 | 
			
		||||
                    anchors.centerIn: parent
 | 
			
		||||
                    anchors.verticalCenterOffset : 18
 | 
			
		||||
                    fillMode: Image.PreserveAspectFit
 | 
			
		||||
                    height: 9
 | 
			
		||||
                    opacity: cancelArea.enabled ? 1 : 0.2
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                onClicked: { ViewManager.quit(); }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Item {
 | 
			
		||||
            Layout.fillHeight: true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle {
 | 
			
		||||
            id: debugArea
 | 
			
		||||
            Layout.fillWidth: true;
 | 
			
		||||
            height: 35
 | 
			
		||||
            Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
 | 
			
		||||
            color: Branding.styleString( mouseAreaDebug.containsMouse ? Branding.SidebarBackgroundCurrent : Branding.SidebarBackground);
 | 
			
		||||
            visible: debug.enabled
 | 
			
		||||
 | 
			
		||||
            MouseArea {
 | 
			
		||||
                id: mouseAreaDebug
 | 
			
		||||
                anchors.fill: parent;
 | 
			
		||||
                cursorShape: Qt.PointingHandCursor
 | 
			
		||||
                hoverEnabled: true
 | 
			
		||||
                Text {
 | 
			
		||||
                    anchors.centerIn: parent
 | 
			
		||||
                    text: qsTr("Debug")
 | 
			
		||||
                    color: Branding.styleString( mouseAreaDebug.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarBackground );
 | 
			
		||||
                    font.pointSize : 8
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                onClicked: debug.toggle()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Rectangle {
 | 
			
		||||
            id: aboutArea
 | 
			
		||||
            Layout.fillWidth: true;
 | 
			
		||||
            height: 35
 | 
			
		||||
            Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
 | 
			
		||||
            color: Branding.styleString( mouseAreaAbout.containsMouse ? Branding.SidebarBackgroundCurrent : Branding.SidebarBackground);
 | 
			
		||||
            visible: true
 | 
			
		||||
 | 
			
		||||
            MouseArea {
 | 
			
		||||
                id: mouseAreaAbout
 | 
			
		||||
                anchors.fill: parent;
 | 
			
		||||
                cursorShape: Qt.PointingHandCursor
 | 
			
		||||
                hoverEnabled: true
 | 
			
		||||
                Text {
 | 
			
		||||
                    anchors.centerIn: parent
 | 
			
		||||
                    text: qsTr("About")
 | 
			
		||||
                    ToolTip {
 | 
			
		||||
                        visible: mouseAreaAbout.containsMouse
 | 
			
		||||
                        delay: 1000
 | 
			
		||||
                        text: qsTr("Info about Calamares")
 | 
			
		||||
                    }
 | 
			
		||||
                    color: Branding.styleString( mouseAreaAbout.containsMouse ? Branding.SidebarTextCurrent : Branding.SidebarBackgroundCurrent );
 | 
			
		||||
                    font.pointSize : 8
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                property variant window;
 | 
			
		||||
                onClicked: {
 | 
			
		||||
                    var component = Qt.createComponent("about.qml");
 | 
			
		||||
                    window = component.createObject();
 | 
			
		||||
                    window.show();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								branding/kaos_branding/calamares-sidebar.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								branding/kaos_branding/calamares-sidebar.qml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
/* Sample of QML progress tree.
 | 
			
		||||
 | 
			
		||||
   SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
   SPDX-FileCopyrightText: 2021 - 2022 Anke Boersma <demm@kaosx.us>
 | 
			
		||||
   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   The progress tree (actually a list) is "horizontal" in this example,
 | 
			
		||||
   with the steps going to the right.
 | 
			
		||||
*/
 | 
			
		||||
import io.calamares.ui 1.0
 | 
			
		||||
import io.calamares.core 1.0
 | 
			
		||||
 | 
			
		||||
import QtQuick 2.3
 | 
			
		||||
import QtQuick.Layouts 1.3
 | 
			
		||||
import QtQuick.Controls 2.15
 | 
			
		||||
 | 
			
		||||
Rectangle {
 | 
			
		||||
    id: sideBar;
 | 
			
		||||
    color: Branding.styleString( Branding.SidebarBackground );
 | 
			
		||||
    height: 48;
 | 
			
		||||
    width: parent.width
 | 
			
		||||
 | 
			
		||||
    RowLayout {
 | 
			
		||||
        anchors.fill: parent;
 | 
			
		||||
        spacing: 2;
 | 
			
		||||
 | 
			
		||||
        Item {
 | 
			
		||||
            Layout.fillHeight: true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Repeater {
 | 
			
		||||
            model: ViewManager
 | 
			
		||||
            Rectangle {
 | 
			
		||||
                Layout.leftMargin: 0;
 | 
			
		||||
                Layout.fillWidth: true;
 | 
			
		||||
                Layout.alignment: Qt.AlignTop;
 | 
			
		||||
                height: 42;
 | 
			
		||||
                radius: 0;
 | 
			
		||||
                color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarBackgroundCurrent : Branding.SidebarBackground );
 | 
			
		||||
 | 
			
		||||
                Text {
 | 
			
		||||
                    anchors.verticalCenter: parent.verticalCenter;
 | 
			
		||||
                    anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
                    x: parent.x + 12;
 | 
			
		||||
                    color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarTextCurrent : Branding.SidebarText );
 | 
			
		||||
                    text: display;
 | 
			
		||||
                    font.pointSize : index == ViewManager.currentStepIndex ? 10 : 9
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Rectangle {
 | 
			
		||||
                    height: 2
 | 
			
		||||
                    width: 800
 | 
			
		||||
                    anchors.bottom: parent.bottom;
 | 
			
		||||
                    border.color: Branding.styleString(ViewManager.currentStepIndex === index ? Branding.SidebarTextCurrent : (ViewManager.currentStepIndex >= index ? Branding.SidebarTextCurrent : Branding.SidebarBackgroundCurrent))
 | 
			
		||||
                    border.width: 3
 | 
			
		||||
 | 
			
		||||
                    Image {
 | 
			
		||||
                        source: "pan-up-symbolic.svg"
 | 
			
		||||
                        id: image
 | 
			
		||||
                        anchors.verticalCenter: parent.verticalCenter;
 | 
			
		||||
                        anchors.verticalCenterOffset : -3
 | 
			
		||||
                        x: parent.x + 35;
 | 
			
		||||
                        fillMode: Image.PreserveAspectFit
 | 
			
		||||
                        height: 32
 | 
			
		||||
                        visible: index == ViewManager.currentStepIndex ? true : false
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								branding/kaos_branding/draw-rectangle.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								branding/kaos_branding/draw-rectangle.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22"><path d="m2 1034.36v16h16v-16z" fill="#566060" transform="translate(1-1031.36)"/></svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 147 B  | 
@@ -1,3 +1,6 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: no
 | 
			
		||||
#   SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
foreach( lang ast ca cs de en es es_AR fr hu id_ID nl_NL pl pt_BR pt_PT ro_RO ru sr_RS tr_TR zh_CN )
 | 
			
		||||
   list( APPEND TS_FILES "${CMAKE_CURRENT_SOURCE_DIR}/calamares-${COMPONENT_NAME}_${lang}.ts" )
 | 
			
		||||
endforeach()
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 292 KiB After Width: | Height: | Size: 106 KiB  | 
							
								
								
									
										15
									
								
								branding/kaos_branding/pan-end-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								branding/kaos_branding/pan-end-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
 | 
			
		||||
<svg height="16" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" version="1.1" width="16" xmlns="http://www.w3.org/2000/svg" enable-background="new">
 | 
			
		||||
 <metadata id="metadata90"/>
 | 
			
		||||
 <defs id="defs7386">
 | 
			
		||||
  <linearGradient id="linearGradient5606" osb:paint="solid">
 | 
			
		||||
   <stop id="stop5608"/>
 | 
			
		||||
  </linearGradient>
 | 
			
		||||
  <filter inkscape:collect="always" color-interpolation-filters="sRGB" id="filter7554">
 | 
			
		||||
   <feBlend inkscape:collect="always" id="feBlend7556" in2="BackgroundImage" mode="darken"/>
 | 
			
		||||
  </filter>
 | 
			
		||||
 </defs>
 | 
			
		||||
 <g inkscape:groupmode="layer" id="layer12" inkscape:label="actions" transform="translate(-445.0002,-129)">
 | 
			
		||||
  <path inkscape:connector-curvature="0" d="m 451.0002,142 5,-5 -5,-5 z" id="path6412" sodipodi:nodetypes="cccc" fill="#555555"/>
 | 
			
		||||
 </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 896 B  | 
							
								
								
									
										15
									
								
								branding/kaos_branding/pan-start-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								branding/kaos_branding/pan-start-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
 | 
			
		||||
<svg height="16" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" version="1.1" width="16" xmlns="http://www.w3.org/2000/svg" enable-background="new">
 | 
			
		||||
 <metadata id="metadata90"/>
 | 
			
		||||
 <defs id="defs7386">
 | 
			
		||||
  <linearGradient id="linearGradient5606" osb:paint="solid">
 | 
			
		||||
   <stop id="stop5608"/>
 | 
			
		||||
  </linearGradient>
 | 
			
		||||
  <filter inkscape:collect="always" color-interpolation-filters="sRGB" id="filter7554">
 | 
			
		||||
   <feBlend inkscape:collect="always" id="feBlend7556" in2="BackgroundImage" mode="darken"/>
 | 
			
		||||
  </filter>
 | 
			
		||||
 </defs>
 | 
			
		||||
 <g inkscape:groupmode="layer" id="layer12" inkscape:label="actions" transform="translate(-425.0002,-129)">
 | 
			
		||||
  <path inkscape:connector-curvature="0" d="m 435.0002,142 -5,-5 5,-5 z" id="path6400-8" sodipodi:nodetypes="cccc" fill="#555555"/>
 | 
			
		||||
 </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 898 B  | 
							
								
								
									
										15
									
								
								branding/kaos_branding/pan-up-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								branding/kaos_branding/pan-up-symbolic.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
 | 
			
		||||
<svg height="16" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" version="1.1" width="16" xmlns="http://www.w3.org/2000/svg" enable-background="new">
 | 
			
		||||
 <metadata id="metadata90"/>
 | 
			
		||||
 <defs id="defs7386">
 | 
			
		||||
  <linearGradient id="linearGradient5606" osb:paint="solid">
 | 
			
		||||
   <stop id="stop5608"/>
 | 
			
		||||
  </linearGradient>
 | 
			
		||||
  <filter inkscape:collect="always" color-interpolation-filters="sRGB" id="filter7554">
 | 
			
		||||
   <feBlend inkscape:collect="always" id="feBlend7556" in2="BackgroundImage" mode="darken"/>
 | 
			
		||||
  </filter>
 | 
			
		||||
 </defs>
 | 
			
		||||
 <g inkscape:groupmode="layer" id="layer12" inkscape:label="actions" transform="translate(-465.0002,-129.00001)">
 | 
			
		||||
  <path inkscape:connector-curvature="0" d="m 478.0002,139 -5,-5 -5,5 z" id="path6418" sodipodi:nodetypes="cccc" fill="#3498DB"/>
 | 
			
		||||
 </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 902 B  | 
@@ -1,6 +1,7 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   Copyright 2015, Teo Mrnjavac <teo@kde.org>
 | 
			
		||||
 *   Copyright 2015-2018, Anke Boersma <demm@kaosx.us>
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is free software: you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -24,13 +25,12 @@ Presentation
 | 
			
		||||
    id: presentation
 | 
			
		||||
 | 
			
		||||
    Timer {
 | 
			
		||||
        id: advanceTimer
 | 
			
		||||
        interval: 5000
 | 
			
		||||
        running: false
 | 
			
		||||
        repeat: true
 | 
			
		||||
        onTriggered: presentation.goToNextSlide()
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    Slide {
 | 
			
		||||
        anchors.fill: parent
 | 
			
		||||
 | 
			
		||||
@@ -38,7 +38,7 @@ Presentation
 | 
			
		||||
            id: background
 | 
			
		||||
            source: "1.svg"
 | 
			
		||||
            anchors.fill: parent
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
            Text {
 | 
			
		||||
                anchors.centerIn: parent
 | 
			
		||||
                anchors.verticalCenterOffset: 0
 | 
			
		||||
@@ -96,15 +96,15 @@ Presentation
 | 
			
		||||
                anchors.horizontalCenterOffset: -100
 | 
			
		||||
                font.pixelSize: parent.width *.015
 | 
			
		||||
                color: 'white'
 | 
			
		||||
                text: qsTr("The default Office Suite is Calligra.<br/>"+
 | 
			
		||||
                    "LibreOffice is available in the repositories. <br/>")
 | 
			
		||||
                text: qsTr("The default Office Suite is LibreOffice.<br/>"+
 | 
			
		||||
                    "Calligra is available in the repositories. <br/>")
 | 
			
		||||
                wrapMode: Text.WordWrap
 | 
			
		||||
                width: 450
 | 
			
		||||
                horizontalAlignment: Text.AlignLeft
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    Slide {
 | 
			
		||||
        anchors.fill: parent
 | 
			
		||||
 | 
			
		||||
@@ -120,7 +120,7 @@ Presentation
 | 
			
		||||
                font.pixelSize: parent.width *.015
 | 
			
		||||
                color: 'white'
 | 
			
		||||
                text: qsTr("Qt/KDE specific internet applications include the <br/>"+
 | 
			
		||||
                    "Qupzilla web-browser and kde-telepathy for <br/>"+
 | 
			
		||||
                    "Falkon web-browser and kde-telepathy for <br/>"+
 | 
			
		||||
                    "chat and Instant Messaging. <br/>")
 | 
			
		||||
                wrapMode: Text.WordWrap
 | 
			
		||||
                width: 450
 | 
			
		||||
@@ -128,7 +128,7 @@ Presentation
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    Slide {
 | 
			
		||||
        anchors.fill: parent
 | 
			
		||||
 | 
			
		||||
@@ -150,7 +150,7 @@ Presentation
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    Slide {
 | 
			
		||||
        anchors.fill: parent
 | 
			
		||||
 | 
			
		||||
@@ -172,6 +172,4 @@ Presentation
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Component.onCompleted: advanceTimer.running = true
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -140,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"
 | 
			
		||||
#
 | 
			
		||||
KEY_ID="328D742D8807A435"
 | 
			
		||||
git tag -u "$KEY_ID" -m "Release v$V" "v$V" || { echo "Could not sign tag v$V." ; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
### Create the tarball
 | 
			
		||||
#
 | 
			
		||||
# Create the tarball, compute SHA256 for later reporting, and
 | 
			
		||||
# sign the tarball so the signature can be uploaded separately.
 | 
			
		||||
#
 | 
			
		||||
TAR_V="$TARBALL_PREFIX-$V"
 | 
			
		||||
TAR_FILE="$TAR_V.tar.gz"
 | 
			
		||||
git archive -o "$TAR_FILE" --prefix "$TAR_V/" "v$V" || { echo "Could not create tarball." ; exit 1 ; }
 | 
			
		||||
test -f "$TAR_FILE" || { echo "Tarball was not created." ; exit 1 ; }
 | 
			
		||||
SHA256=$(sha256sum "$TAR_FILE" | cut -d" " -f1)
 | 
			
		||||
gpg -s -u $KEY_ID --detach --armor $TAR_FILE  # Sign the tarball
 | 
			
		||||
 | 
			
		||||
### Build the tarball
 | 
			
		||||
#
 | 
			
		||||
@@ -183,7 +187,6 @@ rm -rf "$TMPDIR"  # From tarball
 | 
			
		||||
cat <<EOF
 | 
			
		||||
# Next steps for this release:
 | 
			
		||||
  git push origin v$V
 | 
			
		||||
  gpg -s -u $KEY_ID --detach --armor $TAR_FILE  # Sign the tarball
 | 
			
		||||
  # Upload tarball $TAR_FILE and the signature $TAR_FILE.asc
 | 
			
		||||
  # Announce via https://github.com/calamares/$PROJECT_NAME/releases/new
 | 
			
		||||
  # SHA256: $SHA256
 | 
			
		||||
 
 | 
			
		||||
@@ -5,12 +5,7 @@
 | 
			
		||||
#   SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
#
 | 
			
		||||
# Calls astyle with settings matching Calamares coding style
 | 
			
		||||
# Requires astyle >= 2.04 and clang-format-7 -8 or -9
 | 
			
		||||
#
 | 
			
		||||
# Clang-format-10 is **not** supported, since it changes a default
 | 
			
		||||
# that re-introduces a space into empty function bodies; this
 | 
			
		||||
# can be turned off with a style setting, but that breaks
 | 
			
		||||
# older format versions which don't recognize the setting.
 | 
			
		||||
# Requires astyle >= 2.04 and clang-format-8 or later
 | 
			
		||||
#
 | 
			
		||||
# You can pass in directory names, in which case the files
 | 
			
		||||
# in that directory (NOT below it) are processed.
 | 
			
		||||
@@ -20,9 +15,16 @@ LC_ALL=C
 | 
			
		||||
LC_NUMERIC=C
 | 
			
		||||
export LANG LC_ALL LC_NUMERIC
 | 
			
		||||
 | 
			
		||||
BASEDIR=$(dirname $0)
 | 
			
		||||
TOPDIR=$( cd $BASEDIR/.. && pwd -P )
 | 
			
		||||
test -d "$BASEDIR" || { echo "! Could not determine base for $0" ; exit 1 ; }
 | 
			
		||||
test -d "$TOPDIR" || { echo "! Cound not determine top-level source dir" ; exit 1 ; }
 | 
			
		||||
test -f "$TOPDIR/.clang-format.base" || { echo "! No .clang-format support files in $TOPDIR" ; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
AS=$( which astyle )
 | 
			
		||||
 | 
			
		||||
CF_VERSIONS="clang-format-7 clang-format-8 clang-format70 clang-format80 clang-format90 clang-format-9.0.1 clang-format"
 | 
			
		||||
# Allow specifying CF_VERSIONS outside already
 | 
			
		||||
CF_VERSIONS="$CF_VERSIONS clang-format-8 clang-format80 clang-format90 clang-format-9.0.1 clang-format"
 | 
			
		||||
for _cf in $CF_VERSIONS
 | 
			
		||||
do
 | 
			
		||||
	# Not an error if this particular clang-format isn't found
 | 
			
		||||
@@ -35,14 +37,39 @@ test -n "$CF" || { echo "! No clang-format ($CF_VERSIONS) found in PATH"; exit 1
 | 
			
		||||
test -x "$AS" || { echo "! $AS is not executable."; exit 1 ; }
 | 
			
		||||
test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; }
 | 
			
		||||
 | 
			
		||||
unmangle_clang_format=""
 | 
			
		||||
if expr `"$CF" --version | tr -dc '[^.0-9]' | cut  -d . -f 1` '<' 10 > /dev/null ; then
 | 
			
		||||
	:
 | 
			
		||||
else
 | 
			
		||||
	unmangle_clang_format=$( dirname $0 )/../.clang-format
 | 
			
		||||
	echo "SpaceInEmptyBlock: false" >> "$unmangle_clang_format"
 | 
			
		||||
fi
 | 
			
		||||
### CLANG-FORMAT-WRANGLING
 | 
			
		||||
#
 | 
			
		||||
# Version 7 and earlier doesn't understand all the options we would like
 | 
			
		||||
# Version 8 is ok
 | 
			
		||||
# Version 9 is ok
 | 
			
		||||
# Later versions change some defaults so need extra wrangling.
 | 
			
		||||
# .. there are extra files that are appended to the settings, per
 | 
			
		||||
# .. clang-format version.
 | 
			
		||||
 | 
			
		||||
format_version=`"$CF" --version | tr -dc '[^.0-9]' | cut  -d . -f 1`
 | 
			
		||||
case "$format_version" in
 | 
			
		||||
	[0-7] )
 | 
			
		||||
		echo "! Clang-format version 8+ required"
 | 
			
		||||
		exit 1
 | 
			
		||||
		;;
 | 
			
		||||
	[89] )
 | 
			
		||||
		:
 | 
			
		||||
		;;
 | 
			
		||||
	* )
 | 
			
		||||
		echo "! Clang-format version '$format_version' unsupported."
 | 
			
		||||
		exit 1
 | 
			
		||||
		;;
 | 
			
		||||
esac
 | 
			
		||||
_fmt="$TOPDIR/.clang-format"
 | 
			
		||||
cp "$_fmt.base" "$_fmt"
 | 
			
		||||
for f in "$extra_settings" ; do
 | 
			
		||||
	test -f "$_fmt.$f" && cat "$_fmt.$f" >> "$_fmt"
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### FILE PROCESSING
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
any_dirs=no
 | 
			
		||||
@@ -54,7 +81,7 @@ done
 | 
			
		||||
style_some()
 | 
			
		||||
{
 | 
			
		||||
	if test -n "$*" ; then
 | 
			
		||||
		$AS --options=$(dirname $0)/astylerc --quiet "$@"
 | 
			
		||||
		$AS --options=$BASEDIR/astylerc --quiet "$@"
 | 
			
		||||
		$CF -i -style=file "$@"
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
@@ -72,6 +99,7 @@ else
 | 
			
		||||
	style_some "$@"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test -n "$unmangle_clang_format" ; then
 | 
			
		||||
	sed -i.bak '/^SpaceInEmptyBlock/d' "$unmangle_clang_format"
 | 
			
		||||
fi
 | 
			
		||||
### CLANG-FORMAT-WRANGLING
 | 
			
		||||
#
 | 
			
		||||
# Restore the original .clang-format
 | 
			
		||||
cp "$_fmt.base" "$_fmt"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
# The FileKeeper plugin preserves files from the live system
 | 
			
		||||
# to the target system. It is particularly suited for copying
 | 
			
		||||
# the log file(s) for post-installation or post-mortem examination.
 | 
			
		||||
 | 
			
		||||
calamares_add_plugin( filekeeper
 | 
			
		||||
    TYPE job
 | 
			
		||||
    EXPORT_MACRO PLUGINDLLEXPORT_PRO
 | 
			
		||||
    SOURCES
 | 
			
		||||
        FileKeeper.cpp
 | 
			
		||||
    SHARED_LIB
 | 
			
		||||
)
 | 
			
		||||
@@ -1,58 +0,0 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   Copyright 2018, Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is free software: you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "FileKeeper.h"
 | 
			
		||||
 | 
			
		||||
#include <QDateTime>
 | 
			
		||||
#include <QProcess>
 | 
			
		||||
#include <QThread>
 | 
			
		||||
 | 
			
		||||
#include <GlobalStorage.h>
 | 
			
		||||
#include <JobQueue.h>
 | 
			
		||||
 | 
			
		||||
#include <utils/Logger.h>
 | 
			
		||||
 | 
			
		||||
FileKeeperJob::FileKeeperJob( QObject* parent )
 | 
			
		||||
    : Calamares::CppJob( parent )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FileKeeperJob::~FileKeeperJob() {}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
QString
 | 
			
		||||
FileKeeperJob::prettyName() const
 | 
			
		||||
{
 | 
			
		||||
    return tr( "File keeper Job" );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Calamares::JobResult
 | 
			
		||||
FileKeeperJob::exec()
 | 
			
		||||
{
 | 
			
		||||
    return Calamares::JobResult::ok();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
FileKeeperJob::setConfigurationMap( const QVariantMap& configurationMap )
 | 
			
		||||
{
 | 
			
		||||
    Q_UNUSED( configurationMap );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( FileKeeperJobFactory, registerPlugin< FileKeeperJob >(); )
 | 
			
		||||
@@ -1,46 +0,0 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   Copyright 2018, Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is free software: you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef FILEKEEPER_H
 | 
			
		||||
#define FILEKEEPER_H
 | 
			
		||||
 | 
			
		||||
#include <CppJob.h>
 | 
			
		||||
#include <DllMacro.h>
 | 
			
		||||
#include <utils/PluginFactory.h>
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QVariantMap>
 | 
			
		||||
 | 
			
		||||
class PLUGINDLLEXPORT FileKeeperJob : public Calamares::CppJob
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit FileKeeperJob( QObject* parent = nullptr );
 | 
			
		||||
    virtual ~FileKeeperJob() override;
 | 
			
		||||
 | 
			
		||||
    QString prettyName() const override;
 | 
			
		||||
 | 
			
		||||
    Calamares::JobResult exec() override;
 | 
			
		||||
 | 
			
		||||
    void setConfigurationMap( const QVariantMap& configurationMap ) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( FileKeeperJobFactory )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,3 +1,6 @@
 | 
			
		||||
#   SPDX-FileCopyrightText: no
 | 
			
		||||
#   SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
if( NOT Calamares_WITH_QML )
 | 
			
		||||
    calamares_skip_module( "freebsddisk (QML is not supported in this build)" )
 | 
			
		||||
    return()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,6 @@
 | 
			
		||||
# SPDX-FileCopyrightText: no
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
# The *freebsddisk* module can be used to pick a disk
 | 
			
		||||
# as an installer step. This module supports ZFSroot
 | 
			
		||||
# on one whole disk, and UFSroot on one whole disk.
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
#include "UsersJob.h"
 | 
			
		||||
 | 
			
		||||
#include "ViewManager.h"
 | 
			
		||||
#include "utils/Logger.h"
 | 
			
		||||
#include "utils/Variant.h"
 | 
			
		||||
 | 
			
		||||
#include <QVariant>
 | 
			
		||||
@@ -19,11 +20,23 @@ Config::setConfigurationMap( const QVariantMap& cfgMap )
 | 
			
		||||
{
 | 
			
		||||
    using namespace CalamaresUtils;
 | 
			
		||||
 | 
			
		||||
    if ( getBool( cfgMap, "bogus", false ) )
 | 
			
		||||
    {
 | 
			
		||||
        cWarning() << "Configuration key \"bogus\" is still set for *mobile*";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_osName = getString( cfgMap, "osName", "(unknown)" );
 | 
			
		||||
    m_arch = getString( cfgMap, "arch", "(unknown)" );
 | 
			
		||||
    m_device = getString( cfgMap, "device", "(unknown)" );
 | 
			
		||||
    m_userInterface = getString( cfgMap, "userInterface", "(unknown)" );
 | 
			
		||||
    m_version = getString( cfgMap, "version", "(unknown)" );
 | 
			
		||||
 | 
			
		||||
    m_reservedUsernames = getStringList( cfgMap, "reservedUsernames", QStringList { "adm", "at ", "bin", "colord",
 | 
			
		||||
            "cron", "cyrus", "daemon", "ftp", "games", "geoclue", "guest", "halt", "lightdm", "lp", "mail", "man",
 | 
			
		||||
            "messagebus", "news", "nobody", "ntp", "operator", "polkitd", "postmaster", "pulse", "root", "shutdown",
 | 
			
		||||
            "smmsp", "squid", "sshd", "sync", "uucp", "vpopmail", "xfs" } );
 | 
			
		||||
 | 
			
		||||
    // ensure m_cmdUsermod matches m_username
 | 
			
		||||
    m_username = getString( cfgMap, "username", "user" );
 | 
			
		||||
    m_userPasswordNumeric = getBool( cfgMap, "userPasswordNumeric", true );
 | 
			
		||||
 | 
			
		||||
@@ -48,6 +61,8 @@ Config::setConfigurationMap( const QVariantMap& cfgMap )
 | 
			
		||||
 | 
			
		||||
    m_cmdInternalStoragePrepare = getString( cfgMap, "cmdInternalStoragePrepare", "ondev-internal-storage-prepare" );
 | 
			
		||||
    m_cmdPasswd = getString( cfgMap, "cmdPasswd", "passwd" );
 | 
			
		||||
    m_cmdUsermod = getString( cfgMap, "cmdUsermod", "xargs -I{} -n1 usermod -m -d /home/{} -l {} -c {} user");
 | 
			
		||||
 | 
			
		||||
    m_cmdSshdEnable = getString( cfgMap, "cmdSshdEnable", "systemctl enable sshd.service" );
 | 
			
		||||
    m_cmdSshdDisable = getString( cfgMap, "cmdSshdDisable", "systemctl disable sshd.service" );
 | 
			
		||||
    m_cmdSshdUseradd = getString( cfgMap, "cmdSshdUseradd", "useradd -G wheel -m" );
 | 
			
		||||
@@ -62,6 +77,7 @@ Config::createJobs()
 | 
			
		||||
    /* Put users job in queue (should run after unpackfs) */
 | 
			
		||||
    Calamares::Job* j = new UsersJob( m_featureSshd,
 | 
			
		||||
                                      m_cmdPasswd,
 | 
			
		||||
                                      m_cmdUsermod,
 | 
			
		||||
                                      cmdSshd,
 | 
			
		||||
                                      m_cmdSshdUseradd,
 | 
			
		||||
                                      m_isSshEnabled,
 | 
			
		||||
@@ -126,6 +142,13 @@ Config::runPartitionJobThenLeave( bool b )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Config::setUsername( const QString& username )
 | 
			
		||||
{
 | 
			
		||||
    m_username = username;
 | 
			
		||||
    emit usernameChanged( m_username );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Config::setUserPassword( const QString& userPassword )
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,11 @@ class Config : public QObject
 | 
			
		||||
    Q_PROPERTY( QString userInterface READ userInterface CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString version READ version CONSTANT FINAL )
 | 
			
		||||
 | 
			
		||||
    /* reserved usernames (user_pass, ssh_credentials )*/
 | 
			
		||||
    Q_PROPERTY( QStringList reservedUsernames READ reservedUsernames CONSTANT FINAL )
 | 
			
		||||
 | 
			
		||||
    /* default user */
 | 
			
		||||
    Q_PROPERTY( QString username READ username CONSTANT FINAL )
 | 
			
		||||
    Q_PROPERTY( QString username READ username WRITE setUsername NOTIFY usernameChanged )
 | 
			
		||||
    Q_PROPERTY( QString userPassword READ userPassword WRITE setUserPassword NOTIFY userPasswordChanged )
 | 
			
		||||
    Q_PROPERTY( bool userPasswordNumeric READ userPasswordNumeric CONSTANT FINAL )
 | 
			
		||||
 | 
			
		||||
@@ -72,13 +75,17 @@ public:
 | 
			
		||||
    QString userInterface() const { return m_userInterface; }
 | 
			
		||||
    QString version() const { return m_version; }
 | 
			
		||||
 | 
			
		||||
    /* default user */
 | 
			
		||||
    /* reserved usernames (user_pass, ssh_credentials) */
 | 
			
		||||
    QStringList reservedUsernames() const { return m_reservedUsernames; };
 | 
			
		||||
 | 
			
		||||
    /* user */
 | 
			
		||||
    QString username() const { return m_username; }
 | 
			
		||||
    QString userPassword() const { return m_userPassword; }
 | 
			
		||||
    void setUsername( const QString& username );
 | 
			
		||||
    void setUserPassword( const QString& userPassword );
 | 
			
		||||
    bool userPasswordNumeric() const { return m_userPasswordNumeric; }
 | 
			
		||||
 | 
			
		||||
    /* ssh server + credetials */
 | 
			
		||||
    /* ssh server + credentials */
 | 
			
		||||
    bool featureSshd() { return m_featureSshd; }
 | 
			
		||||
    QString sshdUsername() const { return m_sshdUsername; }
 | 
			
		||||
    QString sshdPassword() const { return m_sshdPassword; }
 | 
			
		||||
@@ -120,6 +127,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    /* users job */
 | 
			
		||||
    QString cmdPasswd() const { return m_cmdPasswd; }
 | 
			
		||||
    QString cmdUsermod() const { return m_cmdUsermod; }
 | 
			
		||||
    QString cmdSshdEnable() const { return m_cmdSshdEnable; }
 | 
			
		||||
    QString cmdSshdDisable() const { return m_cmdSshdDisable; }
 | 
			
		||||
    QString cmdSshdUseradd() const { return m_cmdSshdUseradd; }
 | 
			
		||||
@@ -135,6 +143,9 @@ private:
 | 
			
		||||
    QString m_userInterface;
 | 
			
		||||
    QString m_version;
 | 
			
		||||
 | 
			
		||||
    /* reserved usernames (user_pass, ssh_credentials) */
 | 
			
		||||
    QStringList m_reservedUsernames;
 | 
			
		||||
 | 
			
		||||
    /* default user */
 | 
			
		||||
    QString m_username;
 | 
			
		||||
    QString m_userPassword;
 | 
			
		||||
@@ -172,6 +183,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    /* users job */
 | 
			
		||||
    QString m_cmdPasswd;
 | 
			
		||||
    QString m_cmdUsermod;
 | 
			
		||||
    QString m_cmdSshdEnable;
 | 
			
		||||
    QString m_cmdSshdDisable;
 | 
			
		||||
    QString m_cmdSshdUseradd;
 | 
			
		||||
@@ -181,6 +193,7 @@ signals:
 | 
			
		||||
 | 
			
		||||
    /* default user */
 | 
			
		||||
    void userPasswordChanged( QString userPassword );
 | 
			
		||||
    void usernameChanged( QString username );
 | 
			
		||||
 | 
			
		||||
    /* ssh server + credentials */
 | 
			
		||||
    void sshdUsernameChanged( QString sshdUsername );
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,14 @@
 | 
			
		||||
 * SPDX-License-Identifier: GPL-3.0-or-later */
 | 
			
		||||
#include "MobileQmlViewStep.h"
 | 
			
		||||
 | 
			
		||||
#include "Branding.h"
 | 
			
		||||
#include "GlobalStorage.h"
 | 
			
		||||
 | 
			
		||||
#include "locale/LabelModel.h"
 | 
			
		||||
#include "locale/TranslationsModel.h"
 | 
			
		||||
#include "modulesystem/ModuleManager.h"
 | 
			
		||||
#include "utils/Dirs.h"
 | 
			
		||||
#include "utils/Logger.h"
 | 
			
		||||
#include "utils/Variant.h"
 | 
			
		||||
 | 
			
		||||
#include "Branding.h"
 | 
			
		||||
#include "modulesystem/ModuleManager.h"
 | 
			
		||||
 | 
			
		||||
#include <QProcess>
 | 
			
		||||
 | 
			
		||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( MobileQmlViewStepFactory, registerPlugin< MobileQmlViewStep >(); )
 | 
			
		||||
 
 | 
			
		||||
@@ -118,7 +118,7 @@ PartitionJob::exec()
 | 
			
		||||
        const QString pathRoot = "/";
 | 
			
		||||
 | 
			
		||||
        ProcessResult res
 | 
			
		||||
            = System::runCommand( System::RunLocation::RunInHost, args, pathRoot, stdInput, chrono::seconds( 120 ) );
 | 
			
		||||
            = System::runCommand( System::RunLocation::RunInHost, args, pathRoot, stdInput, chrono::seconds( 600 ) );
 | 
			
		||||
        if ( res.getExitCode() )
 | 
			
		||||
        {
 | 
			
		||||
            return JobResult::error( "Command failed:<br><br>"
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@
 | 
			
		||||
 | 
			
		||||
UsersJob::UsersJob( bool featureSshd,
 | 
			
		||||
                    const QString& cmdPasswd,
 | 
			
		||||
                    const QString& cmdUsermod,
 | 
			
		||||
                    const QString& cmdSshd,
 | 
			
		||||
                    const QString& cmdSshdUseradd,
 | 
			
		||||
                    bool isSshEnabled,
 | 
			
		||||
@@ -24,6 +25,7 @@ UsersJob::UsersJob( bool featureSshd,
 | 
			
		||||
    : Calamares::Job()
 | 
			
		||||
    , m_featureSshd( featureSshd )
 | 
			
		||||
    , m_cmdPasswd( cmdPasswd )
 | 
			
		||||
    , m_cmdUsermod( cmdUsermod )
 | 
			
		||||
    , m_cmdSshd( cmdSshd )
 | 
			
		||||
    , m_cmdSshdUseradd( cmdSshdUseradd )
 | 
			
		||||
    , m_isSshEnabled( isSshEnabled )
 | 
			
		||||
@@ -49,9 +51,11 @@ UsersJob::exec()
 | 
			
		||||
    using namespace std;
 | 
			
		||||
 | 
			
		||||
    QList< QPair< QStringList, QString > > commands = {
 | 
			
		||||
        { { "sh", "-c", m_cmdPasswd + " " + m_username }, m_password + "\n" + m_password + "\n" },
 | 
			
		||||
        { { "sh", "-c", m_cmdUsermod }, m_username + "\n" }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    commands.append( { { "sh", "-c", m_cmdPasswd + " " + m_username }, m_password + "\n" + m_password + "\n" } );
 | 
			
		||||
 | 
			
		||||
    if ( m_featureSshd )
 | 
			
		||||
    {
 | 
			
		||||
        commands.append( { { "sh", "-c", m_cmdSshd }, QString() } );
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ class UsersJob : public Calamares::Job
 | 
			
		||||
public:
 | 
			
		||||
    UsersJob( bool featureSshd,
 | 
			
		||||
              const QString& cmdPasswd,
 | 
			
		||||
              const QString& cmdUsermod,
 | 
			
		||||
              const QString& cmdSshd,
 | 
			
		||||
              const QString& cmdSshdUseradd,
 | 
			
		||||
              bool isSshEnabled,
 | 
			
		||||
@@ -26,6 +27,7 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
    bool m_featureSshd;
 | 
			
		||||
    QString m_cmdPasswd;
 | 
			
		||||
    QString m_cmdUsermod;
 | 
			
		||||
    QString m_cmdSshd;
 | 
			
		||||
    QString m_cmdSshdUseradd;
 | 
			
		||||
    bool m_isSshEnabled;
 | 
			
		||||
 
 | 
			
		||||
@@ -22,13 +22,13 @@ Item {
 | 
			
		||||
        id: mainText
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: parent.top
 | 
			
		||||
        anchors.topMargin: 30
 | 
			
		||||
        anchors.topMargin: 25
 | 
			
		||||
        wrapMode: Text.WordWrap
 | 
			
		||||
 | 
			
		||||
        text: (function() {
 | 
			
		||||
            var ret = "Once you hit 'install', the installation will begin." +
 | 
			
		||||
                " It will typically take a few minutes. Do not power off the" +
 | 
			
		||||
                " device until it is done.<br><br>";
 | 
			
		||||
                " device until it is done.<br>";
 | 
			
		||||
 | 
			
		||||
            if (config.installFromExternalToInternal) {
 | 
			
		||||
                ret += "<b>After the installation, your device will shutdown" +
 | 
			
		||||
@@ -44,14 +44,14 @@ Item {
 | 
			
		||||
            return ret;
 | 
			
		||||
        }())
 | 
			
		||||
 | 
			
		||||
        width: 500
 | 
			
		||||
        width: 550
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Button {
 | 
			
		||||
        id: firstButton
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: mainText.bottom
 | 
			
		||||
        anchors.topMargin: 40
 | 
			
		||||
        anchors.topMargin: 20
 | 
			
		||||
        width: 500
 | 
			
		||||
 | 
			
		||||
        text: qsTr("Install")
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
#######
 | 
			
		||||
@@ -19,8 +26,45 @@
 | 
			
		||||
# version: "(unknown)"
 | 
			
		||||
 | 
			
		||||
## Default username (for which the password will be set)
 | 
			
		||||
## Ensure also cmdUsermod command matches the default user, so it can be changed if desired.
 | 
			
		||||
# username: "user"
 | 
			
		||||
 | 
			
		||||
## reserved usernames (for user_pass username prompt and ssh_credentials)
 | 
			
		||||
# reservedUsernames:
 | 
			
		||||
#        - adm
 | 
			
		||||
#        - at
 | 
			
		||||
#        - bin
 | 
			
		||||
#        - colord
 | 
			
		||||
#        - cron
 | 
			
		||||
#        - cyrus
 | 
			
		||||
#        - daemon
 | 
			
		||||
#        - ftp
 | 
			
		||||
#        - games
 | 
			
		||||
#        - geoclue
 | 
			
		||||
#        - guest
 | 
			
		||||
#        - halt
 | 
			
		||||
#        - lightdm
 | 
			
		||||
#        - lp
 | 
			
		||||
#        - mail
 | 
			
		||||
#        - man
 | 
			
		||||
#        - messagebus
 | 
			
		||||
#        - news
 | 
			
		||||
#        - nobody
 | 
			
		||||
#        - ntp
 | 
			
		||||
#        - operator
 | 
			
		||||
#        - polkitd
 | 
			
		||||
#        - postmaster
 | 
			
		||||
#        - pulse
 | 
			
		||||
#        - root
 | 
			
		||||
#        - shutdown
 | 
			
		||||
#        - smmsp
 | 
			
		||||
#        - squid
 | 
			
		||||
#        - sshd
 | 
			
		||||
#        - sync
 | 
			
		||||
#        - uucp
 | 
			
		||||
#        - vpopmail
 | 
			
		||||
#        - xfs
 | 
			
		||||
 | 
			
		||||
#######
 | 
			
		||||
### Target device information
 | 
			
		||||
#######
 | 
			
		||||
@@ -111,6 +155,10 @@
 | 
			
		||||
### Commands running in the target OS (chroot)
 | 
			
		||||
#######
 | 
			
		||||
 | 
			
		||||
## Change the username for the default user
 | 
			
		||||
## Stdin: username with \n
 | 
			
		||||
# cmdUsermod: "xargs -I{} -n1 usermod -m -d /home/{} -l {} -c {} user"
 | 
			
		||||
 | 
			
		||||
## Set the password for default user and sshd user
 | 
			
		||||
## Arguments: <username>
 | 
			
		||||
## Stdin: password twice, each time with \n
 | 
			
		||||
 
 | 
			
		||||
@@ -253,7 +253,7 @@ Page
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Input validation: user-screens (user_pass, ssh_credentials) */
 | 
			
		||||
    /* Input validation: user-screens (fde_pass, user_pass, ssh_credentials) */
 | 
			
		||||
    function validatePin(userPin, userPinRepeat, errorText) {
 | 
			
		||||
        var pin = userPin.text;
 | 
			
		||||
        var repeat = userPinRepeat.text;
 | 
			
		||||
@@ -278,47 +278,12 @@ Page
 | 
			
		||||
 | 
			
		||||
        return validationFailureClear(errorText);
 | 
			
		||||
    }
 | 
			
		||||
    function validateSshdUsername(username, errorText) {
 | 
			
		||||
    function validateUsername(username, errorText, extraReservedUsernames = []) {
 | 
			
		||||
        var name = username.text;
 | 
			
		||||
        var reserved = [ /* FIXME: make configurable */
 | 
			
		||||
            config.username,
 | 
			
		||||
            "adm",
 | 
			
		||||
            "at ",
 | 
			
		||||
            "bin",
 | 
			
		||||
            "colord",
 | 
			
		||||
            "cron",
 | 
			
		||||
            "cyrus",
 | 
			
		||||
            "daemon",
 | 
			
		||||
            "ftp",
 | 
			
		||||
            "games",
 | 
			
		||||
            "geoclue",
 | 
			
		||||
            "guest",
 | 
			
		||||
            "halt",
 | 
			
		||||
            "lightdm",
 | 
			
		||||
            "lp",
 | 
			
		||||
            "mail",
 | 
			
		||||
            "man",
 | 
			
		||||
            "messagebus",
 | 
			
		||||
            "news",
 | 
			
		||||
            "nobody",
 | 
			
		||||
            "ntp",
 | 
			
		||||
            "operator",
 | 
			
		||||
            "polkitd",
 | 
			
		||||
            "postmaster",
 | 
			
		||||
            "pulse",
 | 
			
		||||
            "root",
 | 
			
		||||
            "shutdown",
 | 
			
		||||
            "smmsp",
 | 
			
		||||
            "squid",
 | 
			
		||||
            "sshd",
 | 
			
		||||
            "sync",
 | 
			
		||||
            "uucp",
 | 
			
		||||
            "vpopmail",
 | 
			
		||||
            "xfs",
 | 
			
		||||
        ]
 | 
			
		||||
        var reserved = config.reservedUsernames.concat(extraReservedUsernames);
 | 
			
		||||
 | 
			
		||||
        /* Validate characters */
 | 
			
		||||
        for (var i=0; i<name.length; i++) {
 | 
			
		||||
        for (var i = 0; i < name.length; i++) {
 | 
			
		||||
            if (i) {
 | 
			
		||||
                if (!name[i].match(/^[a-z0-9_-]$/))
 | 
			
		||||
                    return validationFailure(errorText,
 | 
			
		||||
@@ -335,16 +300,20 @@ Page
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Validate against reserved usernames */
 | 
			
		||||
        for (var i=0;i<reserved.length;i++) {
 | 
			
		||||
        for (var i = 0; i < reserved.length; i++) {
 | 
			
		||||
            if (name == reserved[i])
 | 
			
		||||
                return validationFailure(errorText, "Username '" +
 | 
			
		||||
                                                    reserved[i] +
 | 
			
		||||
                                                    "' is reserved.")
 | 
			
		||||
                                                    "' is reserved.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Passed */
 | 
			
		||||
        return validationFailureClear(errorText);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function validateSshdUsername(username, errorText) {
 | 
			
		||||
        return validateUsername(username, errorText, [config.username]);
 | 
			
		||||
    }
 | 
			
		||||
    function validateSshdPassword(password, passwordRepeat, errorText) {
 | 
			
		||||
        var pass = password.text;
 | 
			
		||||
        var repeat = passwordRepeat.text;
 | 
			
		||||
@@ -352,10 +321,10 @@ Page
 | 
			
		||||
        if (pass == "")
 | 
			
		||||
            return validationFailure(errorText);
 | 
			
		||||
 | 
			
		||||
        if (pass.length < 8)
 | 
			
		||||
        if (pass.length < 6)
 | 
			
		||||
            return validationFailure(errorText,
 | 
			
		||||
                                     "Too short: needs at least 8" +
 | 
			
		||||
                                     " characters.");
 | 
			
		||||
                                     "Too short: needs at least 6" +
 | 
			
		||||
                                     " digits/characters.");
 | 
			
		||||
 | 
			
		||||
        if (repeat == "")
 | 
			
		||||
            return validationFailure(errorText);
 | 
			
		||||
@@ -365,8 +334,6 @@ Page
 | 
			
		||||
 | 
			
		||||
        return validationFailureClear(errorText);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Input validation: fde_pass */
 | 
			
		||||
    function check_chars(input) {
 | 
			
		||||
        for (var i = 0; i < input.length; i++) {
 | 
			
		||||
            if (allowed_chars.indexOf(input[i]) == -1)
 | 
			
		||||
@@ -407,10 +374,10 @@ Page
 | 
			
		||||
                                     "\n" +
 | 
			
		||||
                                     allowed_chars_multiline());
 | 
			
		||||
 | 
			
		||||
        if (pass.length < 8)
 | 
			
		||||
        if (pass.length < 6)
 | 
			
		||||
            return validationFailure(errorText,
 | 
			
		||||
                                     "Too short: needs at least 8" +
 | 
			
		||||
                                     " characters.");
 | 
			
		||||
                                     "Too short: needs at least 6" +
 | 
			
		||||
                                     " digits/characters.");
 | 
			
		||||
 | 
			
		||||
        if (repeat == "")
 | 
			
		||||
            return validationFailure(errorText);
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
  <file>install_target.qml</file> <!-- install from external to internal? -->
 | 
			
		||||
  <file>install_target_confirm.qml</file> <!-- overwrite internal storage? -->
 | 
			
		||||
 | 
			
		||||
  <file>user_pass.qml</file> <!-- default user: password -->
 | 
			
		||||
  <file>user_pass.qml</file> <!-- default user: username, password -->
 | 
			
		||||
  <file>ssh_confirm.qml</file> <!-- sshd: enable or not? -->
 | 
			
		||||
  <file>ssh_credentials.qml</file> <!-- sshd user: username, password -->
 | 
			
		||||
  <file>fs_selection.qml</file> <!-- filesystem selection -->
 | 
			
		||||
 
 | 
			
		||||
@@ -12,16 +12,18 @@ import QtQuick.Window 2.3
 | 
			
		||||
import QtQuick.VirtualKeyboard 2.1
 | 
			
		||||
 | 
			
		||||
Item {
 | 
			
		||||
    property var placeholder: (config.userPasswordNumeric
 | 
			
		||||
    property var passPlaceholder: (config.userPasswordNumeric
 | 
			
		||||
                               ? "PIN"
 | 
			
		||||
                               : "Password")
 | 
			
		||||
    property var hints: (config.userPasswordNumeric
 | 
			
		||||
                         ? Qt.ImhDigitsOnly
 | 
			
		||||
                         : Qt.ImhPreferLowercase)
 | 
			
		||||
    property var validateFunc: (config.userPasswordNumeric
 | 
			
		||||
    property var validatePassFunc: (config.userPasswordNumeric
 | 
			
		||||
                                ? validatePin
 | 
			
		||||
                                : validatePassword);
 | 
			
		||||
 | 
			
		||||
    property var validateNameFunc: validateUsername;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    anchors.left: parent.left
 | 
			
		||||
    anchors.top: parent.top
 | 
			
		||||
@@ -30,12 +32,38 @@ Item {
 | 
			
		||||
    height: parent.height
 | 
			
		||||
 | 
			
		||||
    Text {
 | 
			
		||||
        id: description
 | 
			
		||||
        id: usernameDescription
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: parent.top
 | 
			
		||||
        anchors.topMargin: 30
 | 
			
		||||
        wrapMode: Text.WordWrap
 | 
			
		||||
 | 
			
		||||
        text: (function() {
 | 
			
		||||
            return "Set the username of your user. The default" +
 | 
			
		||||
                   " username is \"" + config.username + "\".";
 | 
			
		||||
        }())
 | 
			
		||||
 | 
			
		||||
        width: 500
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    TextField {
 | 
			
		||||
        id: username
 | 
			
		||||
        anchors.top: usernameDescription.bottom
 | 
			
		||||
        placeholderText: qsTr("Username")
 | 
			
		||||
        onTextChanged: validateNameFunc(username, errorText)
 | 
			
		||||
        text: config.username
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.topMargin: 50
 | 
			
		||||
        width: 500
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Text {
 | 
			
		||||
        id: userPassDescription
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
        anchors.top: username.bottom
 | 
			
		||||
        anchors.topMargin: 30
 | 
			
		||||
        wrapMode: Text.WordWrap
 | 
			
		||||
 | 
			
		||||
        text: (function() {
 | 
			
		||||
            if (config.userPasswordNumeric) {
 | 
			
		||||
                return "Set the numeric password of your user. The" +
 | 
			
		||||
@@ -53,10 +81,10 @@ Item {
 | 
			
		||||
 | 
			
		||||
    TextField {
 | 
			
		||||
        id: userPass
 | 
			
		||||
        anchors.top: description.bottom
 | 
			
		||||
        placeholderText: qsTr(placeholder)
 | 
			
		||||
        anchors.top: userPassDescription.bottom
 | 
			
		||||
        placeholderText: qsTr(passPlaceholder)
 | 
			
		||||
        echoMode: TextInput.Password
 | 
			
		||||
        onTextChanged: validateFunc(userPass, userPassRepeat, errorText)
 | 
			
		||||
        onTextChanged: validatePassFunc(userPass, userPassRepeat, errorText)
 | 
			
		||||
        text: config.userPassword
 | 
			
		||||
 | 
			
		||||
        /* Let the virtual keyboard change to digits only */
 | 
			
		||||
@@ -75,10 +103,10 @@ Item {
 | 
			
		||||
    TextField {
 | 
			
		||||
        id: userPassRepeat
 | 
			
		||||
        anchors.top: userPass.bottom
 | 
			
		||||
        placeholderText: qsTr(placeholder + " (repeat)")
 | 
			
		||||
        placeholderText: qsTr(passPlaceholder + " (repeat)")
 | 
			
		||||
        inputMethodHints: hints
 | 
			
		||||
        echoMode: TextInput.Password
 | 
			
		||||
        onTextChanged: validateFunc(userPass, userPassRepeat, errorText)
 | 
			
		||||
        onTextChanged: validatePassFunc(userPass, userPassRepeat, errorText)
 | 
			
		||||
        text: config.userPassword
 | 
			
		||||
 | 
			
		||||
        anchors.horizontalCenter: parent.horizontalCenter
 | 
			
		||||
@@ -105,8 +133,9 @@ Item {
 | 
			
		||||
 | 
			
		||||
        text: qsTr("Continue")
 | 
			
		||||
        onClicked: {
 | 
			
		||||
            if (validateFunc(userPass, userPassRepeat, errorText)) {
 | 
			
		||||
            if (validatePassFunc(userPass, userPassRepeat, errorText) && validateNameFunc(username, errorText)) {
 | 
			
		||||
                config.userPassword = userPass.text;
 | 
			
		||||
                config.username = username.text;
 | 
			
		||||
                navNext();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ Page
 | 
			
		||||
            anchors.topMargin: 150
 | 
			
		||||
            wrapMode: Text.WordWrap
 | 
			
		||||
            text: "Formatting and mounting target partition. This may" +
 | 
			
		||||
                  " take up to two minutes, please be patient."
 | 
			
		||||
                  " take up to ten minutes, please be patient."
 | 
			
		||||
            width: 500
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,6 @@
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
#   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
#   License-Filename: LICENSE
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
@@ -44,39 +43,233 @@ _ = gettext.translation("calamares-python",
 | 
			
		||||
                        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."""
 | 
			
		||||
    libcalamares.utils.debug("LocaleDir=" +
 | 
			
		||||
                             str(libcalamares.utils.gettext_path()))
 | 
			
		||||
    libcalamares.utils.debug("Languages=" +
 | 
			
		||||
                             str(libcalamares.utils.gettext_languages()))
 | 
			
		||||
 | 
			
		||||
    # TODO: probably want to use the job configuration
 | 
			
		||||
    #       with a key "stage" to distinguish generate-config
 | 
			
		||||
    #       from execute-config; maybe it wants an "all" as well
 | 
			
		||||
    #       to do both.
 | 
			
		||||
    accumulator = "*** Job configuration\n"
 | 
			
		||||
    accumulator += str(libcalamares.job.configuration)
 | 
			
		||||
    libcalamares.utils.debug(accumulator)
 | 
			
		||||
    gs = libcalamares.globalstorage
 | 
			
		||||
    text = configuration_nix_sample
 | 
			
		||||
 | 
			
		||||
    accumulator = "*** GlobalStorage configuration\n"
 | 
			
		||||
    accumulator += "count: " + str(libcalamares.globalstorage.count()) + "\n"
 | 
			
		||||
    accumulator += "keys: {}\n".format(str(libcalamares.globalstorage.keys()))
 | 
			
		||||
    libcalamares.utils.debug(accumulator)
 | 
			
		||||
    # 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"))
 | 
			
		||||
 | 
			
		||||
    libcalamares.utils.debug("Run NixOS tools.")
 | 
			
		||||
    # 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))
 | 
			
		||||
 | 
			
		||||
    libcalamares.job.setprogress( 0.1 )
 | 
			
		||||
    sleep(1)
 | 
			
		||||
    libcalamares.job.setprogress( 0.5 )
 | 
			
		||||
    sleep(1)
 | 
			
		||||
    libcalamares.job.setprogress( 1.0 )
 | 
			
		||||
    # 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))
 | 
			
		||||
 | 
			
		||||
    sleep(3)
 | 
			
		||||
    # 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)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,9 @@
 | 
			
		||||
# 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"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								modules/os-nixos/tests/1.global
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								modules/os-nixos/tests/1.global
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
# SPDX-FileCopyrightText: no
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
---
 | 
			
		||||
hostname: my-nix-host
 | 
			
		||||
locationRegion: Asia
 | 
			
		||||
locationZone: Kolkata
 | 
			
		||||
							
								
								
									
										130
									
								
								modules/refind/main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								modules/refind/main.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
#
 | 
			
		||||
# === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
#
 | 
			
		||||
#   SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
 | 
			
		||||
#   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
#
 | 
			
		||||
#   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import libcalamares
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import subprocess
 | 
			
		||||
 | 
			
		||||
from libcalamares.utils import check_target_env_call
 | 
			
		||||
 | 
			
		||||
import gettext
 | 
			
		||||
_ = gettext.translation("calamares-python",
 | 
			
		||||
                        localedir=libcalamares.utils.gettext_path(),
 | 
			
		||||
                        languages=libcalamares.utils.gettext_languages(),
 | 
			
		||||
                        fallback=True).gettext
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def pretty_name():
 | 
			
		||||
    return _("Install rEFInd.")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_uuid():
 | 
			
		||||
    partitions = libcalamares.globalstorage.value("partitions")
 | 
			
		||||
    for partition in partitions:
 | 
			
		||||
        if partition["mountPoint"] == "/":
 | 
			
		||||
            libcalamares.utils.debug(partition["uuid"])
 | 
			
		||||
            return partition["uuid"]
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def update_conf(uuid, conf_path):
 | 
			
		||||
    """
 | 
			
		||||
    Updates the created rEFInd configuration file based on given parameters.
 | 
			
		||||
    """
 | 
			
		||||
    partitions = libcalamares.globalstorage.value("partitions")
 | 
			
		||||
 | 
			
		||||
    kernel_params = ["quiet", "systemd.show_status=0"]
 | 
			
		||||
    swap = None  # Partition UUID
 | 
			
		||||
    swap_luks = None  # LUKS name
 | 
			
		||||
    cryptdevice_params = []
 | 
			
		||||
    btrfs_params = ""
 | 
			
		||||
 | 
			
		||||
    for partition in partitions:
 | 
			
		||||
        if partition["fs"] == "linuxswap" and not "luksMapperName" in partition:
 | 
			
		||||
            swap = partition["uuid"]
 | 
			
		||||
 | 
			
		||||
        if partition["fs"] == "linuxswap" and "luksMapperName" in partition:
 | 
			
		||||
            swap_luks = partition["luksMapperName"]
 | 
			
		||||
 | 
			
		||||
        if partition["mountPoint"] == "/" and "luksMapperName" in partition:
 | 
			
		||||
            cryptdevice_params = [
 | 
			
		||||
                "cryptdevice=UUID={!s}:{!s}".format(partition["luksUuid"],
 | 
			
		||||
                                                    partition["luksMapperName"]),
 | 
			
		||||
                "root=/dev/mapper/{!s}".format(partition["luksMapperName"]),
 | 
			
		||||
                "resume=/dev/mapper/{!s}".format(partition["luksMapperName"])
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
        # rEFInd with a BTRFS root filesystem needs to be told
 | 
			
		||||
        # about the root subvolume.
 | 
			
		||||
        if partition["mountPoint"] == "/" and partition["fs"] == "btrfs":
 | 
			
		||||
            btrfs_params = "rootflags=subvol=@"
 | 
			
		||||
 | 
			
		||||
    if cryptdevice_params:
 | 
			
		||||
        kernel_params.extend(cryptdevice_params)
 | 
			
		||||
    else:
 | 
			
		||||
        kernel_params.append("root=UUID={!s}".format(uuid))
 | 
			
		||||
 | 
			
		||||
    if swap:
 | 
			
		||||
        kernel_params.append("resume=UUID={!s}".format(swap))
 | 
			
		||||
    if swap_luks:
 | 
			
		||||
        kernel_params.append("resume=/dev/mapper/{!s}".format(swap_luks))
 | 
			
		||||
    if btrfs_params:
 | 
			
		||||
        kernel_params.append(btrfs_params)
 | 
			
		||||
 | 
			
		||||
    with open(conf_path, "r") as refind_file:
 | 
			
		||||
        filedata = [x.strip() for x in refind_file.readlines()]
 | 
			
		||||
 | 
			
		||||
    with open(conf_path, 'w') as refind_file:
 | 
			
		||||
        for line in filedata:
 | 
			
		||||
            if line.startswith('"Boot with standard options"'):
 | 
			
		||||
                line = '"Boot with standard options"    "rw {!s}"'.format(" ".join(kernel_params))
 | 
			
		||||
            refind_file.write(line + "\n")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def efi_partitions(efi_boot_path):
 | 
			
		||||
    """
 | 
			
		||||
    The (one) partition mounted on @p efi_boot_path, or an empty list.
 | 
			
		||||
    """
 | 
			
		||||
    return [p for p in libcalamares.globalstorage.value("partitions") if p["mountPoint"] == efi_boot_path]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def install_refind():
 | 
			
		||||
    install_path = libcalamares.globalstorage.value("rootMountPoint")
 | 
			
		||||
    uuid = get_uuid()
 | 
			
		||||
    conf_path = os.path.join(install_path, "boot/refind_linux.conf")
 | 
			
		||||
 | 
			
		||||
    # TODO: some distro's use /boot/efi , so maybe this needs to
 | 
			
		||||
    #       become configurable (that depends on what rEFInd likes).
 | 
			
		||||
    efi_boot_path = "/boot"
 | 
			
		||||
 | 
			
		||||
    # Might not have a /boot configured in the system at all; warn and don't operate
 | 
			
		||||
    if not efi_partitions(efi_boot_path):
 | 
			
		||||
        libcalamares.utils.warning("No partition mounted on {!s}".format(efi_boot_path))
 | 
			
		||||
        # This isn't returned as an error, but the installation
 | 
			
		||||
        # probably won't boot because no bootloader was installed.
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    subprocess.call(
 | 
			
		||||
        ["refind-install", "--root", "{!s}".format(install_path)])
 | 
			
		||||
    update_conf(uuid, conf_path)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def run():
 | 
			
		||||
    """
 | 
			
		||||
    Optional entry for when providing bootloader choices.
 | 
			
		||||
    Values taken from a packagechooser instance.
 | 
			
		||||
    Module won't run, if value not present.
 | 
			
		||||
    """
 | 
			
		||||
    bootchoice = libcalamares.globalstorage.value("packagechooser_bootchoice")
 | 
			
		||||
 | 
			
		||||
    if bootchoice == "refind":
 | 
			
		||||
        return install_refind()
 | 
			
		||||
							
								
								
									
										11
									
								
								modules/refind/module.desc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								modules/refind/module.desc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
# SPDX-FileCopyrightText: no
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
---
 | 
			
		||||
type:       "job"
 | 
			
		||||
name:       "refind"
 | 
			
		||||
interface:  "python"
 | 
			
		||||
script:     "main.py"
 | 
			
		||||
noconfig:   true
 | 
			
		||||
# The partition module sets up the needed paths in
 | 
			
		||||
# global storage, which is used to decide how to install.
 | 
			
		||||
requiredModules: [ "partition" ]
 | 
			
		||||
							
								
								
									
										12
									
								
								modules/refind/refind.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								modules/refind/refind.conf.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
# SPDX-FileCopyrightText: no
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
---
 | 
			
		||||
## This file should be present in the same directory as the EFISTUB kernel and initramfs files
 | 
			
		||||
## More info at http://www.rodsbooks.com/refind/linux.html , http://www.rodsbooks.com/efi-bootloaders/efistub.html
 | 
			
		||||
## File is not needed when rEFInd is installed with the `refind-install` option, it will be created automatically.
 | 
			
		||||
 | 
			
		||||
#"Boot with defaults"    "root=PARTUUID=XXXXXXXX rootfstype=XXXX rw add_efi_memmap"
 | 
			
		||||
#"Boot to terminal"      "root=PARTUUID=XXXXXXXX rootfstype=XXXX rw add_efi_memmap systemd.unit=multi-user.target"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,3 +1,6 @@
 | 
			
		||||
# SPDX-FileCopyrightText: no
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
# The slowpython module is .. just slow. It can be used
 | 
			
		||||
# in testing to allow the slideshow time to run.
 | 
			
		||||
---
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,6 @@
 | 
			
		||||
# SPDX-FileCopyrightText: no
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
# This is an example module for Python Job Modules.
 | 
			
		||||
#
 | 
			
		||||
# The slowpython module is just slow. It does produce
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								modules/unpackfsc/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								modules/unpackfsc/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
# SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
calamares_add_plugin( unpackfsc
 | 
			
		||||
    TYPE job
 | 
			
		||||
    EXPORT_MACRO PLUGINDLLEXPORT_PRO
 | 
			
		||||
    SOURCES
 | 
			
		||||
        UnpackFSCJob.cpp
 | 
			
		||||
        # The workers for differently-packed filesystems
 | 
			
		||||
        Runners.cpp
 | 
			
		||||
        FSArchiverRunner.cpp
 | 
			
		||||
        TarballRunner.cpp
 | 
			
		||||
        UnsquashRunner.cpp
 | 
			
		||||
    SHARED_LIB
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										117
									
								
								modules/unpackfsc/FSArchiverRunner.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								modules/unpackfsc/FSArchiverRunner.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "FSArchiverRunner.h"
 | 
			
		||||
 | 
			
		||||
#include <utils/Logger.h>
 | 
			
		||||
#include <utils/Runner.h>
 | 
			
		||||
 | 
			
		||||
#include <QProcess>
 | 
			
		||||
 | 
			
		||||
static constexpr const int chunk_size = 137;
 | 
			
		||||
static const QString&
 | 
			
		||||
toolName()
 | 
			
		||||
{
 | 
			
		||||
    static const QString name = QStringLiteral( "fsarchiver" );
 | 
			
		||||
    return name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
FSArchiverRunner::fsarchiverProgress( QString line )
 | 
			
		||||
{
 | 
			
		||||
    m_since++;
 | 
			
		||||
    // Typical line of output is this:
 | 
			
		||||
    // -[00][ 99%][REGFILEM] /boot/thing
 | 
			
		||||
    //      5   9           ^21
 | 
			
		||||
    if ( m_since >= chunk_size && line.length() > 21 && line[ 5 ] == '[' && line[ 9 ] == '%' )
 | 
			
		||||
    {
 | 
			
		||||
        m_since = 0;
 | 
			
		||||
        double p = double( line.mid( 6, 3 ).toInt() ) / 100.0;
 | 
			
		||||
        const QString filename = line.mid( 22 );
 | 
			
		||||
        Q_EMIT progress( p, filename );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Calamares::JobResult
 | 
			
		||||
FSArchiverRunner::checkPrerequisites( QString& fsarchiverExecutable ) const
 | 
			
		||||
{
 | 
			
		||||
    if ( !checkToolExists( toolName(), fsarchiverExecutable ) )
 | 
			
		||||
    {
 | 
			
		||||
        return Calamares::JobResult::internalError(
 | 
			
		||||
            tr( "Missing tools" ),
 | 
			
		||||
            tr( "The <i>%1</i> tool is not installed on the system." ).arg( toolName() ),
 | 
			
		||||
            Calamares::JobResult::MissingRequirements );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( !checkSourceExists() )
 | 
			
		||||
    {
 | 
			
		||||
        return Calamares::JobResult::internalError(
 | 
			
		||||
            tr( "Invalid fsarchiver configuration" ),
 | 
			
		||||
            tr( "The source archive <i>%1</i> does not exist." ).arg( m_source ),
 | 
			
		||||
            Calamares::JobResult::InvalidConfiguration );
 | 
			
		||||
    }
 | 
			
		||||
    return Calamares::JobResult::ok();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Calamares::JobResult
 | 
			
		||||
FSArchiverRunner::checkDestination( QString& destinationPath ) const
 | 
			
		||||
{
 | 
			
		||||
    destinationPath = 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 );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Calamares::JobResult::ok();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Calamares::JobResult
 | 
			
		||||
FSArchiverDirRunner::run()
 | 
			
		||||
{
 | 
			
		||||
    QString fsarchiverExecutable;
 | 
			
		||||
    if ( auto res = checkPrerequisites( fsarchiverExecutable ); !res )
 | 
			
		||||
    {
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
    QString destinationPath;
 | 
			
		||||
    if ( auto res = checkDestination( destinationPath ); !res )
 | 
			
		||||
    {
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Calamares::Utils::Runner r(
 | 
			
		||||
        { fsarchiverExecutable, QStringLiteral( "-v" ), QStringLiteral( "restdir" ), m_source, destinationPath } );
 | 
			
		||||
    r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
 | 
			
		||||
    connect( &r, &decltype( r )::output, this, &FSArchiverDirRunner::fsarchiverProgress );
 | 
			
		||||
    return r.run().explainProcess( toolName(), std::chrono::seconds( 0 ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Calamares::JobResult
 | 
			
		||||
FSArchiverFSRunner::run()
 | 
			
		||||
{
 | 
			
		||||
    QString fsarchiverExecutable;
 | 
			
		||||
    if ( auto res = checkPrerequisites( fsarchiverExecutable ); !res )
 | 
			
		||||
    {
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
    QString destinationPath;
 | 
			
		||||
    if ( auto res = checkDestination( destinationPath ); !res )
 | 
			
		||||
    {
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Calamares::Utils::Runner r(
 | 
			
		||||
        { fsarchiverExecutable, QStringLiteral( "-v" ), QStringLiteral( "restfs" ), m_source, destinationPath } );
 | 
			
		||||
    r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
 | 
			
		||||
    connect( &r, &decltype( r )::output, this, &FSArchiverFSRunner::fsarchiverProgress );
 | 
			
		||||
    return r.run().explainProcess( toolName(), std::chrono::seconds( 0 ) );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								modules/unpackfsc/FSArchiverRunner.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								modules/unpackfsc/FSArchiverRunner.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef UNPACKFSC_FSARCHIVERRUNNER_H
 | 
			
		||||
#define UNPACKFSC_FSARCHIVERRUNNER_H
 | 
			
		||||
 | 
			
		||||
#include "Runners.h"
 | 
			
		||||
 | 
			
		||||
/** @brief Base class for runners of FSArchiver
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class FSArchiverRunner : public Runner
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    using Runner::Runner;
 | 
			
		||||
 | 
			
		||||
protected Q_SLOTS:
 | 
			
		||||
    void fsarchiverProgress( QString line );
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    /** @brief Checks prerequisites, sets full path of fsarchiver in @p executable
 | 
			
		||||
     */
 | 
			
		||||
    Calamares::JobResult checkPrerequisites( QString& executable ) const;
 | 
			
		||||
    Calamares::JobResult checkDestination( QString& destinationPath ) const;
 | 
			
		||||
 | 
			
		||||
    int m_since = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @brief Running FSArchiver in **dir** mode
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class FSArchiverDirRunner : public FSArchiverRunner
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    using FSArchiverRunner::FSArchiverRunner;
 | 
			
		||||
 | 
			
		||||
    Calamares::JobResult run() override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** @brief Running FSArchiver in **dir** mode
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class FSArchiverFSRunner : public FSArchiverRunner
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    using FSArchiverRunner::FSArchiverRunner;
 | 
			
		||||
 | 
			
		||||
    Calamares::JobResult run() override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										38
									
								
								modules/unpackfsc/Runners.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								modules/unpackfsc/Runners.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "Runners.h"
 | 
			
		||||
 | 
			
		||||
#include <utils/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
 | 
			
		||||
							
								
								
									
										86
									
								
								modules/unpackfsc/TarballRunner.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								modules/unpackfsc/TarballRunner.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "TarballRunner.h"
 | 
			
		||||
 | 
			
		||||
#include <utils/Logger.h>
 | 
			
		||||
#include <utils/Runner.h>
 | 
			
		||||
#include <utils/String.h>
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
static constexpr const int chunk_size = 107;
 | 
			
		||||
 | 
			
		||||
Calamares::JobResult
 | 
			
		||||
TarballRunner::run()
 | 
			
		||||
{
 | 
			
		||||
    if ( !checkSourceExists() )
 | 
			
		||||
    {
 | 
			
		||||
        return Calamares::JobResult::internalError(
 | 
			
		||||
            tr( "Invalid tarball configuration" ),
 | 
			
		||||
            tr( "The source archive <i>%1</i> does not exist." ).arg( m_source ),
 | 
			
		||||
            Calamares::JobResult::InvalidConfiguration );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const QString toolName = QStringLiteral( "tar" );
 | 
			
		||||
    QString tarExecutable;
 | 
			
		||||
    if ( !checkToolExists( toolName, tarExecutable ) )
 | 
			
		||||
    {
 | 
			
		||||
        return Calamares::JobResult::internalError(
 | 
			
		||||
            tr( "Missing tools" ),
 | 
			
		||||
            tr( "The <i>%1</i> tool is not installed on the system." ).arg( toolName ),
 | 
			
		||||
            Calamares::JobResult::MissingRequirements );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const QString destinationPath = CalamaresUtils::System::instance()->targetPath( m_destination );
 | 
			
		||||
    if ( destinationPath.isEmpty() )
 | 
			
		||||
    {
 | 
			
		||||
        return Calamares::JobResult::internalError(
 | 
			
		||||
            tr( "Invalid tarball configuration" ),
 | 
			
		||||
            tr( "No destination could be found for <i>%1</i>." ).arg( m_destination ),
 | 
			
		||||
            Calamares::JobResult::InvalidConfiguration );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get the stats (number of inodes) from the FS
 | 
			
		||||
    {
 | 
			
		||||
        m_total = 0;
 | 
			
		||||
        Calamares::Utils::Runner r( { tarExecutable, QStringLiteral( "-tf" ), m_source } );
 | 
			
		||||
        r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
 | 
			
		||||
        QObject::connect( &r, &decltype( r )::output, [ & ]( QString line ) { m_total++; } );
 | 
			
		||||
        /* ignored */ r.run();
 | 
			
		||||
    }
 | 
			
		||||
    if ( m_total <= 0 )
 | 
			
		||||
    {
 | 
			
		||||
        cWarning() << "No stats could be obtained from" << tarExecutable << "-tf" << m_source;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Now do the actual unpack
 | 
			
		||||
    {
 | 
			
		||||
        m_processed = 0;
 | 
			
		||||
        m_since = 0;
 | 
			
		||||
        Calamares::Utils::Runner r(
 | 
			
		||||
            { tarExecutable, QStringLiteral( "-xpvf" ), m_source, QStringLiteral( "-C" ), destinationPath } );
 | 
			
		||||
        r.setLocation( Calamares::Utils::RunLocation::RunInHost ).enableOutputProcessing();
 | 
			
		||||
        connect( &r, &decltype( r )::output, this, &TarballRunner::tarballProgress );
 | 
			
		||||
        return r.run().explainProcess( toolName, std::chrono::seconds( 0 ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
TarballRunner::tarballProgress( QString line )
 | 
			
		||||
{
 | 
			
		||||
    m_processed++;
 | 
			
		||||
    m_since++;
 | 
			
		||||
    if ( m_since > chunk_size )
 | 
			
		||||
    {
 | 
			
		||||
        m_since = 0;
 | 
			
		||||
        double p = m_total > 0 ? ( double( m_processed ) / double( m_total ) ) : 0.5;
 | 
			
		||||
        Q_EMIT progress( p, tr( "Tarball extract file %1" ).arg( line ) );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								modules/unpackfsc/TarballRunner.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								modules/unpackfsc/TarballRunner.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef UNPACKFSC_TARBALLRUNNER_H
 | 
			
		||||
#define UNPACKFSC_TARBALLRUNNER_H
 | 
			
		||||
 | 
			
		||||
#include "Runners.h"
 | 
			
		||||
 | 
			
		||||
/** @brief Use (GNU) tar for extracting a filesystem
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class TarballRunner : public Runner
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    using Runner::Runner;
 | 
			
		||||
 | 
			
		||||
    Calamares::JobResult run() override;
 | 
			
		||||
 | 
			
		||||
protected Q_SLOTS:
 | 
			
		||||
    void tarballProgress( QString line );
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    // Progress reporting
 | 
			
		||||
    int m_total = 0;
 | 
			
		||||
    int m_processed = 0;
 | 
			
		||||
    int m_since = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										130
									
								
								modules/unpackfsc/UnpackFSCJob.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								modules/unpackfsc/UnpackFSCJob.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "UnpackFSCJob.h"
 | 
			
		||||
 | 
			
		||||
#include "FSArchiverRunner.h"
 | 
			
		||||
#include "TarballRunner.h"
 | 
			
		||||
#include "UnsquashRunner.h"
 | 
			
		||||
 | 
			
		||||
#include <utils/Logger.h>
 | 
			
		||||
#include <utils/NamedEnum.h>
 | 
			
		||||
#include <utils/RAII.h>
 | 
			
		||||
#include <utils/Variant.h>
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
static const NamedEnumTable< UnpackFSCJob::Type >
 | 
			
		||||
typeNames()
 | 
			
		||||
{
 | 
			
		||||
    using T = UnpackFSCJob::Type;
 | 
			
		||||
    // clang-format off
 | 
			
		||||
    static const NamedEnumTable< T > names
 | 
			
		||||
    {
 | 
			
		||||
        { "none", T::None },
 | 
			
		||||
        { "fsarchiver", T::FSArchive },
 | 
			
		||||
        { "fsarchive", T::FSArchive },
 | 
			
		||||
        { "fsa", T::FSArchive },
 | 
			
		||||
        { "fsa-dir", T::FSArchive },
 | 
			
		||||
        { "fsa-block", T::FSArchiveFS },
 | 
			
		||||
        { "fsa-fs", T::FSArchiveFS },
 | 
			
		||||
        { "squashfs", T::Squashfs },
 | 
			
		||||
        { "squash", T::Squashfs },
 | 
			
		||||
        { "unsquash", T::Squashfs },
 | 
			
		||||
        { "tar", T::Tarball },
 | 
			
		||||
        { "tarball", T::Tarball },
 | 
			
		||||
        { "tgz", T::Tarball },
 | 
			
		||||
    };
 | 
			
		||||
    // clang-format on
 | 
			
		||||
    return names;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UnpackFSCJob::UnpackFSCJob( QObject* parent )
 | 
			
		||||
    : Calamares::CppJob( parent )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UnpackFSCJob::~UnpackFSCJob() { }
 | 
			
		||||
 | 
			
		||||
QString
 | 
			
		||||
UnpackFSCJob::prettyName() const
 | 
			
		||||
{
 | 
			
		||||
    return tr( "Unpack filesystems" );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString
 | 
			
		||||
UnpackFSCJob::prettyStatusMessage() const
 | 
			
		||||
{
 | 
			
		||||
    return m_progressMessage;
 | 
			
		||||
}
 | 
			
		||||
Calamares::JobResult
 | 
			
		||||
UnpackFSCJob::exec()
 | 
			
		||||
{
 | 
			
		||||
    cScopedAssignment messageClearer( &m_progressMessage, QString() );
 | 
			
		||||
    std::unique_ptr< Runner > r;
 | 
			
		||||
    switch ( m_type )
 | 
			
		||||
    {
 | 
			
		||||
    case Type::FSArchive:
 | 
			
		||||
        r = std::make_unique< FSArchiverDirRunner >( m_source, m_destination );
 | 
			
		||||
        break;
 | 
			
		||||
    case Type::FSArchiveFS:
 | 
			
		||||
        r = std::make_unique< FSArchiverFSRunner >( m_source, m_destination );
 | 
			
		||||
        break;
 | 
			
		||||
    case Type::Squashfs:
 | 
			
		||||
        r = std::make_unique< UnsquashRunner >( m_source, m_destination );
 | 
			
		||||
        break;
 | 
			
		||||
    case Type::Tarball:
 | 
			
		||||
        r = std::make_unique< TarballRunner >( m_source, m_destination );
 | 
			
		||||
        break;
 | 
			
		||||
    case Type::None:
 | 
			
		||||
    default:
 | 
			
		||||
        cDebug() << "Nothing to do.";
 | 
			
		||||
        return Calamares::JobResult::ok();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    connect( r.get(),
 | 
			
		||||
             &Runner::progress,
 | 
			
		||||
             [ = ]( qreal percent, const QString& message )
 | 
			
		||||
             {
 | 
			
		||||
                 m_progressMessage = message;
 | 
			
		||||
                 Q_EMIT progress( percent );
 | 
			
		||||
             } );
 | 
			
		||||
    return r->run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
UnpackFSCJob::setConfigurationMap( const QVariantMap& map )
 | 
			
		||||
{
 | 
			
		||||
    QString source = 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 >(); )
 | 
			
		||||
							
								
								
									
										50
									
								
								modules/unpackfsc/UnpackFSCJob.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								modules/unpackfsc/UnpackFSCJob.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef UNPACKFSC_UNPACKFSCJOB_H
 | 
			
		||||
#define UNPACKFSC_UNPACKFSCJOB_H
 | 
			
		||||
 | 
			
		||||
#include <CppJob.h>
 | 
			
		||||
#include <DllMacro.h>
 | 
			
		||||
#include <utils/PluginFactory.h>
 | 
			
		||||
 | 
			
		||||
class PLUGINDLLEXPORT UnpackFSCJob : public Calamares::CppJob
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    enum class Type
 | 
			
		||||
    {
 | 
			
		||||
        None,  /// << Invalid
 | 
			
		||||
        FSArchive,
 | 
			
		||||
        FSArchiveFS,
 | 
			
		||||
        Squashfs,
 | 
			
		||||
        Tarball,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    explicit UnpackFSCJob( QObject* parent = nullptr );
 | 
			
		||||
    ~UnpackFSCJob() override;
 | 
			
		||||
 | 
			
		||||
    QString prettyName() const override;
 | 
			
		||||
    QString prettyStatusMessage() const override;
 | 
			
		||||
 | 
			
		||||
    Calamares::JobResult exec() override;
 | 
			
		||||
 | 
			
		||||
    void setConfigurationMap( const QVariantMap& configurationMap ) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QString m_source;
 | 
			
		||||
    QString m_destination;
 | 
			
		||||
    Type m_type = Type::None;
 | 
			
		||||
    QString m_progressMessage;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( UnpackFSCFactory )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										101
									
								
								modules/unpackfsc/UnsquashRunner.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								modules/unpackfsc/UnsquashRunner.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "UnsquashRunner.h"
 | 
			
		||||
 | 
			
		||||
#include <utils/Logger.h>
 | 
			
		||||
#include <utils/Runner.h>
 | 
			
		||||
#include <utils/String.h>
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
static constexpr const int chunk_size = 107;
 | 
			
		||||
 | 
			
		||||
Calamares::JobResult
 | 
			
		||||
UnsquashRunner::run()
 | 
			
		||||
{
 | 
			
		||||
    if ( !checkSourceExists() )
 | 
			
		||||
    {
 | 
			
		||||
        return Calamares::JobResult::internalError(
 | 
			
		||||
            tr( "Invalid unsquash configuration" ),
 | 
			
		||||
            tr( "The source archive <i>%1</i> does not exist." ).arg( m_source ),
 | 
			
		||||
            Calamares::JobResult::InvalidConfiguration );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const QString toolName = QStringLiteral( "unsquashfs" );
 | 
			
		||||
    QString unsquashExecutable;
 | 
			
		||||
    if ( !checkToolExists( toolName, unsquashExecutable ) )
 | 
			
		||||
    {
 | 
			
		||||
        return Calamares::JobResult::internalError(
 | 
			
		||||
            tr( "Missing tools" ),
 | 
			
		||||
            tr( "The <i>%1</i> tool is not installed on the system." ).arg( toolName ),
 | 
			
		||||
            Calamares::JobResult::MissingRequirements );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const QString destinationPath = 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 ) );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								modules/unpackfsc/UnsquashRunner.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								modules/unpackfsc/UnsquashRunner.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
/* === This file is part of Calamares - <https://calamares.io> ===
 | 
			
		||||
 *
 | 
			
		||||
 *   SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
 *   SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 *
 | 
			
		||||
 *   Calamares is Free Software: see the License-Identifier above.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef UNPACKFSC_UNSQUASHRUNNER_H
 | 
			
		||||
#define UNPACKFSC_UNSQUASHRUNNER_H
 | 
			
		||||
 | 
			
		||||
#include "Runners.h"
 | 
			
		||||
 | 
			
		||||
/** @brief Use Unsquash for extracting a filesystem
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class UnsquashRunner : public Runner
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    using Runner::Runner;
 | 
			
		||||
 | 
			
		||||
    Calamares::JobResult run() override;
 | 
			
		||||
 | 
			
		||||
protected Q_SLOTS:
 | 
			
		||||
    void unsquashProgress( QString line );
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    int m_inodes = 0;  // Total in the FS
 | 
			
		||||
 | 
			
		||||
    // Progress reporting
 | 
			
		||||
    int m_processed = 0;
 | 
			
		||||
    int m_since = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										2
									
								
								modules/unpackfsc/tests/1.global
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								modules/unpackfsc/tests/1.global
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
---
 | 
			
		||||
rootMountPoint: /tmp/fstest
 | 
			
		||||
							
								
								
									
										4
									
								
								modules/unpackfsc/tests/1.job
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								modules/unpackfsc/tests/1.job
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
---
 | 
			
		||||
source: /tmp/src.fsa
 | 
			
		||||
sourcefs: fsarchive
 | 
			
		||||
destination: "/calasrc"
 | 
			
		||||
							
								
								
									
										39
									
								
								modules/unpackfsc/unpackfsc.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								modules/unpackfsc/unpackfsc.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
# SPDX-FileCopyrightText: no
 | 
			
		||||
# SPDX-License-Identifier: CC0-1.0
 | 
			
		||||
#
 | 
			
		||||
# Unpack a filesystem. Supported ways to "pack" the filesystem are:
 | 
			
		||||
#   - fsarchiver in *savedir/restdir* mode (directories, not block devices)
 | 
			
		||||
#   - squashfs
 | 
			
		||||
#
 | 
			
		||||
# Configuration:
 | 
			
		||||
#
 | 
			
		||||
#   from globalstorage: rootMountPoint
 | 
			
		||||
#   from job configuration: the item to unpack
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
# This module is configured a lot like the items in the *unpackfs*
 | 
			
		||||
# module, but with only **one** item. Use multiple instances for
 | 
			
		||||
# unpacking more than one filesystem.
 | 
			
		||||
#
 | 
			
		||||
# There are the following **mandatory** keys:
 | 
			
		||||
#   - *source* path relative to the live / intstalling system to the image
 | 
			
		||||
#   - *sourcefs* the type of the source files; valid entries are
 | 
			
		||||
#       - `none` (this entry is ignored; kind of useless)
 | 
			
		||||
#       - `fsarchiver`
 | 
			
		||||
#         Aliases of this are `fsarchive`, `fsa` and `fsa-dir`. Uses
 | 
			
		||||
#         fsarchiver in "restdir" mode.
 | 
			
		||||
#       - `fsarchiver-block`
 | 
			
		||||
#         Aliases of this are `fsa-block` and `fsa-fs`. Uses fsarchiver
 | 
			
		||||
#         in "restfs" mode.
 | 
			
		||||
#       - `squashfs`
 | 
			
		||||
#         Aliases of this are `squash` and `unsquash`.
 | 
			
		||||
#       - `tar`
 | 
			
		||||
#   - *destination* path relative to rootMountPoint (so in the target
 | 
			
		||||
#       system) where this filesystem is unpacked. It may be an
 | 
			
		||||
#       empty string, which effectively is / (the root) of the target
 | 
			
		||||
#       system.
 | 
			
		||||
#
 | 
			
		||||
source: /data/rootfs.fsa
 | 
			
		||||
sourcefs: fsarchiver
 | 
			
		||||
destination: "/"
 | 
			
		||||
							
								
								
									
										19
									
								
								modules/unpackfsc/unpackfsc.schema.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								modules/unpackfsc/unpackfsc.schema.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
---
 | 
			
		||||
$schema: https://json-schema.org/schema#
 | 
			
		||||
$id: https://calamares.io/schemas/unpackfsc
 | 
			
		||||
additionalProperties: false
 | 
			
		||||
type: object
 | 
			
		||||
properties:
 | 
			
		||||
    unpack:
 | 
			
		||||
        type: array
 | 
			
		||||
        items:
 | 
			
		||||
            type: object
 | 
			
		||||
            additionalProperties: false
 | 
			
		||||
            properties:
 | 
			
		||||
                source: { type: string }
 | 
			
		||||
                sourcefs: { type: string }
 | 
			
		||||
                destination: { type: string }
 | 
			
		||||
                weight: { type: integer, exclusiveMinimum: 0 }
 | 
			
		||||
            required: [ source , sourcefs, destination ]
 | 
			
		||||
		Reference in New Issue
	
	Block a user