diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..cbf236645 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1 @@ +18fef8dfe5d926ec0bc979562553adf4db8db2e9 diff --git a/.github/workflows/nightly-debian.yml b/.github/workflows/nightly-debian.yml index 433df748b..9d3fc4d4d 100644 --- a/.github/workflows/nightly-debian.yml +++ b/.github/workflows/nightly-debian.yml @@ -34,11 +34,13 @@ jobs: with: token: ${{ secrets.MATRIX_TOKEN }} room: ${{ secrets.MATRIX_ROOM }} - message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}" + message: | + OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }} - name: "notify: fail" if: ${{ failure() && github.repository == 'calamares/calamares' }} uses: calamares/actions/matrix-notify@v4 with: token: ${{ secrets.MATRIX_TOKEN }} room: ${{ secrets.MATRIX_ROOM }} - message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}" + message: | + FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }} diff --git a/.github/workflows/nightly-neon.yml b/.github/workflows/nightly-neon.yml index d2930fa36..b0c576721 100644 --- a/.github/workflows/nightly-neon.yml +++ b/.github/workflows/nightly-neon.yml @@ -28,6 +28,22 @@ jobs: - name: "build" id: build uses: calamares/actions/generic-build@v4 + - name: "notify: ok" + if: ${{ success() && github.repository == 'calamares/calamares' }} + uses: calamares/actions/matrix-notify@v4 + with: + token: ${{ secrets.MATRIX_TOKEN }} + room: ${{ secrets.MATRIX_ROOM }} + message: | + OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }} + - name: "notify: fail" + if: ${{ failure() && github.repository == 'calamares/calamares' }} + uses: calamares/actions/matrix-notify@v4 + with: + token: ${{ secrets.MATRIX_TOKEN }} + room: ${{ secrets.MATRIX_ROOM }} + message: | + FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }} - name: "Calamares: archive" working-directory: ${{ env.BUILDDIR }} run: | @@ -39,18 +55,4 @@ jobs: name: calamares-tarball path: ${{ env.BUILDDIR }}/calamares.tar.gz if-no-files-found: error - retention-days: 3 - - name: "notify: ok" - if: ${{ success() && github.repository == 'calamares/calamares' }} - uses: calamares/actions/matrix-notify@v4 - with: - token: ${{ secrets.MATRIX_TOKEN }} - room: ${{ secrets.MATRIX_ROOM }} - message: "OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}" - - name: "notify: fail" - if: ${{ failure() && github.repository == 'calamares/calamares' }} - uses: calamares/actions/matrix-notify@v4 - with: - token: ${{ secrets.MATRIX_TOKEN }} - room: ${{ secrets.MATRIX_ROOM }} - message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}" + retention-days: 7 diff --git a/.github/workflows/nightly-opensuse.yml b/.github/workflows/nightly-opensuse.yml index 2979c56b6..717cabe66 100644 --- a/.github/workflows/nightly-opensuse.yml +++ b/.github/workflows/nightly-opensuse.yml @@ -35,11 +35,12 @@ jobs: token: ${{ secrets.MATRIX_TOKEN }} room: ${{ secrets.MATRIX_ROOM }} message: | - OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}" + OK ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }} - name: "notify: fail" if: ${{ failure() && github.repository == 'calamares/calamares' }} uses: calamares/actions/matrix-notify@v4 with: token: ${{ secrets.MATRIX_TOKEN }} room: ${{ secrets.MATRIX_ROOM }} - message: "FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }}" + message: | + FAIL ${{ github.workflow }} in ${{ github.repository }} ${{ steps.build.outputs.git-summary }} diff --git a/CHANGES-3.2 b/CHANGES-3.2 index ffc8e0010..c590fe13f 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -8,15 +8,41 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. -# 3.2.56 (unreleased) # +# 3.2.57 (unreleased) # This release contains contributions from (alphabetically by first name): - - Victor Fuentes (new contributor! Welcome!) + - Arjen Balfoort (new contributor! Welcome!) + - Victor Fuentes ## Core ## - No core changes yet ## Modules ## + - *fstab* and *luksbootkeyfile* have better support for an **un**encrypted + `/boot` partition. #1931 (thanks Arjen) + - *packagechooser* and *packagechooserq* can now be given a custom name + in the side-panel. #1932 (thanks Victor) + + +# 3.2.56 (2022-04-22) # + +As of this release, Calamares 3.2 development is winding down. The +reason is simple: systems where the backwards-compatibility of Calamares +3.2 is important are becoming increasingly difficult to work with +for **other** reasons. Foremost among these are deprecated versions +of dependencies and tools. Calamares 3.2 branch remains open for +bugfixes and will see a few more releases, but development is now +shifting wholesale to the newer generation. + +This release contains contributions from (alphabetically by first name): + - Victor Fuentes (new contributor! Welcome!) + +## Core ## + - Changes in git forced some changes on the CI tooling. + +## Modules ## + - *locale* showed the wrong timezone for Dhaka, although it configured + the correct one. #1929 - *users* module sets global storage key *fullname* to the full name of the user (e.g. what is entered in the "your full name" box on the users page). #1923 (Thanks Victor) diff --git a/CMakeLists.txt b/CMakeLists.txt index 472c17fb0..a11f683d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ # TODO:3.3: Require CMake 3.12 cmake_minimum_required( VERSION 3.3 FATAL_ERROR ) project( CALAMARES - VERSION 3.2.56 + VERSION 3.2.57 LANGUAGES C CXX ) diff --git a/lang/calamares_en.ts b/lang/calamares_en.ts index 25da31891..f3d84c625 100644 --- a/lang/calamares_en.ts +++ b/lang/calamares_en.ts @@ -862,52 +862,52 @@ The installer will quit and all changes will be lost. <h1>Welcome to the %1 installer</h1> - + Your username is too long. Your username is too long. - + '%1' is not allowed as username. '%1' is not allowed as username. - + Your username must start with a lowercase letter or underscore. Your username must start with a lowercase letter or underscore. - + Only lowercase letters, numbers, underscore and hyphen are allowed. Only lowercase letters, numbers, underscore and hyphen are allowed. - + Your hostname is too short. Your hostname is too short. - + Your hostname is too long. Your hostname is too long. - + '%1' is not allowed as hostname. '%1' is not allowed as hostname. - + Only letters, numbers, underscore and hyphen are allowed. Only letters, numbers, underscore and hyphen are allowed. - + Your passwords do not match! Your passwords do not match! - + OK! OK! @@ -2487,7 +2487,7 @@ The installer will quit and all changes will be lost. Unknown error - + Password is empty Password is empty @@ -3421,29 +3421,29 @@ Output: SetHostNameJob - + Set hostname %1 Set hostname %1 - + Set hostname <strong>%1</strong>. Set hostname <strong>%1</strong>. - + Setting hostname %1. Setting hostname %1. - - + + Internal Error Internal Error - - + + Cannot write hostname to target system Cannot write hostname to target system @@ -3645,18 +3645,18 @@ Output: SetupGroupsJob - + Preparing groups. Preparing groups. - - + + Could not create groups in target system Could not create groups in target system - + These groups are missing in the target system: %1 These groups are missing in the target system: %1 @@ -3669,12 +3669,12 @@ Output: Configure <pre>sudo</pre> users. - + Cannot chmod sudoers file. Cannot chmod sudoers file. - + Cannot create sudoers file for writing. Cannot create sudoers file for writing. @@ -3877,12 +3877,12 @@ Output: UsersPage - + <small>If more than one person will use this computer, you can create multiple accounts after setup.</small> <small>If more than one person will use this computer, you can create multiple accounts after setup.</small> - + <small>If more than one person will use this computer, you can create multiple accounts after installation.</small> <small>If more than one person will use this computer, you can create multiple accounts after installation.</small> diff --git a/lang/calamares_ko.ts b/lang/calamares_ko.ts index 34a32d5ef..bf62fd7d7 100644 --- a/lang/calamares_ko.ts +++ b/lang/calamares_ko.ts @@ -338,12 +338,12 @@ Link copied to clipboard Calamares Initialization Failed - 깔라마레스 초기화 실패 + Calamares 초기화에 실패했습니다 %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - %1 가 설치될 수 없습니다. 깔라마레스가 모든 구성된 모듈을 불러올 수 없었습니다. 이것은 깔라마레스가 배포판에서 사용되는 방식에서 발생한 문제입니다. + %1 가 설치될 수 없습니다. Calamares가 모든 구성된 모듈을 불러올 수 없었습니다. 이것은 Calamares가 배포판에서 사용되는 방식에서 발생한 문제입니다. @@ -1127,7 +1127,7 @@ The installer will quit and all changes will be lost. The installer failed to create partition on disk '%1'. - 디스크 '%1'에 파티션을 생성하지 못했습니다. + 설치 관리자가 디스크 '%1'에 파티션을 생성하지 못했습니다. @@ -1262,7 +1262,7 @@ The installer will quit and all changes will be lost. The installer failed to deactivate a volume group named %1. - %1로 이름 지정된 볼륨 그룹을 비활성화하지 못했습니다. + 설치 관리자가 %1로 이름 지정된 볼륨 그룹을 비활성화하지 못했습니다. @@ -1672,7 +1672,7 @@ The installer will quit and all changes will be lost. has a screen large enough to show the whole installer - 전체 설치 프로그램을 표시할 수 있을 만큼 큰 화면이 있습니다 + 전체 설치 관리자를 표시할 수 있을 만큼 큰 화면이 있습니다 @@ -2835,17 +2835,17 @@ The installer will quit and all changes will be lost. Unsafe partition actions are enabled. - + 안전하지 않은 파티션 작업이 활성화되었습니다. Partitioning is configured to <b>always</b> fail. - + 파티셔닝이 <b>항상</b> 실패하도록 구성되어 있습니다. No partitions will be changed. - + 파티션 없음은 변경될 것입니다. @@ -2905,7 +2905,7 @@ The installer will quit and all changes will be lost. A GPT partition table is the best option for all systems. This installer supports such a setup for BIOS systems too.<br/><br/>To configure a GPT partition table on BIOS, (if not done so already) go back and set the partition table to GPT, next create a 8 MB unformatted partition with the <strong>%2</strong> flag enabled.<br/><br/>An unformatted 8 MB partition is necessary to start %1 on a BIOS system with GPT. - + GPT 파티션 테이블은 모든 시스템에 가장 적합한 옵션입니다. 이 설치 관리자는 BIOS 시스템에 대한 이러한 설정도 지원합니다.<br/><br/>BIOS에서 GPT 파티션 테이블을 구성하려면(아직 수행하지 않은 경우) 돌아가서 파티션 테이블을 GPT로 설정한 다음 <strong>%2</strong> 플래그가 활성화된 8MB의 포맷되지 않은 파티션을 생성하십시오.<br/><br/>GPT가 있는 BIOS 시스템에서 %1을(를) 시작하려면 포맷되지 않은 8MB 파티션이 필요합니다. @@ -3287,7 +3287,7 @@ Output: Calamares cannot start KPMCore for the file-system resize job. - 깔라마레스는 파일 시스템 크기 조정 작업을 위해 KPMCore를 시작할 수 없습니다. + Calamares는 파일 시스템 크기 조정 작업을 위해 KPMCore를 시작할 수 없습니다. @@ -3791,7 +3791,7 @@ Output: Could not configure machine feedback correctly, Calamares error %1. - 시스템 피드백을 정확하게 설정할 수 없습니다, %1 깔라마레스 오류. + 시스템 피드백을 정확하게 설정할 수 없습니다, Calamares의 %1 오류입니다. @@ -4021,7 +4021,7 @@ Output: <h1>Welcome to the Calamares setup program for %1.</h1> - <h1>%1에 대한 깔라마레스 설정 프로그램에 오신 것을 환영합니다.</h1> + <h1>%1용 Calamares 설정 프로그램에 오신 것을 환영합니다.</h1> @@ -4031,7 +4031,7 @@ Output: <h1>Welcome to the Calamares installer for %1.</h1> - <h1>%1을 위한 깔라마레스 설치 관리자에 오신 것을 환영합니다.</h1> + <h1>%1용 Calamares 설치 관리자에 오신 것을 환영합니다.</h1> @@ -4095,7 +4095,7 @@ Output: No partitions are available for ZFS. - ZFS에 사용할 수 있는 파티션이 없습니다. + 파티션 없음을 ZFS로 사용할 수 있습니다. @@ -4525,7 +4525,7 @@ Output: About - 깔라마레스에 대하여 + Calamares에 대하여 diff --git a/lang/calamares_tr_TR.ts b/lang/calamares_tr_TR.ts index 91c8c718a..b899e02f2 100644 --- a/lang/calamares_tr_TR.ts +++ b/lang/calamares_tr_TR.ts @@ -2850,17 +2850,17 @@ Sistem güç kaynağına bağlı değil. Unsafe partition actions are enabled. - + Güvenli olmayan bölümleme eylemi etkinleştirildi. Partitioning is configured to <b>always</b> fail. - + Bölümleme, <b>her zaman</b> başarısız olacak şekilde yapılandırılmıştır. No partitions will be changed. - + Hiçbir bölüm değiştirilmeyecek. @@ -2920,7 +2920,7 @@ Sistem güç kaynağına bağlı değil. A GPT partition table is the best option for all systems. This installer supports such a setup for BIOS systems too.<br/><br/>To configure a GPT partition table on BIOS, (if not done so already) go back and set the partition table to GPT, next create a 8 MB unformatted partition with the <strong>%2</strong> flag enabled.<br/><br/>An unformatted 8 MB partition is necessary to start %1 on a BIOS system with GPT. - + GPT bölüm tablosu, tüm sistemler için en iyi seçenektir. Bu yükleyici, BIOS sistemleri için de böyle bir kurulumu destekler. <br/><br/>BIOS'ta bir GPT bölüm tablosu yapılandırmak için (önceden yapılmadıysa) geri dönün ve bölüm tablosunu GPT olarak ayarlayın, ardından <strong>%2</strong> bayrağı etkinleştirilmiş.<br/><br/> 8 MB biçimlendirilmemiş bölüm oluşturun .GPT' ile BIOS sisteminde %1 başlatmak için biçimlendirilmemiş 8 MB bir bölüm gereklidir. diff --git a/lang/python.pot b/lang/python.pot index 897a6b4de..2396b14dd 100644 --- a/lang/python.pot +++ b/lang/python.pot @@ -2,426 +2,403 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-21 17:21+0100\n" +"POT-Creation-Date: 2022-04-22 11:03+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" "Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: src/modules/initramfscfg/main.py:32 -msgid "Configuring initramfs." -msgstr "Configuring initramfs." - -#: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89 -#: src/modules/fstab/main.py:361 src/modules/fstab/main.py:367 -#: src/modules/fstab/main.py:394 src/modules/networkcfg/main.py:105 -#: src/modules/initcpiocfg/main.py:235 src/modules/initcpiocfg/main.py:239 -#: src/modules/localecfg/main.py:135 src/modules/mount/main.py:229 -#: src/modules/rawfs/main.py:164 src/modules/openrcdmcryptcfg/main.py:72 -#: src/modules/openrcdmcryptcfg/main.py:76 -msgid "Configuration Error" -msgstr "Configuration Error" - -#: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:362 -#: src/modules/initcpiocfg/main.py:236 src/modules/mount/main.py:230 -#: src/modules/rawfs/main.py:165 src/modules/openrcdmcryptcfg/main.py:73 -msgid "No partitions are defined for
{!s}
to use." -msgstr "No partitions are defined for
{!s}
to use." - -#: src/modules/initramfscfg/main.py:90 src/modules/fstab/main.py:368 -#: src/modules/networkcfg/main.py:106 src/modules/initcpiocfg/main.py:240 -#: src/modules/localecfg/main.py:136 src/modules/openrcdmcryptcfg/main.py:77 -msgid "No root mount point is given for
{!s}
to use." -msgstr "No root mount point is given for
{!s}
to use." - #: src/modules/grubcfg/main.py:28 msgid "Configure GRUB." -msgstr "Configure GRUB." - -#: src/modules/bootloader/main.py:43 -msgid "Install bootloader." -msgstr "Install bootloader." - -#: src/modules/bootloader/main.py:614 -msgid "Failed to install grub, no partitions defined in global storage" -msgstr "Failed to install grub, no partitions defined in global storage" - -#: src/modules/bootloader/main.py:782 -msgid "Bootloader installation error" -msgstr "Bootloader installation error" - -#: src/modules/bootloader/main.py:783 -msgid "" -"The bootloader could not be installed. The installation command " -"
{!s}
returned error code {!s}." msgstr "" -"The bootloader could not be installed. The installation command " -"
{!s}
returned error code {!s}." - -#: src/modules/fstab/main.py:29 -msgid "Writing fstab." -msgstr "Writing fstab." - -#: src/modules/fstab/main.py:395 -msgid "No
{!s}
configuration is given for
{!s}
to use." -msgstr "No
{!s}
configuration is given for
{!s}
to use." - -#: src/modules/dracut/main.py:27 -msgid "Creating initramfs with dracut." -msgstr "Creating initramfs with dracut." - -#: src/modules/dracut/main.py:49 -msgid "Failed to run dracut on the target" -msgstr "Failed to run dracut on the target" - -#: src/modules/dracut/main.py:50 src/modules/mkinitfs/main.py:50 -msgid "The exit code was {}" -msgstr "The exit code was {}" - -#: src/modules/displaymanager/main.py:524 -msgid "Cannot write KDM configuration file" -msgstr "Cannot write KDM configuration file" - -#: src/modules/displaymanager/main.py:525 -msgid "KDM config file {!s} does not exist" -msgstr "KDM config file {!s} does not exist" - -#: src/modules/displaymanager/main.py:586 -msgid "Cannot write LXDM configuration file" -msgstr "Cannot write LXDM configuration file" - -#: src/modules/displaymanager/main.py:587 -msgid "LXDM config file {!s} does not exist" -msgstr "LXDM config file {!s} does not exist" - -#: src/modules/displaymanager/main.py:670 -msgid "Cannot write LightDM configuration file" -msgstr "Cannot write LightDM configuration file" - -#: src/modules/displaymanager/main.py:671 -msgid "LightDM config file {!s} does not exist" -msgstr "LightDM config file {!s} does not exist" - -#: src/modules/displaymanager/main.py:745 -msgid "Cannot configure LightDM" -msgstr "Cannot configure LightDM" - -#: src/modules/displaymanager/main.py:746 -msgid "No LightDM greeter installed." -msgstr "No LightDM greeter installed." - -#: src/modules/displaymanager/main.py:777 -msgid "Cannot write SLIM configuration file" -msgstr "Cannot write SLIM configuration file" - -#: src/modules/displaymanager/main.py:778 -msgid "SLIM config file {!s} does not exist" -msgstr "SLIM config file {!s} does not exist" - -#: src/modules/displaymanager/main.py:991 -msgid "No display managers selected for the displaymanager module." -msgstr "No display managers selected for the displaymanager module." - -#: src/modules/displaymanager/main.py:992 -msgid "" -"The displaymanagers list is empty or undefined in both globalstorage and " -"displaymanager.conf." -msgstr "" -"The displaymanagers list is empty or undefined in both globalstorage and " -"displaymanager.conf." - -#: src/modules/displaymanager/main.py:1074 -msgid "Display manager configuration was incomplete" -msgstr "Display manager configuration was incomplete" - -#: src/modules/services-openrc/main.py:29 -msgid "Configure OpenRC services" -msgstr "Configure OpenRC services" - -#: src/modules/services-openrc/main.py:57 -msgid "Cannot add service {name!s} to run-level {level!s}." -msgstr "Cannot add service {name!s} to run-level {level!s}." - -#: src/modules/services-openrc/main.py:59 -msgid "Cannot remove service {name!s} from run-level {level!s}." -msgstr "Cannot remove service {name!s} from run-level {level!s}." - -#: src/modules/services-openrc/main.py:61 -msgid "" -"Unknown service-action {arg!s} for service {name!s} in run-" -"level {level!s}." -msgstr "" -"Unknown service-action {arg!s} for service {name!s} in run-" -"level {level!s}." - -#: src/modules/services-openrc/main.py:93 -#: src/modules/services-systemd/main.py:59 -msgid "Cannot modify service" -msgstr "Cannot modify service" - -#: src/modules/services-openrc/main.py:94 -msgid "" -"rc-update {arg!s} call in chroot returned error code {num!s}." -msgstr "" -"rc-update {arg!s} call in chroot returned error code {num!s}." - -#: src/modules/services-openrc/main.py:101 -msgid "Target runlevel does not exist" -msgstr "Target runlevel does not exist" - -#: src/modules/services-openrc/main.py:102 -msgid "" -"The path for runlevel {level!s} is {path!s}, which does not " -"exist." -msgstr "" -"The path for runlevel {level!s} is {path!s}, which does not " -"exist." - -#: src/modules/services-openrc/main.py:110 -msgid "Target service does not exist" -msgstr "Target service does not exist" - -#: src/modules/services-openrc/main.py:111 -msgid "" -"The path for service {name!s} is {path!s}, which does not " -"exist." -msgstr "" -"The path for service {name!s} is {path!s}, which does not " -"exist." - -#: src/modules/networkcfg/main.py:29 -msgid "Saving network configuration." -msgstr "Saving network configuration." - -#: src/modules/packages/main.py:54 src/modules/packages/main.py:65 -#: src/modules/packages/main.py:75 -msgid "Install packages." -msgstr "Install packages." - -#: src/modules/packages/main.py:63 -#, python-format -msgid "Processing packages (%(count)d / %(total)d)" -msgstr "Processing packages (%(count)d / %(total)d)" - -#: src/modules/packages/main.py:68 -#, python-format -msgid "Installing one package." -msgid_plural "Installing %(num)d packages." -msgstr[0] "Installing one package." -msgstr[1] "Installing %(num)d packages." - -#: src/modules/packages/main.py:71 -#, python-format -msgid "Removing one package." -msgid_plural "Removing %(num)d packages." -msgstr[0] "Removing one package." -msgstr[1] "Removing %(num)d packages." - -#: src/modules/packages/main.py:725 src/modules/packages/main.py:737 -#: src/modules/packages/main.py:765 -msgid "Package Manager error" -msgstr "Package Manager error" - -#: src/modules/packages/main.py:726 -msgid "" -"The package manager could not prepare updates. The command
{!s}
" -"returned error code {!s}." -msgstr "" -"The package manager could not prepare updates. The command
{!s}
" -"returned error code {!s}." - -#: src/modules/packages/main.py:738 -msgid "" -"The package manager could not update the system. The command
{!s}
" -" returned error code {!s}." -msgstr "" -"The package manager could not update the system. The command
{!s}
" -" returned error code {!s}." - -#: src/modules/packages/main.py:766 -msgid "" -"The package manager could not make changes to the installed system. The " -"command
{!s}
returned error code {!s}." -msgstr "" -"The package manager could not make changes to the installed system. The " -"command
{!s}
returned error code {!s}." - -#: src/modules/plymouthcfg/main.py:27 -msgid "Configure Plymouth theme" -msgstr "Configure Plymouth theme" - -#: src/modules/initcpiocfg/main.py:28 -msgid "Configuring mkinitcpio." -msgstr "Configuring mkinitcpio." - -#: src/modules/localecfg/main.py:30 -msgid "Configuring locales." -msgstr "Configuring locales." #: src/modules/mount/main.py:42 msgid "Mounting partitions." -msgstr "Mounting partitions." +msgstr "" #: src/modules/mount/main.py:88 src/modules/mount/main.py:124 msgid "Internal error mounting zfs datasets" -msgstr "Internal error mounting zfs datasets" +msgstr "" #: src/modules/mount/main.py:100 msgid "Failed to import zpool" -msgstr "Failed to import zpool" +msgstr "" #: src/modules/mount/main.py:116 msgid "Failed to unlock zpool" -msgstr "Failed to unlock zpool" +msgstr "" #: src/modules/mount/main.py:133 src/modules/mount/main.py:138 msgid "Failed to set zfs mountpoint" -msgstr "Failed to set zfs mountpoint" +msgstr "" + +#: src/modules/mount/main.py:229 src/modules/initcpiocfg/main.py:235 +#: src/modules/initcpiocfg/main.py:239 src/modules/rawfs/main.py:164 +#: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89 +#: src/modules/openrcdmcryptcfg/main.py:72 +#: src/modules/openrcdmcryptcfg/main.py:76 src/modules/fstab/main.py:361 +#: src/modules/fstab/main.py:367 src/modules/fstab/main.py:394 +#: src/modules/localecfg/main.py:140 src/modules/networkcfg/main.py:105 +msgid "Configuration Error" +msgstr "" + +#: src/modules/mount/main.py:230 src/modules/initcpiocfg/main.py:236 +#: src/modules/rawfs/main.py:165 src/modules/initramfscfg/main.py:86 +#: src/modules/openrcdmcryptcfg/main.py:73 src/modules/fstab/main.py:362 +msgid "No partitions are defined for
{!s}
to use." +msgstr "" #: src/modules/mount/main.py:253 msgid "zfs mounting error" -msgstr "zfs mounting error" - -#: src/modules/rawfs/main.py:26 -msgid "Installing data." -msgstr "Installing data." - -#: src/modules/dummypython/main.py:35 -msgid "Dummy python job." -msgstr "Dummy python job." - -#: src/modules/dummypython/main.py:37 src/modules/dummypython/main.py:93 -#: src/modules/dummypython/main.py:94 -msgid "Dummy python step {}" -msgstr "Dummy python step {}" - -#: src/modules/hwclock/main.py:26 -msgid "Setting hardware clock." -msgstr "Setting hardware clock." - -#: src/modules/openrcdmcryptcfg/main.py:26 -msgid "Configuring OpenRC dmcrypt service." -msgstr "Configuring OpenRC dmcrypt service." +msgstr "" #: src/modules/services-systemd/main.py:26 msgid "Configure systemd services" -msgstr "Configure systemd services" +msgstr "" + +#: src/modules/services-systemd/main.py:59 +#: src/modules/services-openrc/main.py:93 +msgid "Cannot modify service" +msgstr "" #: src/modules/services-systemd/main.py:60 msgid "" "systemctl {arg!s} call in chroot returned error code {num!s}." msgstr "" -"systemctl {arg!s} call in chroot returned error code {num!s}." #: src/modules/services-systemd/main.py:63 #: src/modules/services-systemd/main.py:69 msgid "Cannot enable systemd service {name!s}." -msgstr "Cannot enable systemd service {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:65 msgid "Cannot enable systemd target {name!s}." -msgstr "Cannot enable systemd target {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:67 msgid "Cannot enable systemd timer {name!s}." -msgstr "Cannot enable systemd timer {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:71 msgid "Cannot disable systemd target {name!s}." -msgstr "Cannot disable systemd target {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:73 msgid "Cannot mask systemd unit {name!s}." -msgstr "Cannot mask systemd unit {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:75 msgid "" -"Unknown systemd commands {command!s} and " -"{suffix!s} for unit {name!s}." +"Unknown systemd commands {command!s} and {suffix!s} for unit {name!s}." msgstr "" -"Unknown systemd commands {command!s} and " -"{suffix!s} for unit {name!s}." - -#: src/modules/mkinitfs/main.py:27 -msgid "Creating initramfs with mkinitfs." -msgstr "Creating initramfs with mkinitfs." - -#: src/modules/mkinitfs/main.py:49 -msgid "Failed to run mkinitfs on the target" -msgstr "Failed to run mkinitfs on the target" #: src/modules/unpackfs/main.py:34 msgid "Filling up filesystems." -msgstr "Filling up filesystems." +msgstr "" #: src/modules/unpackfs/main.py:254 msgid "rsync failed with error code {}." -msgstr "rsync failed with error code {}." +msgstr "" #: src/modules/unpackfs/main.py:299 msgid "Unpacking image {}/{}, file {}/{}" -msgstr "Unpacking image {}/{}, file {}/{}" +msgstr "" #: src/modules/unpackfs/main.py:314 msgid "Starting to unpack {}" -msgstr "Starting to unpack {}" +msgstr "" #: src/modules/unpackfs/main.py:323 src/modules/unpackfs/main.py:467 msgid "Failed to unpack image \"{}\"" -msgstr "Failed to unpack image \"{}\"" +msgstr "" #: src/modules/unpackfs/main.py:430 msgid "No mount point for root partition" -msgstr "No mount point for root partition" +msgstr "" #: src/modules/unpackfs/main.py:431 msgid "globalstorage does not contain a \"rootMountPoint\" key." -msgstr "globalstorage does not contain a \"rootMountPoint\" key." +msgstr "" #: src/modules/unpackfs/main.py:434 msgid "Bad mount point for root partition" -msgstr "Bad mount point for root partition" +msgstr "" #: src/modules/unpackfs/main.py:435 msgid "rootMountPoint is \"{}\", which does not exist." -msgstr "rootMountPoint is \"{}\", which does not exist." +msgstr "" #: src/modules/unpackfs/main.py:439 src/modules/unpackfs/main.py:455 #: src/modules/unpackfs/main.py:459 src/modules/unpackfs/main.py:465 #: src/modules/unpackfs/main.py:480 msgid "Bad unpackfs configuration" -msgstr "Bad unpackfs configuration" +msgstr "" #: src/modules/unpackfs/main.py:440 msgid "There is no configuration information." -msgstr "There is no configuration information." +msgstr "" #: src/modules/unpackfs/main.py:456 msgid "The filesystem for \"{}\" ({}) is not supported by your current kernel" -msgstr "The filesystem for \"{}\" ({}) is not supported by your current kernel" +msgstr "" #: src/modules/unpackfs/main.py:460 msgid "The source filesystem \"{}\" does not exist" -msgstr "The source filesystem \"{}\" does not exist" +msgstr "" #: src/modules/unpackfs/main.py:466 msgid "" "Failed to find unsquashfs, make sure you have the squashfs-tools package " "installed." msgstr "" -"Failed to find unsquashfs, make sure you have the squashfs-tools package " -"installed." #: src/modules/unpackfs/main.py:481 msgid "The destination \"{}\" in the target system is not a directory" -msgstr "The destination \"{}\" in the target system is not a directory" +msgstr "" + +#: src/modules/displaymanager/main.py:524 +msgid "Cannot write KDM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:525 +msgid "KDM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:586 +msgid "Cannot write LXDM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:587 +msgid "LXDM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:670 +msgid "Cannot write LightDM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:671 +msgid "LightDM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:745 +msgid "Cannot configure LightDM" +msgstr "" + +#: src/modules/displaymanager/main.py:746 +msgid "No LightDM greeter installed." +msgstr "" + +#: src/modules/displaymanager/main.py:777 +msgid "Cannot write SLIM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:778 +msgid "SLIM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:991 +msgid "No display managers selected for the displaymanager module." +msgstr "" + +#: src/modules/displaymanager/main.py:992 +msgid "" +"The displaymanagers list is empty or undefined in both globalstorage and " +"displaymanager.conf." +msgstr "" + +#: src/modules/displaymanager/main.py:1074 +msgid "Display manager configuration was incomplete" +msgstr "" + +#: src/modules/initcpiocfg/main.py:28 +msgid "Configuring mkinitcpio." +msgstr "" + +#: src/modules/initcpiocfg/main.py:240 src/modules/initramfscfg/main.py:90 +#: src/modules/openrcdmcryptcfg/main.py:77 src/modules/fstab/main.py:368 +#: src/modules/localecfg/main.py:141 src/modules/networkcfg/main.py:106 +msgid "No root mount point is given for
{!s}
to use." +msgstr "" + +#: src/modules/rawfs/main.py:26 +msgid "Installing data." +msgstr "" + +#: src/modules/services-openrc/main.py:29 +msgid "Configure OpenRC services" +msgstr "" + +#: src/modules/services-openrc/main.py:57 +msgid "Cannot add service {name!s} to run-level {level!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:59 +msgid "Cannot remove service {name!s} from run-level {level!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:61 +msgid "" +"Unknown service-action {arg!s} for service {name!s} in run-" +"level {level!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:94 +msgid "" +"rc-update {arg!s} call in chroot returned error code {num!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:101 +msgid "Target runlevel does not exist" +msgstr "" + +#: src/modules/services-openrc/main.py:102 +msgid "" +"The path for runlevel {level!s} is {path!s}, which does not " +"exist." +msgstr "" + +#: src/modules/services-openrc/main.py:110 +msgid "Target service does not exist" +msgstr "" + +#: src/modules/services-openrc/main.py:111 +msgid "" +"The path for service {name!s} is {path!s}, which does not exist." +msgstr "" + +#: src/modules/plymouthcfg/main.py:27 +msgid "Configure Plymouth theme" +msgstr "" + +#: src/modules/packages/main.py:54 src/modules/packages/main.py:65 +#: src/modules/packages/main.py:75 +msgid "Install packages." +msgstr "" + +#: src/modules/packages/main.py:63 +#, python-format +msgid "Processing packages (%(count)d / %(total)d)" +msgstr "" + +#: src/modules/packages/main.py:68 +#, python-format +msgid "Installing one package." +msgid_plural "Installing %(num)d packages." +msgstr[0] "" +msgstr[1] "" + +#: src/modules/packages/main.py:71 +#, python-format +msgid "Removing one package." +msgid_plural "Removing %(num)d packages." +msgstr[0] "" +msgstr[1] "" + +#: src/modules/packages/main.py:725 src/modules/packages/main.py:737 +#: src/modules/packages/main.py:765 +msgid "Package Manager error" +msgstr "" + +#: src/modules/packages/main.py:726 +msgid "" +"The package manager could not prepare updates. The command
{!s}
" +"returned error code {!s}." +msgstr "" + +#: src/modules/packages/main.py:738 +msgid "" +"The package manager could not update the system. The command
{!s}
" +"returned error code {!s}." +msgstr "" + +#: src/modules/packages/main.py:766 +msgid "" +"The package manager could not make changes to the installed system. The " +"command
{!s}
returned error code {!s}." +msgstr "" + +#: src/modules/bootloader/main.py:43 +msgid "Install bootloader." +msgstr "" + +#: src/modules/bootloader/main.py:614 +msgid "Failed to install grub, no partitions defined in global storage" +msgstr "" + +#: src/modules/bootloader/main.py:782 +msgid "Bootloader installation error" +msgstr "" + +#: src/modules/bootloader/main.py:783 +msgid "" +"The bootloader could not be installed. The installation command
{!s} returned error code {!s}."
+msgstr ""
+
+#: src/modules/hwclock/main.py:26
+msgid "Setting hardware clock."
+msgstr ""
+
+#: src/modules/mkinitfs/main.py:27
+msgid "Creating initramfs with mkinitfs."
+msgstr ""
+
+#: src/modules/mkinitfs/main.py:49
+msgid "Failed to run mkinitfs on the target"
+msgstr ""
+
+#: src/modules/mkinitfs/main.py:50 src/modules/dracut/main.py:50
+msgid "The exit code was {}"
+msgstr ""
+
+#: src/modules/dracut/main.py:27
+msgid "Creating initramfs with dracut."
+msgstr ""
+
+#: src/modules/dracut/main.py:49
+msgid "Failed to run dracut on the target"
+msgstr ""
+
+#: src/modules/initramfscfg/main.py:32
+msgid "Configuring initramfs."
+msgstr ""
+
+#: src/modules/openrcdmcryptcfg/main.py:26
+msgid "Configuring OpenRC dmcrypt service."
+msgstr ""
+
+#: src/modules/fstab/main.py:29
+msgid "Writing fstab."
+msgstr ""
+
+#: src/modules/fstab/main.py:395
+msgid "No 
{!s}
configuration is given for
{!s}
to use." +msgstr "" + +#: src/modules/dummypython/main.py:35 +msgid "Dummy python job." +msgstr "" + +#: src/modules/dummypython/main.py:37 src/modules/dummypython/main.py:93 +#: src/modules/dummypython/main.py:94 +msgid "Dummy python step {}" +msgstr "" + +#: src/modules/localecfg/main.py:31 +msgid "Configuring locales." +msgstr "" + +#: src/modules/networkcfg/main.py:29 +msgid "Saving network configuration." +msgstr "" diff --git a/lang/python/ko/LC_MESSAGES/python.po b/lang/python/ko/LC_MESSAGES/python.po index d5bb1fa76..e8e751c9c 100644 --- a/lang/python/ko/LC_MESSAGES/python.po +++ b/lang/python/ko/LC_MESSAGES/python.po @@ -5,7 +5,7 @@ # # Translators: # Ji-Hyeon Gim , 2018 -# Junghee Lee , 2022 +# JungHee Lee , 2022 # #, fuzzy msgid "" @@ -14,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-03-21 17:21+0100\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: Junghee Lee , 2022\n" +"Last-Translator: JungHee Lee , 2022\n" "Language-Team: Korean (https://www.transifex.com/calamares/teams/20061/ko/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -58,7 +58,7 @@ msgstr "부트로더 설치." #: src/modules/bootloader/main.py:614 msgid "Failed to install grub, no partitions defined in global storage" -msgstr "grub을 설치하지 못했습니다. 전역 저장소에 파티션이 정의되어 있지 않습니다" +msgstr "grub을 설치하지 못했습니다. 파티션 없음이 전역 저장소에 정의되었습니다" #: src/modules/bootloader/main.py:782 msgid "Bootloader installation error" diff --git a/src/modules/fstab/main.py b/src/modules/fstab/main.py old mode 100644 new mode 100755 index 9bc427b13..1cfb5e660 --- a/src/modules/fstab/main.py +++ b/src/modules/fstab/main.py @@ -158,11 +158,23 @@ class FstabGenerator(object): if not mapper_name or not luks_uuid: return None + password = "/crypto_keyfile.bin" + crypttab_options = self.crypttab_options + + # Set crypttab password for partition to none and remove crypttab options + # on root partition when /boot is unencrypted + if partition["mountPoint"] == "/": + if any([p["mountPoint"] == "/boot" + and "luksMapperName" not in p + for p in self.partitions]): + password = "none" + crypttab_options = "" + return dict( name=mapper_name, device="UUID=" + luks_uuid, - password="/crypto_keyfile.bin", - options=self.crypttab_options, + password=password, + options=crypttab_options, ) def print_crypttab_line(self, dct, file=None): @@ -220,7 +232,7 @@ class FstabGenerator(object): # Some "fs" names need special handling in /etc/fstab, so remap them. filesystem = partition["fs"].lower() filesystem = FS_MAP.get(filesystem, filesystem) - has_luks = "luksMapperName" in partition + luks_mapper_name = partition.get("luksMapperName", None) mount_point = partition["mountPoint"] disk_name = disk_name_for_partition(partition) is_ssd = disk_name in self.ssd_disks @@ -263,13 +275,19 @@ class FstabGenerator(object): if filesystem == "btrfs" and partition.get("subvol",None): options = "subvol={},".format(partition["subvol"]) + options - if has_luks: - device = "/dev/mapper/" + partition["luksMapperName"] + device = None + if luks_mapper_name: + device = "/dev/mapper/" + luks_mapper_name elif partition["uuid"]: device = "UUID=" + partition["uuid"] else: device = partition["device"] + if not device: + # TODO: we get here when the user mounted a previously encrypted partition + # This should be catched early in the process + return None + return dict(device=device, mount_point=mount_point, fs=filesystem, diff --git a/src/modules/keyboardq/keyboardq.qml b/src/modules/keyboardq/keyboardq.qml index 1d59cf30e..be96ec85a 100644 --- a/src/modules/keyboardq/keyboardq.qml +++ b/src/modules/keyboardq/keyboardq.qml @@ -1,6 +1,6 @@ /* === This file is part of Calamares - === * - * SPDX-FileCopyrightText: 2020 - 2021 Anke Boersma + * SPDX-FileCopyrightText: 2020 - 2022 Anke Boersma * SPDX-License-Identifier: GPL-3.0-or-later * * Calamares is Free Software: see the License-Identifier above. @@ -137,6 +137,7 @@ Item { hoverEnabled: true width: parent.width + height: 18 highlighted: ListView.isCurrentItem RowLayout { @@ -216,6 +217,7 @@ Item { delegate: ItemDelegate { hoverEnabled: true width: parent.width + height: 18 highlighted: ListView.isCurrentItem RowLayout { diff --git a/src/modules/locale/images/timezone_5.5.png b/src/modules/locale/images/timezone_5.5.png index 78c972fab..172ad8127 100644 Binary files a/src/modules/locale/images/timezone_5.5.png and b/src/modules/locale/images/timezone_5.5.png differ diff --git a/src/modules/locale/images/timezone_8.0.png b/src/modules/locale/images/timezone_8.0.png index ee5095a26..6db98f18f 100644 Binary files a/src/modules/locale/images/timezone_8.0.png and b/src/modules/locale/images/timezone_8.0.png differ diff --git a/src/modules/localecfg/main.py b/src/modules/localecfg/main.py index 8f0edcd17..9cf593017 100644 --- a/src/modules/localecfg/main.py +++ b/src/modules/localecfg/main.py @@ -17,6 +17,7 @@ import os import re import shutil + import libcalamares import gettext @@ -71,8 +72,12 @@ def rewrite_locale_gen(srcfilename, destfilename, locale_conf): # Get entire source-file contents text = [] - with open(srcfilename, "r") as gen: - text = gen.readlines() + try: + with open(srcfilename, "r") as gen: + text = gen.readlines() + except FileNotFoundError: + # That's ok, the file doesn't exist so assume empty + pass # we want unique values, so locale_values should have 1 or 2 items locale_values = set(locale_conf.values()) diff --git a/src/modules/localeq/Offline.qml b/src/modules/localeq/Offline.qml index e5e6b31cf..937554cf6 100644 --- a/src/modules/localeq/Offline.qml +++ b/src/modules/localeq/Offline.qml @@ -1,6 +1,6 @@ /* === This file is part of Calamares - === * - * SPDX-FileCopyrightText: 2020-2021 Anke Boersma + * SPDX-FileCopyrightText: 2020-2022 Anke Boersma * SPDX-License-Identifier: GPL-3.0-or-later * * Calamares is Free Software: see the License-Identifier above. @@ -72,6 +72,7 @@ Page { hoverEnabled: true width: parent.width + height: 30 highlighted: ListView.isCurrentItem Label { @@ -146,6 +147,7 @@ Page { hoverEnabled: true width: parent.width + height: 30 highlighted: ListView.isCurrentItem Label { diff --git a/src/modules/luksbootkeyfile/CMakeLists.txt b/src/modules/luksbootkeyfile/CMakeLists.txt index 6e98af468..dff682521 100644 --- a/src/modules/luksbootkeyfile/CMakeLists.txt +++ b/src/modules/luksbootkeyfile/CMakeLists.txt @@ -3,7 +3,7 @@ # SPDX-FileCopyrightText: 2020 Adriaan de Groot # SPDX-License-Identifier: BSD-2-Clause # -calamares_add_plugin( luksbootkeyfile +calamares_add_plugin(luksbootkeyfile TYPE job EXPORT_MACRO PLUGINDLLEXPORT_PRO SOURCES @@ -11,3 +11,10 @@ calamares_add_plugin( luksbootkeyfile SHARED_LIB NO_CONFIG ) + +calamares_add_test( + luksbootkeyfiletest + SOURCES + Tests.cpp + LuksBootKeyFileJob.cpp +) diff --git a/src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp b/src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp index 137cb750d..e8dfd4724 100644 --- a/src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp +++ b/src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp @@ -150,26 +150,50 @@ setupLuks( const LuksDevice& d ) } static QVariantList -partitions() +partitionsFromGlobalStorage() { Calamares::GlobalStorage* globalStorage = Calamares::JobQueue::instance()->globalStorage(); return globalStorage->value( QStringLiteral( "partitions" ) ).toList(); } -static bool +/// Checks if the partition (represented by @p map) mounts to the given @p path +STATICTEST bool +hasMountPoint( const QVariantMap& map, const QString& path ) +{ + const auto v = map.value( QStringLiteral( "mountPoint" ) ); + return v.isValid() && QDir::cleanPath( v.toString() ) == path; +} + +STATICTEST bool +isEncrypted( const QVariantMap& map ) +{ + return map.contains( QStringLiteral( "luksMapperName" ) ); +} + +/// Checks for any partition satisfying @p pred +STATICTEST bool +anyPartition( bool ( *pred )( const QVariantMap& ) ) +{ + const auto partitions = partitionsFromGlobalStorage(); + return std::find_if( partitions.cbegin(), + partitions.cend(), + [ &pred ]( const QVariant& partitionVariant ) { return pred( partitionVariant.toMap() ); } ) + != partitions.cend(); +} + +STATICTEST bool hasUnencryptedSeparateBoot() { - const QVariantList partitions = ::partitions(); - for ( const QVariant& partition : partitions ) - { - QVariantMap partitionMap = partition.toMap(); - QString mountPoint = partitionMap.value( QStringLiteral( "mountPoint" ) ).toString(); - if ( QDir::cleanPath( mountPoint ) == QStringLiteral( "/boot" ) ) - { - return !partitionMap.contains( QStringLiteral( "luksMapperName" ) ); - } - } - return false; + return anyPartition( + []( const QVariantMap& partition ) + { return hasMountPoint( partition, QStringLiteral( "/boot" ) ) && !isEncrypted( partition ); } ); +} + +STATICTEST bool +hasEncryptedRoot() +{ + return anyPartition( []( const QVariantMap& partition ) + { return hasMountPoint( partition, QStringLiteral( "/" ) ) && isEncrypted( partition ); } ); } Calamares::JobResult @@ -218,7 +242,8 @@ LuksBootKeyFileJob::exec() } // /boot partition is not encrypted, keyfile must not be used - if ( hasUnencryptedSeparateBoot() ) + // But only if root partition is not encrypted + if ( hasUnencryptedSeparateBoot() && !hasEncryptedRoot() ) { cDebug() << Logger::SubEntry << "/boot partition is not encrypted, skipping keyfile creation."; return Calamares::JobResult::ok(); @@ -241,6 +266,12 @@ LuksBootKeyFileJob::exec() for ( const auto& d : s.devices ) { + // Skip setupLuks for root partition if system has an unencrypted /boot + if ( d.isRoot && hasUnencryptedSeparateBoot() ) + { + continue; + } + if ( !setupLuks( d ) ) return Calamares::JobResult::error( tr( "Encrypted rootfs setup error" ), diff --git a/src/modules/luksbootkeyfile/Tests.cpp b/src/modules/luksbootkeyfile/Tests.cpp new file mode 100644 index 000000000..6b6c7be81 --- /dev/null +++ b/src/modules/luksbootkeyfile/Tests.cpp @@ -0,0 +1,169 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2022 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "utils/Logger.h" + +#include + +#undef STATICTEST +#define STATICTEST extern + +// Implementation details +STATICTEST bool hasMountPoint( const QVariantMap& map, const QString& path ); + +STATICTEST bool isEncrypted( const QVariantMap& map ); + +STATICTEST bool anyPartition( bool ( *pred )( const QVariantMap& ) ); + +STATICTEST bool hasUnencryptedSeparateBoot(); + +STATICTEST bool hasEncryptedRoot(); + +class LuksBootKeyFileTests : public QObject +{ + Q_OBJECT +public: + LuksBootKeyFileTests() {} + ~LuksBootKeyFileTests() override {} + +private Q_SLOTS: + void initTestCase(); + + void testMountPoint(); + void testIsEncrypted(); + void testAnyPartition(); +}; + +void +LuksBootKeyFileTests::initTestCase() +{ + Logger::setupLogLevel( Logger::LOGDEBUG ); + cDebug() << "LuksBootKeyFile test started."; + + if ( !Calamares::JobQueue::instance() ) + { + (void)new Calamares::JobQueue(); + } +} + +void +LuksBootKeyFileTests::testMountPoint() +{ + QVariantMap m; // As if this is a partition data + const QString key = QStringLiteral( "mountPoint" ); + const QString boot = QStringLiteral( "/boot" ); + const QString root = QStringLiteral( "/" ); + + QVERIFY( !hasMountPoint( m, QString() ) ); + QVERIFY( !hasMountPoint( m, boot ) ); + + m.insert( key, boot ); + QVERIFY( hasMountPoint( m, boot ) ); + QVERIFY( !hasMountPoint( m, QString() ) ); + QVERIFY( !hasMountPoint( m, root ) ); + + m.insert( key, root ); + QVERIFY( !hasMountPoint( m, boot ) ); + QVERIFY( !hasMountPoint( m, QString() ) ); + QVERIFY( hasMountPoint( m, root ) ); + + m.remove( key ); + QVERIFY( !hasMountPoint( m, root ) ); +} + +void +LuksBootKeyFileTests::testIsEncrypted() +{ + QVariantMap m; // As if this is a partition data + const QString key = QStringLiteral( "luksMapperName" ); + const QString name = QStringLiteral( "any-name" ); + + QVERIFY( !isEncrypted( m ) ); + + // Even an empty string is considered encrypted + m.insert( key, QString() ); + QVERIFY( isEncrypted( m ) ); + + m.insert( key, name ); + QVERIFY( isEncrypted( m ) ); + + m.insert( key, QString() ); + QVERIFY( isEncrypted( m ) ); + + m.remove( key ); + QVERIFY( !isEncrypted( m ) ); +} + + +void +LuksBootKeyFileTests::testAnyPartition() +{ + // This is kind of annoying: we need to build up + // partition data in GS because the functions we're testing + // go straight to GS. + auto* gs = Calamares::JobQueue::instanceGlobalStorage(); + QVERIFY( gs ); + + const QString partitionsKey = QStringLiteral( "partitions" ); + const QString mountPointKey = QStringLiteral( "mountPoint" ); + const QString boot = QStringLiteral( "/boot" ); + const QString root = QStringLiteral( "/" ); + + QVariantList partitions; + QVariantMap p; + QVERIFY( !gs->contains( partitionsKey ) ); + + // Empty list! + QVERIFY( !anyPartition( []( const QVariantMap& ) { return true; } ) ); + + gs->insert( partitionsKey, partitions ); + QVERIFY( !anyPartition( []( const QVariantMap& ) { return true; } ) ); // Still an empty list + + partitions.append( p ); + QCOMPARE( partitions.count(), 1 ); + gs->insert( partitionsKey, partitions ); + QVERIFY( anyPartition( []( const QVariantMap& ) { return true; } ) ); // Now a one-element list + QVERIFY( !anyPartition( []( const QVariantMap& ) { return false; } ) ); // Now a one-element list + + p.insert( mountPointKey, boot ); + QVERIFY( hasMountPoint( p, boot ) ); + partitions.append( p ); + QCOMPARE( partitions.count(), 2 ); + + // Note that GS is not updated yet, so we expect this to fail + QEXPECT_FAIL( "", "GS not updated", Continue ); + QVERIFY( anyPartition( + []( const QVariantMap& partdata ) + { + cDebug() << partdata; + return hasMountPoint( partdata, QStringLiteral( "/boot" ) ); + } ) ); + + gs->insert( partitionsKey, partitions ); // Update GS + QVERIFY( anyPartition( + []( const QVariantMap& partdata ) + { + cDebug() << partdata; + return hasMountPoint( partdata, QStringLiteral( "/boot" ) ); + } ) ); + QVERIFY( !anyPartition( []( const QVariantMap& partdata ) + { return hasMountPoint( partdata, QStringLiteral( "/" ) ); } ) ); + QVERIFY( !anyPartition( []( const QVariantMap& partdata ) { return hasMountPoint( partdata, QString() ); } ) ); + + QVERIFY( !hasEncryptedRoot() ); + QVERIFY( hasUnencryptedSeparateBoot() ); +} + +QTEST_GUILESS_MAIN( LuksBootKeyFileTests ) + +#include "utils/moc-warnings.h" + +#include "Tests.moc" diff --git a/src/modules/packagechooser/Config.cpp b/src/modules/packagechooser/Config.cpp index 491fe5c25..667621597 100644 --- a/src/modules/packagechooser/Config.cpp +++ b/src/modules/packagechooser/Config.cpp @@ -237,6 +237,12 @@ Config::setPackageChoice( const QString& packageChoice ) emit packageChoiceChanged( m_packageChoice.value_or( QString() ) ); } +QString +Config::prettyName() const +{ + return m_stepName ? m_stepName->get() : tr( "Packages" ); +} + QString Config::prettyStatus() const { @@ -343,4 +349,14 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) cWarning() << "Single-selection QML module must use 'Legacy' method."; } } + + bool labels_ok = false; + auto labels = CalamaresUtils::getSubMap( configurationMap, "labels", labels_ok ); + if ( labels_ok ) + { + if ( labels.contains( "step" ) ) + { + m_stepName = new CalamaresUtils::Locale::TranslatedString( labels, "step" ); + } + } } diff --git a/src/modules/packagechooser/Config.h b/src/modules/packagechooser/Config.h index b04b1c30b..d1b783a8d 100644 --- a/src/modules/packagechooser/Config.h +++ b/src/modules/packagechooser/Config.h @@ -98,6 +98,7 @@ public: QString packageChoice() const { return m_packageChoice.value_or( QString() ); } void setPackageChoice( const QString& packageChoice ); + QString prettyName() const; QString prettyStatus() const; signals: @@ -120,6 +121,7 @@ private: * Reading the property will return an empty QString. */ std::optional< QString > m_packageChoice; + CalamaresUtils::Locale::TranslatedString* m_stepName; // As it appears in the sidebar }; diff --git a/src/modules/packagechooser/PackageChooserViewStep.cpp b/src/modules/packagechooser/PackageChooserViewStep.cpp index 9057004de..c3f2ce6e2 100644 --- a/src/modules/packagechooser/PackageChooserViewStep.cpp +++ b/src/modules/packagechooser/PackageChooserViewStep.cpp @@ -29,7 +29,6 @@ PackageChooserViewStep::PackageChooserViewStep( QObject* parent ) : Calamares::ViewStep( parent ) , m_config( new Config( this ) ) , m_widget( nullptr ) - , m_stepName( nullptr ) { emit nextStatusChanged( false ); } @@ -41,14 +40,13 @@ PackageChooserViewStep::~PackageChooserViewStep() { m_widget->deleteLater(); } - delete m_stepName; } QString PackageChooserViewStep::prettyName() const { - return m_stepName ? m_stepName->get() : tr( "Packages" ); + return m_config->prettyName(); } @@ -139,16 +137,6 @@ PackageChooserViewStep::setConfigurationMap( const QVariantMap& configurationMap m_config->setDefaultId( moduleInstanceKey() ); m_config->setConfigurationMap( configurationMap ); - bool labels_ok = false; - auto labels = CalamaresUtils::getSubMap( configurationMap, "labels", labels_ok ); - if ( labels_ok ) - { - if ( labels.contains( "step" ) ) - { - m_stepName = new CalamaresUtils::Locale::TranslatedString( labels, "step" ); - } - } - if ( m_widget ) { hookupModel(); diff --git a/src/modules/packagechooser/PackageChooserViewStep.h b/src/modules/packagechooser/PackageChooserViewStep.h index 7561f2bd7..76b35aed8 100644 --- a/src/modules/packagechooser/PackageChooserViewStep.h +++ b/src/modules/packagechooser/PackageChooserViewStep.h @@ -50,7 +50,6 @@ private: Config* m_config; PackageChooserPage* m_widget; - CalamaresUtils::Locale::TranslatedString* m_stepName; // As it appears in the sidebar }; CALAMARES_PLUGIN_FACTORY_DECLARATION( PackageChooserViewStepFactory ) diff --git a/src/modules/packagechooserq/PackageChooserQmlViewStep.cpp b/src/modules/packagechooserq/PackageChooserQmlViewStep.cpp index 543c9771d..ae4aa3c48 100644 --- a/src/modules/packagechooserq/PackageChooserQmlViewStep.cpp +++ b/src/modules/packagechooserq/PackageChooserQmlViewStep.cpp @@ -29,7 +29,7 @@ PackageChooserQmlViewStep::PackageChooserQmlViewStep( QObject* parent ) QString PackageChooserQmlViewStep::prettyName() const { - return tr( "Packages" ); + return m_config->prettyName(); } QString diff --git a/src/modules/packagechooserq/packagechooserq.conf b/src/modules/packagechooserq/packagechooserq.conf index 803c6f670..9c1878f34 100644 --- a/src/modules/packagechooserq/packagechooserq.conf +++ b/src/modules/packagechooserq/packagechooserq.conf @@ -42,6 +42,19 @@ # method: legacy +# Human-visible strings in this module. These are all optional. +# The following translated keys are used: +# - *step*, used in the overall progress view (left-hand pane) +# +# Each key can have a [locale] added to it, which is used as +# the translated string for that locale. For the strings +# associated with the "no-selection" item, see *items*, below +# with the explicit item-*id* "". +# +labels: + step: "Packages" + step[nl]: "Pakketten" + # The *packageChoice* value is used for setting the default selection # in the QML view; this should match one of the keys used in the QML # module for package names. diff --git a/src/modules/partition/jobs/FormatPartitionJob.cpp b/src/modules/partition/jobs/FormatPartitionJob.cpp index 63d233426..599e29769 100644 --- a/src/modules/partition/jobs/FormatPartitionJob.cpp +++ b/src/modules/partition/jobs/FormatPartitionJob.cpp @@ -58,10 +58,13 @@ FormatPartitionJob::prettyDescription() const QString FormatPartitionJob::prettyStatusMessage() const { + QString partitionLabel = m_partition->label().isEmpty() + ? m_partition->partitionPath() + : tr( "%1 (%2)", "partition label %1 (device path %2)" ) + .arg( m_partition->label(), m_partition->partitionPath() ); return tr( "Formatting partition %1 with " "file system %2." ) - .arg( m_partition->partitionPath() ) - .arg( userVisibleFS( m_partition->fileSystem() ) ); + .arg( partitionLabel, userVisibleFS( m_partition->fileSystem() ) ); } diff --git a/src/modules/usersq/usersq.qml b/src/modules/usersq/usersq.qml index 9d49e6a7d..febdb5be5 100644 --- a/src/modules/usersq/usersq.qml +++ b/src/modules/usersq/usersq.qml @@ -1,6 +1,6 @@ /* === This file is part of Calamares - === * - * SPDX-FileCopyrightText: 2020 - 2021 Anke Boersma + * SPDX-FileCopyrightText: 2020 - 2022 Anke Boersma * SPDX-FileCopyrightText: 2021 Adriaan de Groot * SPDX-License-Identifier: GPL-3.0-or-later * @@ -123,6 +123,7 @@ Kirigami.ScrollablePage { Kirigami.InlineMessage { id: userMessage Layout.fillWidth: true + showCloseButton: true visible: false type: Kirigami.MessageType.Error text: qsTr("Only lowercase letters, numbers, underscore and hyphen are allowed.") @@ -131,6 +132,7 @@ Kirigami.ScrollablePage { Kirigami.InlineMessage { id: forbiddenMessage Layout.fillWidth: true + showCloseButton: true visible: false type: Kirigami.MessageType.Error text: qsTr("root is not allowed as username.") @@ -185,6 +187,7 @@ Kirigami.ScrollablePage { Kirigami.InlineMessage { id: hostMessage Layout.fillWidth: true + showCloseButton: true visible: false type: Kirigami.MessageType.Error text: qsTr("Only letters, numbers, underscore and hyphen are allowed, minimal of two characters.") @@ -193,6 +196,7 @@ Kirigami.ScrollablePage { Kirigami.InlineMessage { id: forbiddenHost Layout.fillWidth: true + showCloseButton: true visible: false type: Kirigami.MessageType.Error text: qsTr("localhost is not allowed as hostname.")