Compare commits
	
		
			66 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 81b4f01fe8 | ||
|   | cfdf15f9bd | ||
|   | 36f99b1291 | ||
|   | e4f38b235e | ||
|   | a50195e372 | ||
|   | 86e24fad9a | ||
|   | 0186985726 | ||
|   | 7bec3f6107 | ||
|   | 657207374e | ||
|   | 9661b70c57 | ||
|   | aa382db619 | ||
|   | 7ab294176a | ||
|   | 730b9fa983 | ||
|   | 2abe92a0f4 | ||
|   | 0fe1341c25 | ||
|   | c51d68828a | ||
|   | a61c0c6890 | ||
|   | 47cda51f8f | ||
|   | 18e68245c1 | ||
|   | 15a2369a98 | ||
|   | 0b6b923480 | ||
|   | 1b594b7125 | ||
|   | f1ce9235ac | ||
|   | 51e89e58dd | ||
|   | d8d5a1fb26 | ||
|   | 85f05e8121 | ||
|   | c28c9b8114 | ||
|   | 935f21ace5 | ||
|   | 14301dbc0b | ||
|   | a26a7b2e3a | ||
|   | d594db2308 | ||
|   | f29e3aaf4f | ||
|   | aeec465e63 | ||
|   | a7dcf46f95 | ||
|   | 575c000d5d | ||
|   | 7a6e6c63b7 | ||
|   | 03e0d3e4df | ||
|   | f06744bacf | ||
|   | 36f2589067 | ||
|   | 6f6bc4de5e | ||
|   | 86db905e1e | ||
|   | ebb7511f5e | ||
|   | 0dc15edb8f | ||
|   | bc0742be43 | ||
|   | 6bd75570de | ||
|   | acdcdea668 | ||
|   | edb405a4d1 | ||
|   | 3ad9c221d4 | ||
|   | 4412694cac | ||
|   | 8f3f6090c3 | ||
|   | 3d05a0d66e | ||
|   | 7c6e73cedb | ||
|   | ea01b275d3 | ||
|   | ab5623018a | ||
|   | ecee3d746c | ||
|   | c7d989dd36 | ||
|   | fe9c71d4fc | ||
|   | 59a4ea58e9 | ||
|   | 9b12dd711d | ||
|   | 6e4c2e728c | ||
|   | 98b72d79ea | ||
|   | c5377b75ac | ||
|   | c5bae4b0cc | ||
|   | dc3550eccd | ||
|   | fac16ac6a7 | ||
|   | a442ed8c12 | 
| @@ -22,14 +22,16 @@ Cpp11BracedListStyle: "false" | ||||
| FixNamespaceComments: "true" | ||||
| IncludeBlocks: Preserve | ||||
| IndentWidth: "4" | ||||
| InsertBraces: "true" | ||||
| MaxEmptyLinesToKeep: "2" | ||||
| NamespaceIndentation: None | ||||
| PointerAlignment: Left | ||||
| ReflowComments: "false" | ||||
| SortIncludes: "true" | ||||
| SpaceAfterCStyleCast: "false" | ||||
| SpaceInEmptyBlock: "false" | ||||
| SpacesBeforeTrailingComments: "2" | ||||
| SpacesInAngles: "true" | ||||
| SpacesInParentheses: "true" | ||||
| SpacesInSquareBrackets: "true" | ||||
| Standard: Cpp11 | ||||
| Standard: c++17 | ||||
|   | ||||
							
								
								
									
										24
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -6,6 +6,30 @@ 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. | ||||
|  | ||||
| # 3.3.12 (2024-11-21) | ||||
|  | ||||
| This is a release to match Calamares 3.3.12. The *unpackfsc* module has | ||||
| moved to Calamares proper. There is a new module *flatpakinfo* that | ||||
| tries to populate a netinstall key with packages available as flatpak. | ||||
|  | ||||
| This release contains contributions from (alphabetically by first name): | ||||
|  - Adriaan de Groot | ||||
|  - Sławomir Lach | ||||
|  | ||||
|  | ||||
| # 3.3.1 (2024-01-15) | ||||
|  | ||||
| This is the first *calamares-extensions* release to go with a Calamares 3.3 | ||||
| release. The extensions now require Calamares 3.3. There is a branch for | ||||
| 3.2 legacy support but no releases are planned for it. The main reason | ||||
| for this release is to have a 3.3-compatible release of *-extensions* at all. | ||||
|  | ||||
| This release contains contributions from (alphabetically by first name): | ||||
|  - Adriaan de Groot | ||||
|  - Anke Boersma | ||||
|  - undef | ||||
|  | ||||
|  | ||||
| # 1.3.2 (2023-08-28) | ||||
|  | ||||
| We skipped a couple of releases in the release-notes, then tagged | ||||
|   | ||||
| @@ -32,15 +32,18 @@ | ||||
| # In this repository, there is just one "group" to which USE_* applies: | ||||
| #   USE_os          : operating-system-specific modules. | ||||
| # | ||||
| # There is a knob WITH_QT6 which can be used to build against Qt6 rather | ||||
| # than Qt5. This must match what Calamares itself is built with. | ||||
| # | ||||
| ### NOTES | ||||
| # | ||||
| # Call this CMake file in script mode, e.g. `cmake -P CMakeLists.txt` | ||||
| # to print out version information. Use `cmake -DVERSION_STYLE=short` | ||||
| # to get just the short versioning. | ||||
| # | ||||
| cmake_minimum_required(VERSION 3.3 FATAL_ERROR) | ||||
| cmake_minimum_required(VERSION 3.16 FATAL_ERROR) | ||||
|  | ||||
| set( CALAMARES_EXTENSIONS_VERSION 1.3.2 ) | ||||
| set( CALAMARES_EXTENSIONS_VERSION 3.3.12 ) | ||||
|  | ||||
| include( ${CMAKE_CURRENT_LIST_DIR}/CMakeModules/ExtendedVersion.cmake ) | ||||
| if ( CMAKE_SCRIPT_MODE_FILE ) | ||||
| @@ -60,12 +63,44 @@ set( CMAKE_CXX_STANDARD_REQUIRED ON ) | ||||
| # consumers by loading the developer's config from a build | ||||
| # directory (which doesn't have the rest of the config | ||||
| # installed inside it). | ||||
| set( CALAMARES_VERSION_REQUIRED 3.2.46 ) | ||||
| find_package(Calamares ${CALAMARES_VERSION_REQUIRED} NO_CMAKE_PACKAGE_REGISTRY) | ||||
| set( CALAMARES_VERSION_REQUIRED 3.3.12 ) | ||||
| message(STATUS "Looking for Calamares system-wide") | ||||
| find_package(Calamares ${CALAMARES_VERSION_REQUIRED} CONFIG NO_CMAKE_PACKAGE_REGISTRY) | ||||
| if (NOT TARGET Calamares::calamares OR NOT TARGET Calamares::calamaresui) | ||||
|     find_package(Calamares ${CALAMARES_VERSION_REQUIRED} REQUIRED) | ||||
|     message(STATUS "Looking for Calamares in the package registry") | ||||
|     find_package(Calamares ${CALAMARES_VERSION_REQUIRED} CONFIG REQUIRED) | ||||
| endif() | ||||
|  | ||||
| message(STATUS "Found Calamares version ${Calamares_VERSION}") | ||||
| message(STATUS "              libraries ${Calamares_LIB_DIRS}") | ||||
| message(STATUS "") | ||||
|  | ||||
| ### EXTRACTING DEPENDENCIES AND CONFIGURATION FROM CALAMARES | ||||
| # | ||||
| # | ||||
| if(Calamares_WITH_QT6) | ||||
|     set(kfname "KF6") | ||||
|     set(KF_VERSION 5.240) # KDE Neon weirdness | ||||
| else() | ||||
|     message(STATUS "Building Calamares-extensions with Qt5") | ||||
|     set(kfname "KF5") | ||||
|     set(KF_VERSION 5.78) | ||||
|     # API that was deprecated before Qt 5.15 causes a compile error | ||||
|     add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0x050f00) | ||||
| endif() | ||||
|  | ||||
| include( FeatureSummary ) | ||||
| find_package(${kfname}CoreAddons ${KF_VERSION} QUIET) | ||||
| set_package_properties( | ||||
|     ${kfname}CoreAddons | ||||
|     PROPERTIES | ||||
|     TYPE REQUIRED | ||||
|     DESCRIPTION "KDE Framework CoreAddons" | ||||
|     URL "https://api.kde.org/frameworks/" | ||||
|     PURPOSE "Essential Framework for AboutData and Macros" | ||||
| ) | ||||
|  | ||||
|  | ||||
| ### CMAKE SETUP | ||||
| # | ||||
| # Enable IN_LIST | ||||
| @@ -117,7 +152,11 @@ 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 ) | ||||
| # The unpackfsc module moved into Calamares proper in 3.3.11 | ||||
| # | ||||
| # calamares_add_module_subdirectory( modules/unpackfsc LIST_SKIPPED_MODULES ) | ||||
|  | ||||
| message(STATUS "Calamares extensions ${CALAMARES_EXTENSIONS_VERSION} for Calamares version ${Calamares_VERSION}") | ||||
|  | ||||
| # If modules cannot be built, they usually call a macro | ||||
| # which builds a list of explanations; show that list. | ||||
|   | ||||
| @@ -164,10 +164,6 @@ phase). | ||||
|  | ||||
| ### Example Modules | ||||
|  | ||||
| - [filekeeper](modules/filekeeper/CMakeLists.txt) is a C++ **job** module | ||||
|   to copy files from the host (live) system to the target system at | ||||
|   the end of installation, like logfiles. (This module is made obsolete | ||||
|   by the *preservefiles* module included with Calamares proper) | ||||
| - [freebsddisk](modules/freebsddisk/CMakeLists.txt) is a C++ **view** | ||||
|   module with a QML-based UI. It has no actual functionality, and serves | ||||
|   as a test that view modules can be built out-of-tree. | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| # NOTE: this is largely a copy of the release script for Calamares, | ||||
| #       with not-applicable parts (such as translation-freeze) either | ||||
| #       commented-out, or skipped with if(false). | ||||
| # NOTE: this script contains Linuxisms (in particular, expects GNU mktemp(1)) | ||||
| # NOTE: this script may contain Linuxisms | ||||
| # | ||||
| # This attempts to perform the different steps of the RELEASE.md | ||||
| # document automatically. It's not tested on other machines or | ||||
| @@ -93,7 +93,7 @@ fi | ||||
| ### Setup | ||||
| # | ||||
| # | ||||
| BUILDDIR=$(mktemp -d --suffix=-build --tmpdir=.) | ||||
| BUILDDIR=$(mktemp -d -p . -t cala-tmp-XXXXX) | ||||
|  | ||||
| ### Build with default compiler | ||||
| # | ||||
| @@ -167,7 +167,7 @@ gpg -s -u $KEY_ID --detach --armor $TAR_FILE  # Sign the tarball | ||||
| # | ||||
| # | ||||
| D=$(date +%Y%m%d-%H%M%S) | ||||
| TMPDIR=$(mktemp -d --suffix="-calamares-$D") | ||||
| TMPDIR=$(mktemp -d -p . -t calamares.XXXXX) | ||||
| test -d "$TMPDIR" || { echo "Could not create tarball-build directory." ; exit 1 ; } | ||||
| tar xzf "$TAR_FILE" -C "$TMPDIR" || { echo "Could not unpack tarball." ; exit 1 ; } | ||||
| test -d "$TMPDIR/$TAR_V" || { echo "Tarball did not contain source directory." ; exit 1 ; } | ||||
|   | ||||
| @@ -4,12 +4,14 @@ | ||||
| #   SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org> | ||||
| #   SPDX-License-Identifier: BSD-2-Clause | ||||
| # | ||||
| # Calls astyle with settings matching Calamares coding style | ||||
| # Requires astyle >= 2.04 and clang-format-8 or later | ||||
| # Apply Calamares-style formatting to sources. Requires clang-format-15. | ||||
| # | ||||
| # You can pass in directory names, in which case the files | ||||
| # in that directory (NOT below it) are processed. | ||||
| # | ||||
| # If the environment variable CLANG_FORMAT is set to a (full path) and | ||||
| # that path is executable, it will be used if possible. | ||||
| # | ||||
| LANG=C | ||||
| LC_ALL=C | ||||
| LC_NUMERIC=C | ||||
| @@ -19,12 +21,19 @@ 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 ; } | ||||
| test -f "$TOPDIR/.clang-format" || { echo "! No .clang-format support files in $TOPDIR" ; exit 1 ; } | ||||
|  | ||||
| AS=$( which astyle ) | ||||
|  | ||||
| # Allow specifying CF_VERSIONS outside already | ||||
| CF_VERSIONS="$CF_VERSIONS clang-format-8 clang-format80 clang-format90 clang-format-9.0.1 clang-format" | ||||
| # Start with CLANG_FORMAT, if it is specified | ||||
| CF_VERSIONS="" | ||||
| if test -n "$CLANG_FORMAT" && test -x "$CLANG_FORMAT" ; then | ||||
| 	CF_VERSIONS="$CLANG_FORMAT" | ||||
| fi | ||||
| # And a bunch of other potential known versions of clang-format, newest first | ||||
| CF_VERSIONS="$CF_VERSIONS clang-format-17" | ||||
| CF_VERSIONS="$CF_VERSIONS clang-format-16 clang-format-16.0.6 " | ||||
| CF_VERSIONS="$CF_VERSIONS clang-format15 clang-format-15 " | ||||
| # Generic name of clang-format | ||||
| CF_VERSIONS="$CF_VERSIONS clang-format" | ||||
| for _cf in $CF_VERSIONS | ||||
| do | ||||
| 	# Not an error if this particular clang-format isn't found | ||||
| @@ -32,39 +41,33 @@ do | ||||
| 	test -n "$CF" && break | ||||
| done | ||||
|  | ||||
| test -n "$AS" || { echo "! No astyle found in PATH"; exit 1 ; } | ||||
| test -n "$CF" || { echo "! No clang-format ($CF_VERSIONS) found in PATH"; exit 1 ; } | ||||
| test -x "$AS" || { echo "! $AS is not executable."; exit 1 ; } | ||||
| test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; } | ||||
|  | ||||
| ### CLANG-FORMAT-WRANGLING | ||||
| # | ||||
| # Version 7 and earlier doesn't understand all the options we would like | ||||
| # Version 8 is ok | ||||
| # Version 9 is ok | ||||
| # Later versions change some defaults so need extra wrangling. | ||||
| # .. there are extra files that are appended to the settings, per | ||||
| # .. clang-format version. | ||||
| # Version 7 and earlier doesn't understand all the options we would like. | ||||
| # Version 12 handled lambdas nicely and was the norm for Calamares 3.2. | ||||
| # Version 13 was also ok. | ||||
| # Version 14 behaves differently with short-functions-in-class, | ||||
| #   spreading functions out that 13 keeps on one line. To avoid | ||||
| #   ping-pong commits, forbid 14. | ||||
| # Version 15 is available on recent-ish Ubuntus and FreeBSD, pick it. | ||||
| #   It also supports inserting braces, which is the one thing we kept | ||||
| #   astyle around for. | ||||
| # Version 16 is available on openSUSE and is ok as well. | ||||
| # Version 17 is available on FreeBSD and KaOS and is ok as well. | ||||
|  | ||||
| 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] ) | ||||
| 	15|16|17 ) | ||||
| 		: | ||||
| 		;; | ||||
| 	* ) | ||||
| 		echo "! Clang-format version '$format_version' unsupported." | ||||
| 		echo "! Clang-format version '$format_version' unsupported, versions 15-17 are ok." | ||||
| 		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 | ||||
| @@ -81,7 +84,6 @@ done | ||||
| style_some() | ||||
| { | ||||
| 	if test -n "$*" ; then | ||||
| 		$AS --options=$BASEDIR/astylerc --quiet "$@" | ||||
| 		$CF -i -style=file "$@" | ||||
| 	fi | ||||
| } | ||||
| @@ -98,8 +100,3 @@ if test "x$any_dirs" = "xyes" ; then | ||||
| else | ||||
| 	style_some "$@" | ||||
| fi | ||||
|  | ||||
| ### CLANG-FORMAT-WRANGLING | ||||
| # | ||||
| # Restore the original .clang-format | ||||
| cp "$_fmt.base" "$_fmt" | ||||
|   | ||||
							
								
								
									
										17
									
								
								modules/flatpakinfo/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								modules/flatpakinfo/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| # === This file is part of Calamares - <https://calamares.io> === | ||||
| # | ||||
| #   SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org> | ||||
| #   SPDX-License-Identifier: BSD-2-Clause | ||||
| # | ||||
| calamares_add_plugin(flatpakInfo | ||||
|     TYPE job | ||||
|     EXPORT_MACRO PLUGINDLLEXPORT_PRO | ||||
|     SOURCES | ||||
|         FlatpakInfoJob.h | ||||
|         ItemFlatpak.h | ||||
|         PackagePool.h | ||||
|         FlatpakInfoJob.cpp | ||||
|         ItemFlatpak.cpp | ||||
|         PackagePool.cpp | ||||
|     SHARED_LIB | ||||
| ) | ||||
							
								
								
									
										63
									
								
								modules/flatpakinfo/FlatpakInfoJob.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								modules/flatpakinfo/FlatpakInfoJob.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| /* === This file is part of Calamares - <https://calamares.io> === | ||||
|  * | ||||
|  *   SPDX-FileCopyrightText: 2023 Sławomir Lach <slawek@lach.art.pl> | ||||
|  *   SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  * | ||||
|  *   Calamares is Free Software: see the License-Identifier above. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "FlatpakInfoJob.h" | ||||
|  | ||||
| #include "utils/Runner.h" | ||||
| #include "utils/Logger.h" | ||||
| #include "utils/Variant.h" | ||||
|  | ||||
| #include "GlobalStorage.h" | ||||
| #include "JobQueue.h" | ||||
| #include "Settings.h" | ||||
|  | ||||
| #include <QProcess> | ||||
|  | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include "ItemFlatpak.h" | ||||
| #include "PackagePool.h" | ||||
|  | ||||
| FlatpakInfoJob::FlatpakInfoJob( QObject* parent ) | ||||
|     : Calamares::CppJob( parent ) | ||||
| { | ||||
| } | ||||
|  | ||||
| FlatpakInfoJob::~FlatpakInfoJob() | ||||
| { | ||||
|     ItemFlatpak_freeMem(); | ||||
| } | ||||
|  | ||||
| QString | ||||
| FlatpakInfoJob::prettyName() const | ||||
| { | ||||
|     return tr( "Fill netinstall with flatpak packages" ); | ||||
| } | ||||
|  | ||||
|  | ||||
| Calamares::JobResult | ||||
| FlatpakInfoJob::exec() | ||||
| { | ||||
|     QVariantList partitions; | ||||
|     Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); | ||||
|  | ||||
|  | ||||
|     downloadPackagesInfo(); | ||||
|     serializePackagesInfo(); | ||||
|  | ||||
|     return Calamares::JobResult::ok(); | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| FlatpakInfoJob::setConfigurationMap( const QVariantMap& map ) | ||||
| { | ||||
| } | ||||
|  | ||||
| CALAMARES_PLUGIN_FACTORY_DEFINITION( FlatpakInfoJobFactory, registerPlugin< FlatpakInfoJob >(); ) | ||||
							
								
								
									
										43
									
								
								modules/flatpakinfo/FlatpakInfoJob.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								modules/flatpakinfo/FlatpakInfoJob.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /* === This file is part of Calamares - <https://calamares.io> === | ||||
|  * | ||||
|  *   SPDX-FileCopyrightText: 2023 Sławomir Lach <slawek@lach.art.pl> | ||||
|  *   SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  * | ||||
|  *   Calamares is Free Software: see the License-Identifier above. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef FLATPAKINFOJOB_H | ||||
| #define FLATPAKINFOJOB_H | ||||
|  | ||||
| #include <QObject> | ||||
| #include <QStringList> | ||||
| #include <QVariantMap> | ||||
|  | ||||
| #include "CppJob.h" | ||||
|  | ||||
| #include "utils/PluginFactory.h" | ||||
|  | ||||
| #include "DllMacro.h" | ||||
|  | ||||
| /** @brief Create zpools and zfs datasets | ||||
|  * | ||||
|  */ | ||||
| class PLUGINDLLEXPORT FlatpakInfoJob : public Calamares::CppJob | ||||
| { | ||||
|     Q_OBJECT | ||||
|  | ||||
| public: | ||||
|     explicit FlatpakInfoJob( QObject* parent = nullptr ); | ||||
|     ~FlatpakInfoJob() override; | ||||
|  | ||||
|     QString prettyName() const override; | ||||
|  | ||||
|     Calamares::JobResult exec() override; | ||||
|  | ||||
|     void setConfigurationMap( const QVariantMap& configurationMap ) override; | ||||
| }; | ||||
|  | ||||
| CALAMARES_PLUGIN_FACTORY_DECLARATION( FlatpakInfoJobFactory ) | ||||
|  | ||||
| #endif  // ZFSJOB_H | ||||
							
								
								
									
										66
									
								
								modules/flatpakinfo/ItemFlatpak.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								modules/flatpakinfo/ItemFlatpak.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| /* === This file is part of Calamares - <https://calamares.io> === | ||||
|  * | ||||
|  *   SPDX-FileCopyrightText: 2023 Sławomir Lach <slawek@lach.art.pl> | ||||
|  *   SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  * | ||||
|  *   Calamares is Free Software: see the License-Identifier above. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /* Qt */ | ||||
| #include <QVariantMap> | ||||
|  | ||||
| /* CPP */ | ||||
| #include <fstream> | ||||
| #include <iostream> | ||||
|  | ||||
| /* Calamares */ | ||||
| #include "utils/Runner.h" | ||||
|  | ||||
| /* Module */ | ||||
| #include "ItemFlatpak.h" | ||||
| #include "utils/Logger.h" | ||||
| #include "utils/Variant.h" | ||||
|  | ||||
| PackageItem | ||||
| fromFlatpak( const QVariantMap& itemMap, InstalledList &installed ) | ||||
| { | ||||
|     // check if it is installed | ||||
|     PackageItem item( Calamares::getString( itemMap, "appstream" ) ); | ||||
|     item.setInstalled( false ); | ||||
|  | ||||
|     item.setInstalled( installed.contains( Calamares::getString( itemMap, "appstream" ) ) ); | ||||
|  | ||||
|     return item; | ||||
| } | ||||
|  | ||||
| InstalledList::InstalledList() | ||||
| { | ||||
|     long long int prev_pos; | ||||
|     long long int pos = 0; | ||||
|     QString line; | ||||
|     auto process = Calamares::System::instance()->targetEnvCommand( | ||||
|         QStringList { QString::fromLatin1( "flatpak" ), | ||||
|                       QString::fromLatin1( "list" ), | ||||
|                       QString::fromLatin1( "--app" ), | ||||
|                       QString::fromLatin1( "--columns=application" ) } ); | ||||
|     auto outputStr = process.second; | ||||
|  | ||||
|     do { | ||||
|         prev_pos = pos; | ||||
|  | ||||
|         pos = outputStr.indexOf('\n', prev_pos); | ||||
|         QString line = outputStr.mid(prev_pos, pos); | ||||
|         installed.append(line); | ||||
|  | ||||
|         /* Increase by 1 to not stuck on newline */ | ||||
|         ++pos; | ||||
|  | ||||
|     /* QString::indexOf returns -1 since no occurences. 0 = -1 + 1.*/ | ||||
|     } while (0 != pos); | ||||
| } | ||||
|  | ||||
| InstalledList::~InstalledList() | ||||
| { | ||||
|     installed.clear(); | ||||
| } | ||||
							
								
								
									
										0
									
								
								modules/flatpakinfo/ItemFlatpak.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								modules/flatpakinfo/ItemFlatpak.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										110
									
								
								modules/flatpakinfo/PackagePool.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								modules/flatpakinfo/PackagePool.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| /* === This file is part of Calamares - <https://calamares.io> === | ||||
|  * | ||||
|  *   SPDX-FileCopyrightText: 2023 Sławomir Lach <slawek@lach.art.pl> | ||||
|  *   SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  * | ||||
|  *   Calamares is Free Software: see the License-Identifier above. | ||||
|  */ | ||||
|  | ||||
| #include <fstream> | ||||
| #include <iostream> | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <sys/wait.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include <QString> | ||||
| #include <QDesktopServices> | ||||
| #include <QVariantMap> | ||||
|  | ||||
| #include "GlobalStorage.h" | ||||
| #include "JobQueue.h" | ||||
| #include "utils/Logger.h" | ||||
| #include "utils/Variant.h" | ||||
| #include "ItemFlatpak.h" | ||||
| #include "PackagePool.h" | ||||
|  | ||||
| #include "utils/System.h" | ||||
|  | ||||
| void PackagePool::downloadPackagesInfo(InstalledList &list) | ||||
| { | ||||
|     QHash<QString,bool> addedPackages; | ||||
|     QString line; | ||||
|     auto process = Calamares::System::instance()->targetEnvCommand( QStringList { QString::fromStdString( "flatpak" ), QString::fromStdString( "remotes" ), QString::fromStdString( "--columns=name" ) }); | ||||
|     auto outputStr = process.second; | ||||
|     QTextStream output(&outputStr); | ||||
|  | ||||
|     while (output.readLineInto(&line)) | ||||
|     { | ||||
|         QString line2; | ||||
|         auto process2 = Calamares::System::instance()->targetEnvCommand( | ||||
|             QStringList { QString::fromStdString( "flatpak" ), | ||||
|                           QString::fromStdString( "remote-ls" ), | ||||
|                           QString::fromStdString( "--app" ), | ||||
|                           QString::fromStdString( "--columns=application" ), | ||||
|                           line } ); | ||||
|         auto output2Str = process2.second; | ||||
|         QTextStream output2( &output2Str ); | ||||
|  | ||||
|         while ( output2.readLineInto( &line2 ) ) | ||||
|         { | ||||
|             if ( line2 == "" ) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|             QVariantMap itemMap; | ||||
|  | ||||
|             if ( addedPackages.contains( line2 ) ) | ||||
|             { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             addedPackages.insert( line2, true ); | ||||
|  | ||||
|             itemMap.insert( "appstream", QVariant( line2 ) ); | ||||
|             itemMap.insert( "id", QVariant( line2 ) ); | ||||
|  | ||||
|             PackageItem item = fromFlatpak( itemMap, list ); | ||||
|             packages.append( item ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     serializePackagesInfo(); | ||||
| } | ||||
|  | ||||
| void PackagePool::serializePackagesInfo() | ||||
| { | ||||
|         QList<QVariant> changedValue; | ||||
|         auto* gs = Calamares::JobQueue::instance()->globalStorage(); | ||||
|  | ||||
|         // If an earlier packagechooser instance added this data to global storage, combine them | ||||
|         if ( gs->contains( "netinstallAdd" ) ) | ||||
|         { | ||||
|             auto selectedOrig = gs->value( "netinstallAdd" ); | ||||
|  | ||||
|             changedValue = selectedOrig.toList(); | ||||
|             for (auto current: packages) | ||||
|             { | ||||
|                QStringList selfInstall; | ||||
|                QVariantMap newValue; | ||||
|                newValue.insert("name", current.getAppStreamId()); | ||||
|  | ||||
|                if (current.getInstalled()) | ||||
|                { | ||||
|                  newValue.insert("selected", true); | ||||
|                  newValue.insert("immutable", true); | ||||
|                  newValue.insert("description", "[Already installed; cannot be uninstalled]"); | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                  newValue.insert("selected", false); | ||||
|                } | ||||
|                selfInstall.append(current.getAppStreamId()); | ||||
|                newValue.insert("packages", selfInstall); | ||||
|                changedValue.append(newValue); | ||||
|             } | ||||
|  | ||||
|             gs->remove( "netinstallAdd" ); | ||||
|         } | ||||
|         gs->insert( "netinstallAdd", changedValue ); | ||||
| } | ||||
							
								
								
									
										0
									
								
								modules/flatpakinfo/PackagePool.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								modules/flatpakinfo/PackagePool.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										8
									
								
								modules/flatpakinfo/flatpakInfo.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								modules/flatpakinfo/flatpakInfo.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| # SPDX-FileCopyrightText: no | ||||
| # SPDX-License-Identifier: CC0-1.0 | ||||
| # | ||||
| # The flatpakinfo module will collect package list from configured flatpak repositories | ||||
| # | ||||
| # | ||||
| # | ||||
| --- | ||||
							
								
								
									
										7
									
								
								modules/flatpakinfo/module.desc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								modules/flatpakinfo/module.desc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| # SPDX-FileCopyrightText: no | ||||
| # SPDX-License-Identifier: CC0-1.0 | ||||
| --- | ||||
| type:      "job" | ||||
| name:      "flatpakinfo" | ||||
| interface: "qtplugin" | ||||
| load:      "libcalamares_job_flatpakInfo.so" | ||||
| @@ -18,7 +18,7 @@ Config::Config( QObject* parent ) | ||||
| void | ||||
| Config::setConfigurationMap( const QVariantMap& cfgMap ) | ||||
| { | ||||
|     using namespace CalamaresUtils; | ||||
|     using namespace Calamares; | ||||
|  | ||||
|     if ( getBool( cfgMap, "bogus", false ) ) | ||||
|     { | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| #include "GlobalStorage.h" | ||||
| #include "JobQueue.h" | ||||
| #include "Settings.h" | ||||
| #include "utils/CalamaresUtilsSystem.h" | ||||
| #include "utils/System.h" | ||||
| #include "utils/Logger.h" | ||||
|  | ||||
| #include <QDir> | ||||
| @@ -75,7 +75,7 @@ Calamares::JobResult | ||||
| PartitionJob::exec() | ||||
| { | ||||
|     using namespace Calamares; | ||||
|     using namespace CalamaresUtils; | ||||
|     using namespace Calamares; | ||||
|     using namespace std; | ||||
|  | ||||
|     const QString pathMount = "/mnt/install"; | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| #include "GlobalStorage.h" | ||||
| #include "JobQueue.h" | ||||
| #include "Settings.h" | ||||
| #include "utils/CalamaresUtilsSystem.h" | ||||
| #include "utils/System.h" | ||||
| #include "utils/Logger.h" | ||||
|  | ||||
| #include <QDir> | ||||
| @@ -47,7 +47,7 @@ Calamares::JobResult | ||||
| UsersJob::exec() | ||||
| { | ||||
|     using namespace Calamares; | ||||
|     using namespace CalamaresUtils; | ||||
|     using namespace Calamares; | ||||
|     using namespace std; | ||||
|  | ||||
|     QList< QPair< QStringList, QString > > commands = { | ||||
|   | ||||
| @@ -22,7 +22,7 @@ Item { | ||||
|         id: mainText | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: parent.top | ||||
|         anchors.topMargin: 30 | ||||
|         anchors.topMargin: 10 | ||||
|         wrapMode: Text.WordWrap | ||||
|  | ||||
|         text: "To protect your data in case your device gets stolen," + | ||||
| @@ -33,15 +33,15 @@ Item { | ||||
|               " boot your device or access any data on it. Make sure that" + | ||||
|               " you don't lose this password!" | ||||
|  | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Button { | ||||
|         id: firstButton | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: mainText.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Enable") | ||||
|         onClicked: { | ||||
| @@ -53,8 +53,8 @@ Item { | ||||
|     Button { | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: firstButton.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Disable") | ||||
|         onClicked: { | ||||
|   | ||||
| @@ -36,7 +36,7 @@ Item { | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     TextField { | ||||
| @@ -49,8 +49,8 @@ Item { | ||||
|         text: config.fdePassword | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Text { | ||||
| @@ -59,15 +59,15 @@ Item { | ||||
|         visible: false | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|         wrapMode: Text.WordWrap | ||||
|     } | ||||
|     Button { | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: errorText.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Continue") | ||||
|         onClicked: { | ||||
|   | ||||
| @@ -22,21 +22,21 @@ Item { | ||||
|         id: mainText | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: parent.top | ||||
|         anchors.topMargin: 30 | ||||
|         anchors.topMargin: 10 | ||||
|         wrapMode: Text.WordWrap | ||||
|  | ||||
|         text: "Select the filesystem for root partition. If unsure, leave the default." | ||||
|  | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     ComboBox { | ||||
|         id: fsTypeCB | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: mainText.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         height: 60 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 150 | ||||
|         height: 30 | ||||
|         editable: false | ||||
|         model: config.fsList | ||||
|         /* Save the current state on selection so it is there when the back button is pressed */ | ||||
| @@ -47,8 +47,8 @@ Item { | ||||
|     Button { | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: fsTypeCB.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Continue") | ||||
|         onClicked: { | ||||
|   | ||||
| @@ -22,7 +22,7 @@ Item { | ||||
|         id: mainText | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: parent.top | ||||
|         anchors.topMargin: 25 | ||||
|         anchors.topMargin: 10 | ||||
|         wrapMode: Text.WordWrap | ||||
|  | ||||
|         text: (function() { | ||||
| @@ -44,15 +44,15 @@ Item { | ||||
|             return ret; | ||||
|         }()) | ||||
|  | ||||
|         width: 550 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Button { | ||||
|         id: firstButton | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: mainText.bottom | ||||
|         anchors.topMargin: 20 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Install") | ||||
|         onClicked: navFinish() | ||||
|   | ||||
| @@ -22,7 +22,7 @@ Item { | ||||
|         id: mainText | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: parent.top | ||||
|         anchors.topMargin: 30 | ||||
|         anchors.topMargin: 10 | ||||
|         wrapMode: Text.WordWrap | ||||
|  | ||||
|         text: "The installation was started from an external storage medium." + | ||||
| @@ -32,15 +32,15 @@ Item { | ||||
|               "<br>" + | ||||
|               "Where would you like to install " + config.osName + "?" | ||||
|  | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Button { | ||||
|         id: firstButton | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: mainText.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Internal (eMMC)") | ||||
|         onClicked: { | ||||
| @@ -52,8 +52,8 @@ Item { | ||||
|     Button { | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: firstButton.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("External (SD card)") | ||||
|         onClicked: { | ||||
|   | ||||
| @@ -22,21 +22,21 @@ Item { | ||||
|         id: mainText | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: parent.top | ||||
|         anchors.topMargin: 30 | ||||
|         anchors.topMargin: 10 | ||||
|         wrapMode: Text.WordWrap | ||||
|  | ||||
| 	text: "Are you sure that you want to overwrite the internal storage?" + | ||||
| 	      "<br><br>" + | ||||
| 	      "<b>All existing data on the device will be lost!</b>" | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Button { | ||||
|         id: firstButton | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: mainText.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Yes") | ||||
|         onClicked: { | ||||
| @@ -47,8 +47,8 @@ Item { | ||||
|     Button { | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: firstButton.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("No") | ||||
|         onClicked: { | ||||
|   | ||||
| @@ -77,7 +77,7 @@ Page | ||||
|             Rectangle { | ||||
|                 id: mobileNavigation | ||||
|                 width: parent.width | ||||
|                 height: 60 | ||||
|                 height: 30 | ||||
|                 color: "#e6e4e1" | ||||
|                 Layout.fillWidth: true | ||||
|  | ||||
| @@ -98,8 +98,8 @@ Page | ||||
|                         text: "<" | ||||
|  | ||||
|                         background: Rectangle { | ||||
|                             implicitWidth: 32 | ||||
|                             implicitHeight: 30 | ||||
|                             implicitWidth: 10 | ||||
|                             implicitHeight: 7 | ||||
|                             border.color: "#c1bab5" | ||||
|                             border.width: 1 | ||||
|                             radius: 4 | ||||
| @@ -109,7 +109,7 @@ Page | ||||
|                         onClicked: navBack() | ||||
|                     } | ||||
|                     Rectangle { | ||||
|                         implicitHeight: 30 | ||||
|                         implicitHeight: 10 | ||||
|                         Layout.fillWidth: true | ||||
|                         color: "#e6e4e1" | ||||
|  | ||||
|   | ||||
| @@ -36,7 +36,7 @@ Item { | ||||
|               "More information:<br>" + | ||||
|               "https://postmarketos.org/ssh" | ||||
|  | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Button { | ||||
| @@ -44,7 +44,7 @@ Item { | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: mainText.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Enable") | ||||
|         onClicked: { | ||||
| @@ -57,7 +57,7 @@ Item { | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: firstButton.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Disable") | ||||
|         onClicked: { | ||||
|   | ||||
| @@ -34,7 +34,7 @@ Item { | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Text { | ||||
| @@ -45,7 +45,7 @@ Item { | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     TextField { | ||||
| @@ -59,7 +59,7 @@ Item { | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     TextField { | ||||
| @@ -73,7 +73,7 @@ Item { | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Text { | ||||
| @@ -84,13 +84,13 @@ Item { | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|     Button { | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: errorTextPassword.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Continue") | ||||
|         onClicked: { | ||||
|   | ||||
| @@ -35,7 +35,7 @@ Item { | ||||
|         id: usernameDescription | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: parent.top | ||||
|         anchors.topMargin: 30 | ||||
|         anchors.topMargin: 10 | ||||
|         wrapMode: Text.WordWrap | ||||
|  | ||||
|         text: (function() { | ||||
| @@ -43,7 +43,7 @@ Item { | ||||
|                    " username is \"" + config.username + "\"."; | ||||
|         }()) | ||||
|  | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     TextField { | ||||
| @@ -53,15 +53,15 @@ Item { | ||||
|         onTextChanged: validateNameFunc(username, errorText) | ||||
|         text: config.username | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Text { | ||||
|         id: userPassDescription | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: username.bottom | ||||
|         anchors.topMargin: 30 | ||||
|         anchors.topMargin: 10 | ||||
|         wrapMode: Text.WordWrap | ||||
|  | ||||
|         text: (function() { | ||||
| @@ -76,7 +76,7 @@ Item { | ||||
|             } | ||||
|         }()) | ||||
|  | ||||
|         width: 500 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     TextField { | ||||
| @@ -96,8 +96,8 @@ Item { | ||||
|         } | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     TextField { | ||||
| @@ -110,8 +110,8 @@ Item { | ||||
|         text: config.userPassword | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Text { | ||||
| @@ -121,15 +121,15 @@ Item { | ||||
|         wrapMode: Text.WordWrap | ||||
|  | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.topMargin: 50 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|     } | ||||
|  | ||||
|     Button { | ||||
|         anchors.horizontalCenter: parent.horizontalCenter | ||||
|         anchors.top: errorText.bottom | ||||
|         anchors.topMargin: 40 | ||||
|         width: 500 | ||||
|         anchors.topMargin: 10 | ||||
|         width: 200 | ||||
|  | ||||
|         text: qsTr("Continue") | ||||
|         onClicked: { | ||||
|   | ||||
| @@ -26,8 +26,8 @@ Page | ||||
|             id: logo | ||||
|             anchors.horizontalCenter: parent.horizontalCenter | ||||
|             anchors.top: parent.top | ||||
|             anchors.topMargin: 50 | ||||
|             height: 250 | ||||
|             anchors.topMargin: 10 | ||||
|             height: 50 | ||||
|             fillMode: Image.PreserveAspectFit | ||||
|             source: "file:///usr/share/calamares/branding/default-mobile/logo.png" | ||||
|         } | ||||
| @@ -35,11 +35,11 @@ Page | ||||
|             id: waitText | ||||
|             anchors.horizontalCenter: parent.horizontalCenter | ||||
|             anchors.top: logo.bottom | ||||
|             anchors.topMargin: 150 | ||||
|             anchors.topMargin: 50 | ||||
|             wrapMode: Text.WordWrap | ||||
|             text: "Formatting and mounting target partition. This may" + | ||||
|                   " take up to ten minutes, please be patient." | ||||
|             width: 500 | ||||
|             width: 200 | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -28,8 +28,8 @@ Page | ||||
|                 id: logo | ||||
|                 anchors.horizontalCenter: parent.horizontalCenter | ||||
|                 anchors.top: parent.top | ||||
|                 anchors.topMargin: 50 | ||||
|                 height: 250 | ||||
|                 anchors.topMargin: 10 | ||||
|                 height: 50 | ||||
|                 fillMode: Image.PreserveAspectFit | ||||
|                 source: "file:///usr/share/calamares/branding/default-mobile/logo.png" | ||||
|             } | ||||
| @@ -37,7 +37,7 @@ Page | ||||
|                 id: mainText | ||||
|                 anchors.horizontalCenter: parent.horizontalCenter | ||||
|                 anchors.top: logo.bottom | ||||
|                 anchors.topMargin: 50 | ||||
|                 anchors.topMargin: 10 | ||||
|                 horizontalAlignment: Text.AlignRight | ||||
|                 text: "You are about to install<br>" + | ||||
|                       "<b>" + config.osName + | ||||
| @@ -46,16 +46,16 @@ Page | ||||
|                       "<b>" + config.userInterface + "</b><br>" + | ||||
|                       "architecture " + | ||||
|                       "<b>" + config.arch + "</b><br>" + | ||||
|                       "on your " + | ||||
|                       "on your <br>" + | ||||
|                       "<b>" + config.device + "</b><br>" | ||||
|                 width: 500 | ||||
|                 width: 200 | ||||
|             } | ||||
|  | ||||
|             Button { | ||||
|                 anchors.horizontalCenter: parent.horizontalCenter | ||||
|                 anchors.top: mainText.bottom | ||||
|                 anchors.topMargin: 50 | ||||
|                 width: 500 | ||||
|                 anchors.topMargin: 10 | ||||
|                 width: 200 | ||||
|  | ||||
|                 text: qsTr("Continue") | ||||
|                 onClicked: navNext() | ||||
|   | ||||
| @@ -1,15 +0,0 @@ | ||||
| # 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 | ||||
| ) | ||||
| @@ -1,117 +0,0 @@ | ||||
| /* === 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 ) ); | ||||
| } | ||||
| @@ -1,59 +0,0 @@ | ||||
| /* === 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 | ||||
| @@ -1,38 +0,0 @@ | ||||
| /* === 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(); | ||||
| } | ||||
| @@ -1,48 +0,0 @@ | ||||
| /* === 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 | ||||
| @@ -1,86 +0,0 @@ | ||||
| /* === 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 ) ); | ||||
|     } | ||||
| } | ||||
| @@ -1,35 +0,0 @@ | ||||
| /* === 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 | ||||
| @@ -1,130 +0,0 @@ | ||||
| /* === 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 >(); ) | ||||
| @@ -1,50 +0,0 @@ | ||||
| /* === 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 | ||||
| @@ -1,101 +0,0 @@ | ||||
| /* === 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 ) ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,36 +0,0 @@ | ||||
| /* === 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 | ||||
| @@ -1,2 +0,0 @@ | ||||
| --- | ||||
| rootMountPoint: /tmp/fstest | ||||
| @@ -1,4 +0,0 @@ | ||||
| --- | ||||
| source: /tmp/src.fsa | ||||
| sourcefs: fsarchive | ||||
| destination: "/calasrc" | ||||
| @@ -1,39 +0,0 @@ | ||||
| # 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: "/" | ||||
| @@ -1,19 +0,0 @@ | ||||
| # 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