diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 6cf5a99ba..baaf261d4 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,16 +7,30 @@ 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.48 (unreleased) # +# 3.2.48 (2021-12-03) # This release contains contributions from (alphabetically by first name): - - No external contributors yet + - Evan James ## Core ## - - No core changes yet + - Python modules now have `warn()` and `error()` methods they can call, + alongside the existing `debug()` and `warning()` (all live in the + *libcalamares.utils* module). + - Python modules can load YAML files via `libcalamares.utils.load_yaml()`. + This may be the most useful for test-scripts. ## Modules ## - - No module changes yet + - *fstab* now has a separate, special, flags-setting for swap subvolumes + on btrfs. A swap subvolume is created if a swap **file** (not a separate + partition) is selected in the auto-partitioning page. (Thanks Evan) + - When using btrfs, the *mount* module creates subvolumes. It was not + possible to **avoid** having a subvolume name created for the root. + This is now possible. #1837 + - The *packages* module now has some special settings for the `pacman` + package manager (generally used on Arch-derivatives). This allows + tweaking of the installation process, if downloads are slow or + packages may fail to install. See the `packages.conf` file for + details. (Thanks Evan) # 3.2.47 (2021-11-19) # diff --git a/CMakeLists.txt b/CMakeLists.txt index 67bb1f319..c998d43d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,10 @@ project( CALAMARES LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development +if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) + message( FATAL_ERROR "Do not build development versions in the source-directory." ) +endif() ### OPTIONS # diff --git a/calamares.desktop b/calamares.desktop index 761a7db01..bfe3955b1 100644 --- a/calamares.desktop +++ b/calamares.desktop @@ -236,7 +236,7 @@ Comment[es_MX]=Calamares - Instalador del sistema Name[pt_PT]=Instalar Sistema Icon[pt_PT]=calamares GenericName[pt_PT]=Instalador de Sistema -Comment[pt_PT]=Calamares - Instalador de Sistema +Comment[pt_PT]=Instalador de Sistema - Calamares Name[tr_TR]=Sistemi Yükle Icon[tr_TR]=calamares GenericName[tr_TR]=Sistem Yükleyici diff --git a/data/FreeBSD/Makefile b/data/FreeBSD/Makefile deleted file mode 100644 index d9b7e5043..000000000 --- a/data/FreeBSD/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# $FreeBSD$ -# -# SPDX-FileCopyrightText: 2020 Adriaan de Groot -# SPDX-License-Identifier: BSD-2-Clause - -PORTNAME= calamares -DISTVERSION= 3.2.25 -CATEGORIES= sysutils -MASTER_SITES= https://github.com/${PORTNAME}/${PORTNAME}/releases/download/v${DISTVERSION}/ - -MAINTAINER= adridg@FreeBSD.org -COMMENT= GUI System installer and OEM configurator - -LICENSE= GPLv3 -LICENSE_FILE= ${WRKSRC}/LICENSE - -LIB_DEPENDS= libyaml-cpp.so:devel/yaml-cpp \ - libpwquality.so:security/libpwquality \ - libboost_python${PYTHON_SUFFIX}.so:devel/boost-python-libs - -USES= cmake compiler:c++17-lang gettext kde:5 pkgconfig \ - python:3.3+ qt:5 -USE_QT= concurrent core dbus declarative gui \ - network quickcontrols2 svg widgets xml \ - buildtools_build linguist_build qmake_build -USE_KDE= coreaddons dbusaddons parts service \ - ecm_build -USE_LDCONFIG= yes - -CMAKE_OFF= WITH_KF5Crash \ - INSTALL_CONFIG \ - INSTALL_COMPLETION \ - INSTALL_POLKIT -CMAKE_ON= CMAKE_DISABLE_FIND_PACKAGE_KPMcore -CMAKE_ARGS= -DSKIP_MODULES="webview" - -.include diff --git a/data/FreeBSD/distinfo b/data/FreeBSD/distinfo deleted file mode 100644 index e333963a8..000000000 --- a/data/FreeBSD/distinfo +++ /dev/null @@ -1,3 +0,0 @@ -TIMESTAMP = 1592339404 -SHA256 (calamares-3.2.25.tar.gz) = 797ce33db7d4e4c06bbccef95f6c4023f7628e91bd142896695565fed4ae8c4b -SIZE (calamares-3.2.25.tar.gz) = 3580197 diff --git a/data/FreeBSD/pkg-descr b/data/FreeBSD/pkg-descr deleted file mode 100644 index 39cb4335c..000000000 --- a/data/FreeBSD/pkg-descr +++ /dev/null @@ -1,14 +0,0 @@ -Calamares is an installer framework. By design it is very customizable, -in order to satisfy a wide variety of needs and use cases. - -Calamares aims to be easy, usable, beautiful, pragmatic, inclusive and -distribution-agnostic. - -Got a Linux distribution but no system installer? Grab Calamares, mix -and match any number of Calamares modules (or write your own in Python -or C++), throw together some branding, package it up and you are ready -to ship! - -(The above applies to FreeBSD as well) - -WWW: https://calamares.io/ diff --git a/data/FreeBSD/pkg-plist b/data/FreeBSD/pkg-plist deleted file mode 100644 index 7f588b7a9..000000000 --- a/data/FreeBSD/pkg-plist +++ /dev/null @@ -1,224 +0,0 @@ -bin/calamares -include/libcalamares/CalamaresConfig.h -include/libcalamares/CppJob.h -include/libcalamares/DllMacro.h -include/libcalamares/GlobalStorage.h -include/libcalamares/Job.h -include/libcalamares/JobExample.h -include/libcalamares/JobQueue.h -include/libcalamares/ProcessJob.h -include/libcalamares/PythonHelper.h -include/libcalamares/PythonJob.h -include/libcalamares/PythonJobApi.h -include/libcalamares/Settings.h -include/libcalamares/utils/BoostPython.h -include/libcalamares/utils/CalamaresUtilsSystem.h -include/libcalamares/utils/CommandList.h -include/libcalamares/utils/Dirs.h -include/libcalamares/utils/Entropy.h -include/libcalamares/utils/Logger.h -include/libcalamares/utils/NamedEnum.h -include/libcalamares/utils/NamedSuffix.h -include/libcalamares/utils/PluginFactory.h -include/libcalamares/utils/RAII.h -include/libcalamares/utils/Retranslator.h -include/libcalamares/utils/String.h -include/libcalamares/utils/Tests.h -include/libcalamares/utils/UMask.h -include/libcalamares/utils/Units.h -include/libcalamares/utils/Variant.h -include/libcalamares/utils/Yaml.h -include/libcalamares/utils/moc-warnings.h -lib/calamares/libcalamares.so -lib/calamares/modules/bootloader/main.py -lib/calamares/modules/bootloader/module.desc -lib/calamares/modules/bootloader/test.yaml -lib/calamares/modules/contextualprocess/libcalamares_job_contextualprocess.so -lib/calamares/modules/contextualprocess/module.desc -lib/calamares/modules/displaymanager/main.py -lib/calamares/modules/displaymanager/module.desc -lib/calamares/modules/dracut/main.py -lib/calamares/modules/dracut/module.desc -lib/calamares/modules/dracutlukscfg/libcalamares_job_dracutlukscfg.so -lib/calamares/modules/dracutlukscfg/module.desc -lib/calamares/modules/dummycpp/libcalamares_job_dummycpp.so -lib/calamares/modules/dummycpp/module.desc -lib/calamares/modules/dummyprocess/module.desc -lib/calamares/modules/dummypython/main.py -lib/calamares/modules/dummypython/module.desc -lib/calamares/modules/finished/libcalamares_viewmodule_finished.so -lib/calamares/modules/finished/module.desc -lib/calamares/modules/fstab/main.py -lib/calamares/modules/fstab/module.desc -lib/calamares/modules/fstab/test.yaml -lib/calamares/modules/grubcfg/main.py -lib/calamares/modules/grubcfg/module.desc -lib/calamares/modules/hostinfo/libcalamares_job_hostinfo.so -lib/calamares/modules/hostinfo/module.desc -lib/calamares/modules/hwclock/main.py -lib/calamares/modules/hwclock/module.desc -lib/calamares/modules/initcpio/libcalamares_job_initcpio.so -lib/calamares/modules/initcpio/module.desc -lib/calamares/modules/initcpiocfg/main.py -lib/calamares/modules/initcpiocfg/module.desc -lib/calamares/modules/initramfs/libcalamares_job_initramfs.so -lib/calamares/modules/initramfs/module.desc -lib/calamares/modules/initramfscfg/encrypt_hook -lib/calamares/modules/initramfscfg/encrypt_hook_nokey -lib/calamares/modules/initramfscfg/main.py -lib/calamares/modules/initramfscfg/module.desc -lib/calamares/modules/interactiveterminal/libcalamares_viewmodule_interactiveterminal.so -lib/calamares/modules/interactiveterminal/module.desc -lib/calamares/modules/keyboard/libcalamares_viewmodule_keyboard.so -lib/calamares/modules/keyboard/module.desc -lib/calamares/modules/keyboardq/libcalamares_viewmodule_keyboardq.so -lib/calamares/modules/keyboardq/module.desc -lib/calamares/modules/license/libcalamares_viewmodule_license.so -lib/calamares/modules/license/module.desc -lib/calamares/modules/locale/libcalamares_viewmodule_locale.so -lib/calamares/modules/locale/module.desc -lib/calamares/modules/localecfg/main.py -lib/calamares/modules/localecfg/module.desc -lib/calamares/modules/localeq/libcalamares_viewmodule_localeq.so -lib/calamares/modules/localeq/module.desc -lib/calamares/modules/luksbootkeyfile/libcalamares_job_luksbootkeyfile.so -lib/calamares/modules/luksbootkeyfile/module.desc -lib/calamares/modules/luksopenswaphookcfg/main.py -lib/calamares/modules/luksopenswaphookcfg/module.desc -lib/calamares/modules/machineid/libcalamares_job_machineid.so -lib/calamares/modules/machineid/module.desc -lib/calamares/modules/mount/main.py -lib/calamares/modules/mount/module.desc -lib/calamares/modules/mount/test.yaml -lib/calamares/modules/netinstall/libcalamares_viewmodule_netinstall.so -lib/calamares/modules/netinstall/module.desc -lib/calamares/modules/networkcfg/main.py -lib/calamares/modules/networkcfg/module.desc -lib/calamares/modules/notesqml/libcalamares_viewmodule_notesqml.so -lib/calamares/modules/notesqml/module.desc -lib/calamares/modules/oemid/libcalamares_viewmodule_oemid.so -lib/calamares/modules/oemid/module.desc -lib/calamares/modules/openrcdmcryptcfg/main.py -lib/calamares/modules/openrcdmcryptcfg/module.desc -lib/calamares/modules/packagechooser/libcalamares_viewmodule_packagechooser.so -lib/calamares/modules/packagechooser/module.desc -lib/calamares/modules/packages/main.py -lib/calamares/modules/packages/module.desc -lib/calamares/modules/packages/test.yaml -lib/calamares/modules/plymouthcfg/main.py -lib/calamares/modules/plymouthcfg/module.desc -lib/calamares/modules/preservefiles/libcalamares_job_preservefiles.so -lib/calamares/modules/preservefiles/module.desc -lib/calamares/modules/rawfs/main.py -lib/calamares/modules/rawfs/module.desc -lib/calamares/modules/removeuser/libcalamares_job_removeuser.so -lib/calamares/modules/removeuser/module.desc -lib/calamares/modules/services-openrc/main.py -lib/calamares/modules/services-openrc/module.desc -lib/calamares/modules/services-systemd/main.py -lib/calamares/modules/services-systemd/module.desc -lib/calamares/modules/shellprocess/libcalamares_job_shellprocess.so -lib/calamares/modules/shellprocess/module.desc -lib/calamares/modules/summary/libcalamares_viewmodule_summary.so -lib/calamares/modules/summary/module.desc -lib/calamares/modules/tracking/libcalamares_viewmodule_tracking.so -lib/calamares/modules/tracking/module.desc -lib/calamares/modules/umount/main.py -lib/calamares/modules/umount/module.desc -lib/calamares/modules/unpackfs/main.py -lib/calamares/modules/unpackfs/module.desc -lib/calamares/modules/unpackfs/runtests.sh -lib/calamares/modules/users/libcalamares_viewmodule_users.so -lib/calamares/modules/users/module.desc -lib/calamares/modules/welcome/libcalamares_viewmodule_welcome.so -lib/calamares/modules/welcome/module.desc -lib/calamares/modules/welcomeq/libcalamares_viewmodule_welcomeq.so -lib/calamares/modules/welcomeq/module.desc -lib/cmake/Calamares/CMakeColors.cmake -lib/cmake/Calamares/CalamaresAddBrandingSubdirectory.cmake -lib/cmake/Calamares/CalamaresAddLibrary.cmake -lib/cmake/Calamares/CalamaresAddModuleSubdirectory.cmake -lib/cmake/Calamares/CalamaresAddPlugin.cmake -lib/cmake/Calamares/CalamaresAddTest.cmake -lib/cmake/Calamares/CalamaresAddTranslations.cmake -lib/cmake/Calamares/CalamaresAutomoc.cmake -lib/cmake/Calamares/CalamaresConfig.cmake -lib/cmake/Calamares/CalamaresConfigVersion.cmake -lib/cmake/Calamares/CalamaresLibraryDepends-%%CMAKE_BUILD_TYPE%%.cmake -lib/cmake/Calamares/CalamaresLibraryDepends.cmake -lib/cmake/Calamares/CalamaresUse.cmake -lib/libcalamares.so -lib/libcalamares.so.3.2.25 -lib/libcalamaresui.so -lib/libcalamaresui.so.3.2.25 -man/man8/calamares.8.gz -share/applications/calamares.desktop -%%DATADIR%%/branding/default/banner.png -%%DATADIR%%/branding/default/branding.desc -%%DATADIR%%/branding/default/lang/calamares-default_ar.qm -%%DATADIR%%/branding/default/lang/calamares-default_en.qm -%%DATADIR%%/branding/default/lang/calamares-default_eo.qm -%%DATADIR%%/branding/default/lang/calamares-default_fr.qm -%%DATADIR%%/branding/default/lang/calamares-default_nl.qm -%%DATADIR%%/branding/default/languages.png -%%DATADIR%%/branding/default/show.qml -%%DATADIR%%/branding/default/squid.png -%%DATADIR%%/branding/default/stylesheet.qss -%%DATADIR%%/qml/calamares/slideshow/BackButton.qml -%%DATADIR%%/qml/calamares/slideshow/ForwardButton.qml -%%DATADIR%%/qml/calamares/slideshow/NavButton.qml -%%DATADIR%%/qml/calamares/slideshow/Presentation.qml -%%DATADIR%%/qml/calamares/slideshow/Slide.qml -%%DATADIR%%/qml/calamares/slideshow/SlideCounter.qml -%%DATADIR%%/qml/calamares/slideshow/qmldir -share/icons/hicolor/scalable/apps/calamares.svg -share/locale/ar/LC_MESSAGES/calamares-python.mo -share/locale/as/LC_MESSAGES/calamares-python.mo -share/locale/ast/LC_MESSAGES/calamares-python.mo -share/locale/be/LC_MESSAGES/calamares-python.mo -share/locale/bg/LC_MESSAGES/calamares-python.mo -share/locale/ca/LC_MESSAGES/calamares-python.mo -share/locale/cs_CZ/LC_MESSAGES/calamares-python.mo -share/locale/da/LC_MESSAGES/calamares-python.mo -share/locale/de/LC_MESSAGES/calamares-python.mo -share/locale/el/LC_MESSAGES/calamares-python.mo -share/locale/en_GB/LC_MESSAGES/calamares-python.mo -share/locale/eo/LC_MESSAGES/calamares-python.mo -share/locale/es/LC_MESSAGES/calamares-python.mo -share/locale/es_MX/LC_MESSAGES/calamares-python.mo -share/locale/es_PR/LC_MESSAGES/calamares-python.mo -share/locale/et/LC_MESSAGES/calamares-python.mo -share/locale/eu/LC_MESSAGES/calamares-python.mo -share/locale/fi_FI/LC_MESSAGES/calamares-python.mo -share/locale/fr/LC_MESSAGES/calamares-python.mo -share/locale/gl/LC_MESSAGES/calamares-python.mo -share/locale/he/LC_MESSAGES/calamares-python.mo -share/locale/hi/LC_MESSAGES/calamares-python.mo -share/locale/hr/LC_MESSAGES/calamares-python.mo -share/locale/hu/LC_MESSAGES/calamares-python.mo -share/locale/id/LC_MESSAGES/calamares-python.mo -share/locale/is/LC_MESSAGES/calamares-python.mo -share/locale/it_IT/LC_MESSAGES/calamares-python.mo -share/locale/ja/LC_MESSAGES/calamares-python.mo -share/locale/ko/LC_MESSAGES/calamares-python.mo -share/locale/lt/LC_MESSAGES/calamares-python.mo -share/locale/ml/LC_MESSAGES/calamares-python.mo -share/locale/mr/LC_MESSAGES/calamares-python.mo -share/locale/nb/LC_MESSAGES/calamares-python.mo -share/locale/nl/LC_MESSAGES/calamares-python.mo -share/locale/pl/LC_MESSAGES/calamares-python.mo -share/locale/pt_BR/LC_MESSAGES/calamares-python.mo -share/locale/pt_PT/LC_MESSAGES/calamares-python.mo -share/locale/ro/LC_MESSAGES/calamares-python.mo -share/locale/ru/LC_MESSAGES/calamares-python.mo -share/locale/sk/LC_MESSAGES/calamares-python.mo -share/locale/sl/LC_MESSAGES/calamares-python.mo -share/locale/sq/LC_MESSAGES/calamares-python.mo -share/locale/sr/LC_MESSAGES/calamares-python.mo -share/locale/sr@latin/LC_MESSAGES/calamares-python.mo -share/locale/sv/LC_MESSAGES/calamares-python.mo -share/locale/th/LC_MESSAGES/calamares-python.mo -share/locale/tr_TR/LC_MESSAGES/calamares-python.mo -share/locale/uk/LC_MESSAGES/calamares-python.mo -share/locale/zh_CN/LC_MESSAGES/calamares-python.mo -share/locale/zh_TW/LC_MESSAGES/calamares-python.mo diff --git a/lang/calamares_pt_BR.ts b/lang/calamares_pt_BR.ts index 435f398e4..517a84b3a 100644 --- a/lang/calamares_pt_BR.ts +++ b/lang/calamares_pt_BR.ts @@ -689,27 +689,27 @@ O instalador será fechado e todas as alterações serão perdidas. Successfully unmounted %1. - + %1 desmontado com sucesso. Successfully disabled swap %1. - + Swap %1 desativada com sucesso. Successfully cleared swap %1. - + Swap %1 limpa com sucesso. Successfully closed mapper device %1. - + Dispositivo de mapeamento %1 fechado com sucesso. Successfully disabled volume group %1. - + Grupo de volume %1 desativado com sucesso. diff --git a/lang/calamares_pt_PT.ts b/lang/calamares_pt_PT.ts index dbbc088a9..951645ab1 100644 --- a/lang/calamares_pt_PT.ts +++ b/lang/calamares_pt_PT.ts @@ -789,7 +789,7 @@ O instalador será encerrado e todas as alterações serão perdidas. The system language will be set to %1. - A linguagem do sistema será definida para %1. + O idioma do sistema será definido para %1. @@ -1684,7 +1684,7 @@ O instalador será encerrado e todas as alterações serão perdidas. Collecting information about your machine. - A recolher informação acerca da sua máquina. + A recolher informação sobre a sua máquina. @@ -3988,7 +3988,7 @@ Saída de Dados: %1 support - %1 suporte + Suporte do %1 @@ -3998,7 +3998,7 @@ Saída de Dados: About %1 installer - Acerca %1 instalador + Acerca do instalador %1 diff --git a/lang/calamares_ru.ts b/lang/calamares_ru.ts index 712662224..c722e2359 100644 --- a/lang/calamares_ru.ts +++ b/lang/calamares_ru.ts @@ -189,7 +189,7 @@ Run command '%1' in target system. - Запустить комманду'%1'в целевой системе. + Запустить команду '%1' в целевой системе. @@ -274,10 +274,10 @@ (%n second(s)) - (% секунда) - (% секунд) - (% секунд) + (%n секунда) + (%n секунды) (%n секунд) + (%n секунд(ы)) @@ -2673,7 +2673,7 @@ The installer will quit and all changes will be lost. EFI system - Система EFI + Системный раздел EFI diff --git a/lang/python/pt_BR/LC_MESSAGES/python.po b/lang/python/pt_BR/LC_MESSAGES/python.po index d3cf730a0..f8f3e8ca7 100644 --- a/lang/python/pt_BR/LC_MESSAGES/python.po +++ b/lang/python/pt_BR/LC_MESSAGES/python.po @@ -330,7 +330,7 @@ msgstr "Não é possível habilitar o alvo {name!s} do systemd." #: src/modules/services-systemd/main.py:67 msgid "Cannot enable systemd timer {name!s}." -msgstr "" +msgstr "Não foi possível ativar o cronômetro systemd {name!s}." #: src/modules/services-systemd/main.py:71 msgid "Cannot disable systemd target {name!s}." @@ -410,6 +410,8 @@ msgid "" "Failed to find unsquashfs, make sure you have the squashfs-tools package " "installed." msgstr "" +"Não foi possível encontrar o unsquashfs, certifique-se de que o pacote " +"squashfs-tools foi instalado." #: src/modules/unpackfs/main.py:479 msgid "The destination \"{}\" in the target system is not a directory" diff --git a/lang/python/vi/LC_MESSAGES/python.po b/lang/python/vi/LC_MESSAGES/python.po index 83928edd6..900b99454 100644 --- a/lang/python/vi/LC_MESSAGES/python.po +++ b/lang/python/vi/LC_MESSAGES/python.po @@ -5,6 +5,7 @@ # # Translators: # T. Tran , 2020 +# Th1nhhdk, 2021 # #, fuzzy msgid "" @@ -13,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-02 15:45+0100\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: T. Tran , 2020\n" +"Last-Translator: Th1nhhdk, 2021\n" "Language-Team: Vietnamese (https://www.transifex.com/calamares/teams/20061/vi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -61,13 +62,15 @@ msgstr "Đang cài đặt bộ khởi động." #: src/modules/bootloader/main.py:508 msgid "Bootloader installation error" -msgstr "" +msgstr "Lỗi cài đặt trình khởi động(bootloader)" #: src/modules/bootloader/main.py:509 msgid "" "The bootloader could not be installed. The installation command " "
{!s}
returned error code {!s}." msgstr "" +"Trình khởi động(bootloader) không thể được cài đặt. Lệnh cài đặt " +"
{!s}
đã trả mã lỗi {!s}." #: src/modules/fstab/main.py:29 msgid "Writing fstab." diff --git a/src/libcalamares/PythonJob.cpp b/src/libcalamares/PythonJob.cpp index afeebbe07..291adbc54 100644 --- a/src/libcalamares/PythonJob.cpp +++ b/src/libcalamares/PythonJob.cpp @@ -79,13 +79,25 @@ BOOST_PYTHON_MODULE( libcalamares ) bp::scope utilsScope = utilsModule; Q_UNUSED( utilsScope ) + // .. Logging functions bp::def( "debug", &CalamaresPython::debug, bp::args( "s" ), "Writes the given string to the Calamares debug stream." ); bp::def( "warning", &CalamaresPython::warning, bp::args( "s" ), "Writes the given string to the Calamares warning stream." ); + bp::def( "warn", + &CalamaresPython::warning, + bp::args( "s" ), + "Writes the given string to the Calamares warning stream." ); + bp::def( + "error", &CalamaresPython::warning, bp::args( "s" ), "Writes the given string to the Calamares error stream." ); + + // .. YAML functions + bp::def( "load_yaml", &CalamaresPython::load_yaml, bp::args( "path" ), "Loads YAML from a file." ); + + // .. Filesystem functions bp::def( "mount", &CalamaresPython::mount, mount_overloads( bp::args( "device_path", "mount_point", "filesystem_name", "options" ), @@ -94,6 +106,8 @@ BOOST_PYTHON_MODULE( libcalamares ) "-1 = QProcess crash\n" "-2 = QProcess cannot start\n" "-3 = bad arguments" ) ); + + // .. Process functions bp::def( "target_env_call", static_cast< int ( * )( const std::string&, const std::string&, int ) >( &CalamaresPython::target_env_call ), @@ -152,6 +166,7 @@ BOOST_PYTHON_MODULE( libcalamares ) host_env_process_output_overloads( bp::args( "command", "callback", "stdin", "timeout" ), "Runs the specified command in the host system." ) ); + // .. String functions bp::def( "obscure", &CalamaresPython::obscure, bp::args( "s" ), @@ -160,7 +175,7 @@ BOOST_PYTHON_MODULE( libcalamares ) "Applying the function to a string obscured by this function will result " "in the original string." ); - + // .. Translation functions bp::def( "gettext_languages", &CalamaresPython::gettext_languages, "Returns list of languages (most to least-specific) for gettext." ); diff --git a/src/libcalamares/PythonJobApi.cpp b/src/libcalamares/PythonJobApi.cpp index 1713569a4..bb2b8749e 100644 --- a/src/libcalamares/PythonJobApi.cpp +++ b/src/libcalamares/PythonJobApi.cpp @@ -19,6 +19,7 @@ #include "utils/RAII.h" #include "utils/Runner.h" #include "utils/String.h" +#include "utils/Yaml.h" #include #include @@ -139,19 +140,44 @@ check_target_env_output( const bp::list& args, const std::string& stdin, int tim } static const char output_prefix[] = "[PYTHON JOB]:"; +static inline void +log_action( unsigned int level, const std::string& s ) +{ + Logger::CDebug( level ) << output_prefix << QString::fromStdString( s ); +} void debug( const std::string& s ) { - Logger::CDebug( Logger::LOGDEBUG ) << output_prefix << QString::fromStdString( s ); + log_action( Logger::LOGDEBUG, s ); } void warning( const std::string& s ) { - Logger::CDebug( Logger::LOGWARNING ) << output_prefix << QString::fromStdString( s ); + log_action( Logger::LOGWARNING, s ); } +void +error( const std::string& s ) +{ + log_action( Logger::LOGERROR, s ); +} + +boost::python::dict +load_yaml( const std::string& path ) +{ + const QString filePath = QString::fromStdString( path ); + bool ok = false; + auto map = CalamaresUtils::loadYaml( filePath, &ok ); + if ( !ok ) + { + cWarning() << "Loading YAML from" << filePath << "failed."; + } + return variantMapToPyDict( map ); +} + + PythonJobInterface::PythonJobInterface( Calamares::PythonJob* parent ) : m_parent( parent ) { diff --git a/src/libcalamares/PythonJobApi.h b/src/libcalamares/PythonJobApi.h index 48bd4f87c..62346ceda 100644 --- a/src/libcalamares/PythonJobApi.h +++ b/src/libcalamares/PythonJobApi.h @@ -60,6 +60,12 @@ boost::python::list gettext_languages(); void debug( const std::string& s ); void warning( const std::string& s ); +void error( const std::string& s ); + +/** @brief Loads YAML and returns (nested) dicts representing it + * + */ +boost::python::dict load_yaml( const std::string& path ); class PythonJobInterface { diff --git a/src/modules/fstab/fstab.conf b/src/modules/fstab/fstab.conf index d35bebb03..9c76f0c46 100644 --- a/src/modules/fstab/fstab.conf +++ b/src/modules/fstab/fstab.conf @@ -15,9 +15,13 @@ # With kernels 5.15 and newer be cautious of adding the option space_cache # to the btrfs mount options. The default in 5.15 changed to space_cache=v2. # If space_cache or space_cache=v1 are specified, it may fail to remount. +# +# btrfs_swap options are used when a swapfile is chosen with a btrfs root +# the options are applied to the subvolume which holds the swap partition mountOptions: default: defaults,noatime btrfs: defaults,noatime,autodefrag,compress=zstd + btrfs_swap: defaults,noatime # Mount options to use for the EFI System Partition. If not defined, the # *mountOptions* for *vfat* are used, or if that is not set either, diff --git a/src/modules/fstab/fstab.schema.yaml b/src/modules/fstab/fstab.schema.yaml index fc68fd2c5..087e82cac 100644 --- a/src/modules/fstab/fstab.schema.yaml +++ b/src/modules/fstab/fstab.schema.yaml @@ -22,6 +22,7 @@ properties: xfs: { type: string } swap: { type: string } btrfs: { type: string } + btrfs_swap: { type: string } efiMountOptions: { type: string } crypttabOptions: { type: string } required: [ mountOptions ] diff --git a/src/modules/fstab/main.py b/src/modules/fstab/main.py index 3a2dbcf41..6a771a24b 100644 --- a/src/modules/fstab/main.py +++ b/src/modules/fstab/main.py @@ -236,7 +236,11 @@ class FstabGenerator(object): libcalamares.utils.debug("Ignoring foreign swap {!s} {!s}".format(disk_name, partition.get("uuid", None))) return None - options = self.get_mount_options(filesystem, mount_point) + # If this is btrfs subvol a dedicated to a swapfile, use different options than a normal btrfs subvol + if filesystem == "btrfs" and partition.get("subvol", None) == "/@swap": + options = self.get_mount_options("btrfs_swap", mount_point) + else: + options = self.get_mount_options(filesystem, mount_point) if is_ssd: extra = self.ssd_extra_mount_options.get(filesystem) @@ -254,7 +258,8 @@ class FstabGenerator(object): if mount_point == "/": self.root_is_ssd = is_ssd - if filesystem == "btrfs" and "subvol" in partition: + # If there's a set-and-not-empty subvolume set, add it + if filesystem == "btrfs" and partition.get("subvol",None): options = "subvol={},".format(partition["subvol"]) + options if has_luks: diff --git a/src/modules/locale/images/timezone_5.0.png b/src/modules/locale/images/timezone_5.0.png index e8ea14466..a15aaccc0 100644 Binary files a/src/modules/locale/images/timezone_5.0.png and b/src/modules/locale/images/timezone_5.0.png differ diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index 900342e6d..f186b0d26 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -191,6 +191,8 @@ def mount_partition(root_mount_point, partition, partitions): libcalamares.globalstorage.insert("btrfsSubvolumes", btrfs_subvolumes) # Create the subvolumes that are in the completed list for s in btrfs_subvolumes: + if not s["subvolume"]: + continue subprocess.check_call(["btrfs", "subvolume", "create", root_mount_point + s["subvolume"]]) if s["mountPoint"] == "/": diff --git a/src/modules/mount/mount.conf b/src/modules/mount/mount.conf index 6168e97cc..84dca05a7 100644 --- a/src/modules/mount/mount.conf +++ b/src/modules/mount/mount.conf @@ -42,15 +42,24 @@ extraMountsEfi: mountPoint: /sys/firmware/efi/efivars # Btrfs subvolumes to create if root filesystem is on btrfs volume. -# If mountpoint is mounted already to another partition, it is ignored. +# If *mountpoint* is mounted already to another partition, it is ignored. # Separate subvolume for swapfile is handled separately and automatically. +# +# It is possible to prevent subvolume creation -- this is likely only relevant +# for the root (/) subvolume -- by giving an empty string as a subvolume +# name. In this case no subvolume will be created. When using snapper as +# a rollback mechanism, it is recommended to **not** create a subvolume +# for root. btrfsSubvolumes: - mountPoint: / subvolume: /@ + # As an alternative: + # + # subvolume: "" - mountPoint: /home subvolume: /@home - mountPoint: /var/cache subvolume: /@cache - mountPoint: /var/log - subvolume: /@log \ No newline at end of file + subvolume: /@log diff --git a/src/modules/packages/main.py b/src/modules/packages/main.py index 98faa9b63..10371777e 100644 --- a/src/modules/packages/main.py +++ b/src/modules/packages/main.py @@ -379,6 +379,7 @@ class PMPacman(PackageManager): def __init__(self): import re progress_match = re.compile("^\\((\\d+)/(\\d+)\\)") + def line_cb(line): if line.startswith(":: "): self.in_package_changes = "package changes" in line @@ -396,30 +397,79 @@ class PMPacman(PackageManager): self.in_package_changes = False self.line_cb = line_cb + pacman = libcalamares.job.configuration.get("pacman", None) + if pacman is None: + pacman = dict() + if type(pacman) is not dict: + libcalamares.utils.warning("Job configuration *pacman* will be ignored.") + pacman = dict() + self.pacman_num_retries = pacman.get("num_retries", 0) + self.pacman_disable_timeout = pacman.get("disable_download_timeout", False) + self.pacman_needed_only = pacman.get("needed_only", False) + def reset_progress(self): self.in_package_changes = False # These are globals self.progress_fraction = (completed_packages * 1.0 / total_packages) + def run_pacman(self, command, callback=False): + """ + Call pacman in a loop until it is successful or the number of retries is exceeded + :param command: The pacman command to run + :param callback: An optional boolean that indicates if this pacman run should use the callback + :return: + """ + + pacman_count = 0 + while pacman_count <= self.pacman_num_retries: + pacman_count += 1 + try: + if callback is True: + libcalamares.utils.target_env_process_output(command, self.line_cb) + else: + libcalamares.utils.target_env_process_output(command) + + return + except subprocess.CalledProcessError: + if pacman_count <= self.pacman_num_retries: + pass + else: + raise + def install(self, pkgs, from_local=False): + command = ["pacman"] + if from_local: - pacman_flags = "-U" + command.append("-U") else: - pacman_flags = "-S" + command.append("-S") + + command.append("--noconfirm") + + if self.pacman_needed_only is True: + command.append("--needed") + + if self.pacman_disable_timeout is True: + command.append("--disable-download-timeout") + + command += pkgs self.reset_progress() - libcalamares.utils.target_env_process_output(["pacman", pacman_flags, - "--noconfirm"] + pkgs, self.line_cb) + self.run_pacman(command, True) def remove(self, pkgs): self.reset_progress() - libcalamares.utils.target_env_process_output(["pacman", "-Rs", "--noconfirm"] + pkgs, self.line_cb) + self.run_pacman(["pacman", "-Rs", "--noconfirm"] + pkgs, True) def update_db(self): - check_target_env_call(["pacman", "-Sy"]) + self.run_pacman(["pacman", "-Sy"]) def update_system(self): - check_target_env_call(["pacman", "-Su", "--noconfirm"]) + command = ["pacman", "-Su", "--noconfirm"] + if self.pacman_disable_timeout is True: + command.append("--disable-download-timeout") + + self.run_pacman(command) class PMPamac(PackageManager): diff --git a/src/modules/packages/packages.conf b/src/modules/packages/packages.conf index 49fdbb6d6..6e62f4b5f 100644 --- a/src/modules/packages/packages.conf +++ b/src/modules/packages/packages.conf @@ -62,6 +62,23 @@ skip_if_no_internet: false update_db: true update_system: false +# pacman specific options +# +# *num_retries* should be a positive integer which specifies the +# number of times the call to pacman will be retried in the event of a +# failure. If it is missing, it will be set to 0. +# +# *disable_download_timeout* is a boolean that, when true, includes +# the flag --disable-download-timeout on calls to pacman. When missing, +# false is assumed. +# +# *needed_only* is a boolean that includes the pacman argument --needed +# when set to true. If missing, false is assumed. +pacman: + num_retries: 0 + disable_download_timeout: false + needed_only: false + # # List of maps with package operations such as install or remove. # Distro developers can provide a list of packages to remove diff --git a/src/modules/packages/packages.schema.yaml b/src/modules/packages/packages.schema.yaml index 989bf11dd..d12f0507e 100644 --- a/src/modules/packages/packages.schema.yaml +++ b/src/modules/packages/packages.schema.yaml @@ -26,6 +26,14 @@ properties: update_system: { type: boolean, default: false } skip_if_no_internet: { type: boolean, default: false } + pacman: + additionalProperties: false + type: object + properties: + num_retries: { type: integer, default: 0 } + disable_download_timeout: { type: boolean, default: false } + needed_only: { type: boolean, default: false } + operations: type: array items: diff --git a/src/modules/packages/tests/1.global b/src/modules/packages/tests/1.global new file mode 100644 index 000000000..ee06ccfe1 --- /dev/null +++ b/src/modules/packages/tests/1.global @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +rootMountPoint: /tmp diff --git a/src/modules/packages/test.yaml b/src/modules/packages/tests/2.job similarity index 90% rename from src/modules/packages/test.yaml rename to src/modules/packages/tests/2.job index 130214dfd..ba205ed44 100644 --- a/src/modules/packages/test.yaml +++ b/src/modules/packages/tests/2.job @@ -1,7 +1,6 @@ # SPDX-FileCopyrightText: no # SPDX-License-Identifier: CC0-1.0 backend: dummy -rootMountPoint: /tmp/mount operations: - install: - pre-script: touch /tmp/foo diff --git a/src/modules/packages/tests/CMakeTests.txt b/src/modules/packages/tests/CMakeTests.txt new file mode 100644 index 000000000..4f7d6185f --- /dev/null +++ b/src/modules/packages/tests/CMakeTests.txt @@ -0,0 +1,42 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +# +# We have tests to load (some) of the package-managers specifically, to +# test their configuration code and implementation. Those tests conventionally +# live in Python files here in the tests/ directory. Add them. + +# Pacman (Arch) tests +set(_pm pacman) +add_test( + NAME configure-packages-${_pm} + COMMAND env PYTHONPATH=.: python3 ${CMAKE_CURRENT_LIST_DIR}/test-pm-${_pm}.py + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) +add_test( + NAME configure-packages-${_pm}-ops-1 + COMMAND env PYTHONPATH=.: python3 ${CMAKE_CURRENT_LIST_DIR}/test-pm-${_pm}.py ${CMAKE_CURRENT_LIST_DIR}/pm-pacman-1.yaml 4 1 1 + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) +add_test( + NAME configure-packages-${_pm}-ops-2 + COMMAND env PYTHONPATH=.: python3 ${CMAKE_CURRENT_LIST_DIR}/test-pm-${_pm}.py ${CMAKE_CURRENT_LIST_DIR}/pm-pacman-2.yaml 3 0 0 + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) + +if ( BUILD_TESTING AND BUILD_SCHEMA_TESTING AND PYTHONINTERP_FOUND AND PYTHON_EXECUTABLE ) + set( _module packages ) + set( _schema_file "${CMAKE_CURRENT_SOURCE_DIR}/${_module}/${_module}.schema.yaml" ) + message(STATUS "Schema ${_schema_file}") + foreach( _cf pm-pacman-1.yaml pm-pacman-2.yaml ) + set( _conf_file "${CMAKE_CURRENT_SOURCE_DIR}/${_module}/tests/${_cf}" ) + if ( EXISTS "${_schema_file}" AND EXISTS "${_conf_file}" ) + add_test( + NAME validate-packages-${_cf} + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_SOURCE_DIR}/ci/configvalidator.py" "${_schema_file}" "${_conf_file}" + ) + else() + message(FATAL_ERROR "Missing ${_conf_file}") + endif() + endforeach() +endif() + diff --git a/src/modules/packages/tests/pm-pacman-1.yaml b/src/modules/packages/tests/pm-pacman-1.yaml new file mode 100644 index 000000000..aeb5b8625 --- /dev/null +++ b/src/modules/packages/tests/pm-pacman-1.yaml @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +backend: pacman +operations: [] + +pacman: + num_retries: 4 + disable_download_timeout: true + needed_only: true + diff --git a/src/modules/packages/tests/pm-pacman-2.yaml b/src/modules/packages/tests/pm-pacman-2.yaml new file mode 100644 index 000000000..8b0bda397 --- /dev/null +++ b/src/modules/packages/tests/pm-pacman-2.yaml @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +backend: pacman +operations: [] + +# Leave some things unspecified +pacman: + num_retries: 3 + diff --git a/src/modules/packages/tests/test-pm-pacman.py b/src/modules/packages/tests/test-pm-pacman.py new file mode 100644 index 000000000..ee814b620 --- /dev/null +++ b/src/modules/packages/tests/test-pm-pacman.py @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +# +# Calamares Boilerplate +import libcalamares +libcalamares.globalstorage = libcalamares.GlobalStorage(None) +libcalamares.globalstorage.insert("testing", True) + +# Module prep-work +from src.modules.packages import main + +# .. we don't have a job in this test, so fake one +class Job(object): + def __init__(self, filename): + self.configuration = libcalamares.utils.load_yaml(filename) if filename is not None else dict() + +import sys +if len(sys.argv) > 4: + filename = sys.argv[1] + retry = int(sys.argv[2]) + timeout = bool(int(sys.argv[3])) + needed = bool(int(sys.argv[4])) +else: + filename = None + retry = 0 + timeout = False + needed = False + +libcalamares.utils.warning("Expecting {!s} retry={!s} timeout={!s} needed={!s}".format(filename, retry, timeout, needed)) + +# Specific PM test +libcalamares.job = Job(filename) +p = main.PMPacman() +assert p.pacman_num_retries == retry, "{!r} vs {!r}".format(p.pacman_num_retries, retry) +assert p.pacman_disable_timeout == timeout, "{!r} vs {!r}".format(p.pacman_disable_timeout, timeout) +assert p.pacman_needed_only == needed, "{!r} vs {!r}".format(p.pacman_needed_only, needed) diff --git a/src/modules/zfs/README.md b/src/modules/zfs/README.md index 9138a0598..992fa5cb3 100644 --- a/src/modules/zfs/README.md +++ b/src/modules/zfs/README.md @@ -6,7 +6,10 @@ There are a few considerations to be aware of when enabling the zfs module * You must provide zfs kernel modules or kernel support on the ISO for the zfs module to function + * The zfs kernel module must be loaded prior to the partition module running + * One way to achieve this is by running `modprobe zfs` * Support for zfs in the partition module is conditional on the zfs module being enabled +* The config for the default pools and datasets is configured and described in modules/zfs.conf * If you use grub with zfs, you must have `ZPOOL_VDEV_NAME_PATH=1` in your environment when running grub-install or grub-mkconfig. * Calamares will ensure this happens during the bootloader module. * It will also add it to `/etc/environment` so it will be available in the installation diff --git a/src/modules/zfs/zfs.conf b/src/modules/zfs/zfs.conf index f2f8f52b0..e5a0aa348 100644 --- a/src/modules/zfs/zfs.conf +++ b/src/modules/zfs/zfs.conf @@ -10,6 +10,9 @@ poolName: zpcala # A list of options that will be passed to zpool create +# +# Encryption options should generally not be added here since they will be added by +# selecting the encrypt disk option in the partition module poolOptions: "-f -o ashift=12 -O mountpoint=none -O acltype=posixacl -O relatime=on" # A list of options that will be passed to zfs create when creating each dataset @@ -17,6 +20,10 @@ poolOptions: "-f -o ashift=12 -O mountpoint=none -O acltype=posixacl -O relatime datasetOptions: "-o compression=lz4 -o atime=off -o xattr=sa" # An array of datasets that will be created on the zpool mounted at / +# +# This default configuration is commonly used when support for booting more than one distro +# out of a single zpool is desired. If you decide to keep this default configuration, +# you should replace "distro" with an identifier that represents your distro. datasets: - dsName: ROOT mountpoint: none