Compare commits

...

69 Commits

Author SHA1 Message Date
Teo Mrnjavac
755a56914d Don't assume 'User' exists in autologin section. 2017-01-19 17:04:50 +01:00
Teo Mrnjavac
ef04515011 Bump. 2017-01-13 18:16:47 +01:00
Teo Mrnjavac
8e842efd66 Force the correct flags for EFI system partition. 2017-01-12 16:52:55 +01:00
Teo Mrnjavac
21a6459611 Make sure to disable the root password if setRootPassword is false.
CAL-442 #comment Backported to 2.4.x-stable.
2017-01-12 13:47:05 +01:00
Teo Mrnjavac
a81c8137b2 The sender QObject should be in scope so the bootloader path is written.
CAL-388
CAL-417
CAL-441
2017-01-11 11:50:40 +01:00
Teo Mrnjavac
1c946bf365 Improve debug output. 2016-12-23 14:17:39 +01:00
Teo Mrnjavac
67bd3306f8 Improve debug output. 2016-12-23 14:04:12 +01:00
Teo Mrnjavac
89f078f8c5 Alignment. 2016-12-22 13:53:17 +01:00
demmm
6e2d445888 fix crash on loading webview page with QtWebengine 2016-12-22 13:53:09 +01:00
Teo Mrnjavac
bdda452f66 ifdef all the things so we can build with both KPMcore 3 and 2.2. 2016-12-21 13:59:17 +01:00
Teo Mrnjavac
50187261c3 Expose KPMcore version status to partition module. 2016-12-21 13:58:17 +01:00
Teo Mrnjavac
1f37f3dda0 Do not dereference nullptr. 2016-12-13 12:16:56 +01:00
Teo Mrnjavac
d7302ca024 Provide default for m_writeEtcDefaultKeyboard in KeyboardViewStep. 2016-12-13 12:10:40 +01:00
Teo Mrnjavac
92e1233279 Write hasInternet to GlobalStorage.
CAL-431 #close
2016-12-12 13:38:28 +01:00
Teo Mrnjavac
4a50f5ae54 Do not LINK_PUBLIC by default. 2016-12-07 16:40:04 +01:00
Teo Mrnjavac
fe75e980f5 Add LINK_PRIVATE_LIBRARIES to calamares_add_plugin. 2016-12-07 16:39:57 +01:00
Teo Mrnjavac
7a67eed918 Document settings for services module. 2016-12-05 18:01:12 +01:00
Kevin Kofler
b4fb2115dc [displaymanager] set_autologin: Unset autologin for sddm when needed
CAL-423 #close
2016-12-03 19:20:29 +01:00
Teo Mrnjavac
61703ad070 Write Btrfs subvolume lines to fstab. 2016-11-25 18:38:44 +01:00
Teo Mrnjavac
e95b555289 Special case for Btrfs root: create subvolumes and mount them. 2016-11-25 18:38:44 +01:00
Teo Mrnjavac
e5274df598 Bump. 2016-11-25 18:21:24 +01:00
Kevin Kofler
b3ecb8a981 [dracutlukscfg] Don't include keyfile in initramfs on unencrypted /boot.
This matches the fix in initcpiocfg and initramfscfg.
2016-11-19 02:32:31 +01:00
Kevin Kofler
d18eda219c [initramfscfg] Don't include keyfile in initramfs on unencrypted /boot.
This matches the fix in initcpiocfg.

I had to create an encrypt_hook_nokey that is a copy of encrypt_hook
without the part that copies the keyfile.
2016-11-19 02:32:26 +01:00
Teo Mrnjavac
b0a690256a Show warning. 2016-11-18 15:54:15 +01:00
Teo Mrnjavac
1c0fb2e4be Oops. 2016-11-18 15:54:15 +01:00
Teo Mrnjavac
efd93a0f82 Warn user about encrypted root with unencrypted /boot. 2016-11-18 15:54:00 +01:00
Teo Mrnjavac
08699206da Don't include keyfile in initramfs on unencrypted /boot. 2016-11-18 15:54:00 +01:00
Teo Mrnjavac
6376c39fe6 Bind-mount /run/udev in the chroot by default.
NOTE: this is absolutely necessary for grub-mkconfig's os-prober
instance to work.
2016-11-08 11:18:40 +01:00
Kevin Kofler
c7dd77c0f9 [bootloader] Fix UEFI firmware workaround for 32-bit UEFI.
On 32-bit UEFI (note that the bitness of the firmware is what matters
here, not the bitness of the distribution), instead of copying
grubx64.efi to bootx64.efi, copy grubia32.efi to bootia32.efi.

Patch by TeHMoroS from SparkyLinux.

CAL-403 #close
2016-11-06 03:39:15 +01:00
Kevin Kofler
3028855a6c [welcome] Use QNetworkAccessManager in checkHasInternet.
Use QNetworkAccessManager instead of raw QtDBus queries to
NetworkManager in RequirementsChecker::checkHasInternet(). This is much
simpler (i.e., less error-prone) and should be more portable (to, e.g.,
ConnMan).
2016-11-05 22:22:40 +01:00
Kevin Kofler
c0ebc91b15 [welcome] Fix RequirementsChecker::checkHasInternet().
The NetworkManager property is called "State", not "state". The call
was always failing, and the method was always returning true as a
result.
2016-11-05 20:34:46 +01:00
Kevin Kofler
5f5b38d148 [bootloader] Fix vfat_correct_case.
If the directory already existed, vfat_correct_case was returning only
the last part rather than the full path as it is supposed to.
2016-11-05 17:44:11 +01:00
Teo Mrnjavac
9581b803cc Bump. 2016-11-04 20:29:51 +01:00
Kevin Kofler
2f6274fa28 [unpackfs] Do not fail if rsync returns exit code 23.
Unfortunately, rsync returns exit code 23 (Partial transfer due to
error) if it cannot write extended attributes (with -X) because the
target file system does not support it, e.g., the FAT EFI system
partition. We need -X because distributions using file system
capabilities and/or SELinux require the extended attributes. But
distributions using SELinux may also have SELinux labels set on files
under /boot/efi, and rsync complains about those. The only clean way
would be to split the rsync into one with -X and --exclude /boot/efi and
a separate one without -X for /boot/efi, but only if /boot/efi is
actually an EFI system partition. For now, this hack will have to do.

See also:
https://bugzilla.redhat.com/show_bug.cgi?id=868755#c50
for the same issue in Anaconda, which uses a similar workaround.
2016-11-04 01:37:49 +01:00
Teo Mrnjavac
969ec3cd10 Allow try_install and try_remove entries in packages module. 2016-11-02 17:00:35 +01:00
Rohan Garg
7295085596 Make sure we also set a preferred Xsession 2016-11-02 13:34:45 +01:00
Teo Mrnjavac
9171fb7a77 Add option of updating packages db before perfoming package operations. 2016-11-02 13:04:32 +01:00
Kevin Kofler
9867d85924 [netinstall] Support selecting visible groups by default.
In other words, support:
  hidden: false
  selected: true
groups.

This was supposed to work according to README.md, but not actually
implemented. Now it should be working.
2016-11-02 05:59:01 +01:00
Rohan Garg
821730c1d4 Better handling for when the Autologin section already has things 2016-10-31 17:56:59 +01:00
Rohan Garg
9f8b6936e6 Use configparser to parse sddm.conf
Since sddm.conf follows the INI format we can use configparser
with a few added options to properly parse the config and write
it out instead of manually parsing each line which is slow and
prone to error.

For eg. The old code would fail to parse a conf which had no
commented out User key but where the user had configured autologin
in Calamares.
2016-10-31 17:17:59 +01:00
Kevin Kofler
06c353f170 README.md: sgdisk is no longer used. 2016-10-29 01:26:37 +02:00
Kevin Kofler
636d59ebf9 [partition] Use FlagEsp instead of sgdisk to scan for ESPs.
Address an old FIXME in
PartitionCoreModule::scanForEfiSystemPartitions(): Check the FlagEsp on
the Partition object (that KPMcore has been supporting since 2.1.0)
instead of running sgdisk.
2016-10-29 01:09:41 +02:00
Kevin Kofler
d8b6f94720 Set the ESP flag in partition rather than bootloader.
The manual partitioning setup was already requiring the user to check
the ESP flag for the EFI System Partition. Now the autopartitioning also
sets it directly (a one-line change). The sgdisk call in the bootloader
module is thus no longer necessary (it was only a workaround because
kpmcore < 2.1.0 did not support FlagEsp), so remove that snippet.

This fixes configurations such as NVME disks where splitting boot_device
into boot_device[-1:] and boot_device[:-1] is not the correct split
(because the partition gets a 2-letter suffix) (reported by demmm on
IRC).
2016-10-29 00:53:21 +02:00
Teo Mrnjavac
571724db83 Bump. 2016-10-28 11:26:34 +02:00
Teo Mrnjavac
f9e036b0ae Only add LUKS keyfile if relevant, and with a 15s timeout. 2016-10-28 10:18:18 +02:00
Philip
a1be43c959 [displaymanager] use same pattern for all str.format calls 2016-10-28 09:26:04 +02:00
Bernhard Landauer
7e67a2fc46 [displaymanager] add Deepin 2016-10-28 09:25:57 +02:00
Teo Mrnjavac
53c1371895 Add user to groups separately from useradd. 2016-10-27 15:27:43 +02:00
Kevin Kofler
699b57016d [grubcfg] Compare integers to integers, not strings.
target_env_call returns an integer, so do not compare its result to the
string "0".
2016-10-21 17:42:11 +02:00
V3n3RiX
8d2d8d04fc dracut : unlock encrypted swap if exists (#267)
* dracut : unlock encrypted swap if exists
* only check for swap_outer_uuid if dracut exists
2016-10-21 17:41:53 +02:00
V3n3RiX
eca367b9c0 Only write rd.luks.uuid if dracut is present and leave other initramfs generators clean (#266)
* add rd.luks.uuid to GRUB_CMDLINE (fixes unbootable system with dracut --nohostonly, and doesn't affect any other initramfs generators)

* typo

* only write rd.luks.uuid line if dracut is present, and leave other initramfs generators alone :D

* add missing = operator
2016-10-21 17:41:39 +02:00
V3n3RiX
57479d79a3 add rd.luks.uuid to GRUB_CMDLINE (fixes unbootable system with dracut… (#265)
* add rd.luks.uuid to GRUB_CMDLINE (fixes unbootable system with dracut --nohostonly, and doesn't affect any other initramfs generators)

* typo
2016-10-21 17:41:20 +02:00
Kevin Kofler
f1ab1ca3dd [dracutlukscfg] New module: pre-configuration for dracut+LUKS.
Add a dracutlukscfg module to write a
/etc/dracut.conf.d/calamares-luks.conf file for LUKS full disk
encryption support with Dracut.

You should run:

* partition
* luksbootkeyfile
* dracutlukscfg
* dracut

in that order (not necessarily in immediate sequence). The
luksopenswaphook module is not used with Dracut.
2016-10-21 17:40:56 +02:00
David McKinney
be8f310672 [initramfscfg] New module: pre-configuration for update-initramfs.
Added an initramfscfg module to handle pre-configuration for the Debian
update-initramfs, such as installing hooks (needed for luks/FDE support
on Debian-based distros).

Closes #254. (Cherry-picked from the pull request.)
2016-10-21 17:39:54 +02:00
Kevin Kofler
c6e591c9c7 [fstab] Write configurable options to crypttab (default: luks).
fstab.conf: Add a new "crypttabOptions" option that defaults to "luks".
            Document that for Debian and Debian-based distributions, the
            setting should be changed to "luks,keyscript=/bin/cat".

main.py: Append the options from the above setting to the end of every
         line in crypttab.

At least the "luks" option should always be there, because there may be
different encryption types. The Debian initramfs-tools also require the
Debian-specific keyscript option and will otherwise ignore the keyfile
entirely (see pull request #254).
2016-10-21 17:39:37 +02:00
Kevin Kofler
62f94e5ce9 [fstab] Do not omit "/" from crypttab.
At least the Debian update-initramfs needs the entry to be there (see
pull request #254). Dracut will probably need it too. And logically, it
should be there.
2016-10-21 17:39:24 +02:00
Kevin Kofler
9d15b61331 New dummycpp C++ job module (ported from dummypython). 2016-10-21 17:38:48 +02:00
Kevin Kofler
32e05000f6 Add support for C++/Qt batch job plugins
These job plugins work similarly to view modules, with the following
differences:

* These jobs need to link only libcalamares, not libcalamaresui. For
  this reason, PluginFactory was moved from libcalamaresui to
  libcalamares. (It depends only on QtCore.)

* Instead of deriving from ViewModule, derive from CppJob (which is a
  subclass of Job).

* Like process and Python jobs, a job plugin is a single job, whereas a
  ViewModule can generate a whole list of jobs.

The CppJob and CppJobModule classes are new. In Module::fromDescriptor,
the combination type=job, intf=qtplugin is now supported and mapped to
CppJobModule.
2016-10-21 00:41:55 +02:00
Kevin Kofler
165fe26996 [grubcfg] Fix mismatched quoting and escaping.
If we use .replace("'", "'\\''") for escaping, we also need to use
single quotes, not double quotes.

This was broken by the port from '%' to format, which also randomly
changed quoting characters for no good reason. Changing the outer ones
does not matter, but \" or ' within a string is not the same thing!
2016-10-16 18:49:31 +02:00
Teo Mrnjavac
68dcbf95f3 Bump. 2016-10-14 16:11:44 +02:00
Teo Mrnjavac
a672a4fdb9 Use the target system's boot name in partitioning summary widget. 2016-10-14 15:56:07 +02:00
Teo Mrnjavac
13507e81ad Allow disabling automated LUKS modes. 2016-09-26 13:15:53 +02:00
Teo Mrnjavac
f2fe7a83c6 Make writeEtcDefaultKeyboard an option in keyboard.conf. 2016-09-26 10:59:31 +02:00
Kevin Kofler
effc8b4496 Fix locale filtering for UTF-8 on Fedora.
locale -a returns the locales using ".utf8" names rather than ".UTF-8".
The case-insensitive match does not help because it is "utf8" rather
than "UTF-8". So we need to match both with and without the dash.
2016-09-26 01:48:28 +02:00
Teo Mrnjavac
c0c51ad51d Remove target resolv.conf before proceeding. 2016-09-22 15:44:14 +02:00
Teo Mrnjavac
9460e53233 Add support for writing keymap data to /etc/default/keyboard. 2016-09-22 12:33:43 +02:00
Kevin Kofler
114bd6ae63 users: Drop dependency on chfn. (#260)
Pass the full name directly to useradd instead, using the "-c" (comment)
parameter, which is "currently used as the field for the user's full
name" according to the documentation.

The chfn utility is no longer installed by default on current Fedora
releases due to its dependency on libuser. (They split out chfn and chsh
from util-linux into an optional subpackage.) It could be added as a
dependency of Calamares, but since it is needed inside the chroot, it
has to be on the base live image, not the overlay. Thus, to allow
testing Calamares with a simple "dnf install calamares" again, the
dependency needs to go away. And it is unnecessary anyway.
2016-09-20 15:03:13 +02:00
Teo Mrnjavac
77fb264129 Fix VFAT filename handling in bootloader module.
CAL-385 #close
2016-09-16 16:30:17 +02:00
Teo Mrnjavac
0c29233062 Warning in debug output when the RequirementsChecker is misconfigured.
CAL-390 #close
2016-09-16 11:00:53 +02:00
85 changed files with 1484 additions and 200 deletions

View File

@@ -102,7 +102,7 @@ set( CALAMARES_TRANSLATION_LANGUAGES ar ast bg ca cs_CZ da de el en en_GB es_MX
### Bump version here
set( CALAMARES_VERSION_MAJOR 2 )
set( CALAMARES_VERSION_MINOR 4 )
set( CALAMARES_VERSION_PATCH 1 )
set( CALAMARES_VERSION_PATCH 6 )
set( CALAMARES_VERSION_RC 0 )
set( CALAMARES_VERSION ${CALAMARES_VERSION_MAJOR}.${CALAMARES_VERSION_MINOR}.${CALAMARES_VERSION_PATCH} )

View File

@@ -6,7 +6,7 @@ function( calamares_add_plugin )
set( NAME ${ARGV0} )
set( options NO_INSTALL SHARED_LIB )
set( oneValueArgs NAME TYPE EXPORT_MACRO RESOURCES )
set( multiValueArgs SOURCES UI LINK_LIBRARIES COMPILE_DEFINITIONS )
set( multiValueArgs SOURCES UI LINK_LIBRARIES LINK_PRIVATE_LIBRARIES COMPILE_DEFINITIONS )
cmake_parse_arguments( PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
set( PLUGIN_NAME ${NAME} )
set( PLUGIN_DESTINATION ${CMAKE_INSTALL_LIBDIR}/calamares/modules/${PLUGIN_NAME} )
@@ -22,6 +22,7 @@ function( calamares_add_plugin )
if( NOT CMAKE_BUILD_TYPE STREQUAL "Release" )
message( " ${Green}TYPE:${ColorReset} ${PLUGIN_TYPE}" )
message( " ${Green}LINK_LIBRARIES:${ColorReset} ${PLUGIN_LINK_LIBRARIES}" )
message( " ${Green}LINK_PRIVATE_LIBRARIES:${ColorReset} ${PLUGIN_LINK_PRIVATE_LIBRARIES}" )
# message( " ${Green}SOURCES:${ColorReset} ${PLUGIN_SOURCES}" )
# message( " ${Green}UI:${ColorReset} ${PLUGIN_UI}" )
# message( " ${Green}EXPORT_MACRO:${ColorReset} ${PLUGIN_EXPORT_MACRO}" )
@@ -60,6 +61,10 @@ function( calamares_add_plugin )
list( APPEND calamares_add_library_args "LINK_LIBRARIES" "${PLUGIN_LINK_LIBRARIES}" )
endif()
if( PLUGIN_LINK_PRIVATE_LIBRARIES )
list( APPEND calamares_add_library_args "LINK_PRIVATE_LIBRARIES" "${PLUGIN_LINK_PRIVATE_LIBRARIES}" )
endif()
if( PLUGIN_COMPILE_DEFINITIONS )
list( APPEND calamares_add_library_args "COMPILE_DEFINITIONS" ${PLUGIN_COMPILE_DEFINITIONS} )
endif()

View File

@@ -28,10 +28,8 @@ Modules:
* extra-cmake-modules
* KF5: KCoreAddons, KConfig, KI18n, KIconThemes, KIO, KService
* KPMcore >= 2.2
* sgdisk
* bootloader:
* systemd-boot or GRUB
* sgdisk
* unpackfs:
* squashfs-tools
* rsync

View File

@@ -67,6 +67,7 @@ sequence:
- users
- summary
- exec:
# - dummycpp
# - dummyprocess
# - dummypython
- partition
@@ -79,6 +80,7 @@ sequence:
- localecfg
# - luksbootkeyfile
# - luksopenswaphookcfg
# - dracutlukscfg
- initcpiocfg
- initcpio
- users

View File

@@ -59,12 +59,12 @@ endif()
qt5_use_modules( calamares_bin Core Widgets )
target_link_libraries( calamares_bin
${CALAMARES_LIBRARIES}
calamaresui
Qt5::Core
Qt5::Widgets
yaml-cpp
${LINK_LIBRARIES}
PRIVATE
${CALAMARES_LIBRARIES}
calamaresui
Qt5::Core
Qt5::Widgets
${LINK_LIBRARIES}
)
install( TARGETS calamares_bin

View File

@@ -11,6 +11,7 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../calamares/CalamaresVersion.h.in
${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersion.h )
set( libSources
CppJob.cpp
GlobalStorage.cpp
Job.cpp
JobQueue.cpp
@@ -24,6 +25,7 @@ set( libSources
utils/CalamaresUtils.cpp
utils/CalamaresUtilsSystem.cpp
utils/Logger.cpp
utils/PluginFactory.cpp
utils/Retranslator.cpp
)

View File

@@ -0,0 +1,45 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
* Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CppJob.h"
namespace Calamares
{
CppJob::CppJob( QObject* parent )
: Job( parent )
{}
CppJob::~CppJob()
{}
void
CppJob::setModuleInstanceKey( const QString& instanceKey )
{
m_instanceKey = instanceKey;
}
void
CppJob::setConfigurationMap( const QVariantMap& configurationMap )
{}
}

51
src/libcalamares/CppJob.h Normal file
View File

@@ -0,0 +1,51 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALAMARES_CPPJOB_H
#define CALAMARES_CPPJOB_H
#include <QObject>
#include <QVariant>
#include "DllMacro.h"
#include "Typedefs.h"
#include "Job.h"
namespace Calamares
{
class DLLEXPORT CppJob : public Job
{
Q_OBJECT
public:
explicit CppJob( QObject* parent = nullptr );
virtual ~CppJob();
void setModuleInstanceKey( const QString& instanceKey );
QString moduleInstanceKey() const { return m_instanceKey; }
virtual void setConfigurationMap( const QVariantMap& configurationMap );
protected:
QString m_instanceKey;
};
}
#endif // CALAMARES_CPPJOB_H

View File

@@ -23,7 +23,7 @@
#ifndef CALAMARESPLUGINFACTORY_H
#define CALAMARESPLUGINFACTORY_H
#include "UiDllMacro.h"
#include "DllMacro.h"
#include <QtCore/QObject>
#include <QtCore/QVariant>
@@ -196,7 +196,7 @@ namespace Calamares
* \author Matthias Kretz <kretz@kde.org>
* \author Bernhard Loos <nhuh.put@web.de>
*/
class UIDLLEXPORT PluginFactory : public QObject
class DLLEXPORT PluginFactory : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(PluginFactory)

View File

@@ -1,6 +1,7 @@
set( CALAMARESUI_LIBRARY_TARGET calamaresui )
list( APPEND ${CALAMARESUI_LIBRARY_TARGET}_SOURCES
modulesystem/CppJobModule.cpp
modulesystem/Module.cpp
modulesystem/ModuleManager.cpp
modulesystem/ProcessJobModule.cpp
@@ -14,8 +15,6 @@ list( APPEND ${CALAMARESUI_LIBRARY_TARGET}_SOURCES
utils/qjsonmodel.cpp
utils/qjsonitem.cpp
utils/PluginFactory.cpp
viewpages/AbstractPage.cpp
viewpages/ViewStep.cpp
@@ -44,10 +43,11 @@ calamares_add_library( ${CALAMARESUI_LIBRARY_TARGET}
SOURCES ${${CALAMARESUI_LIBRARY_TARGET}_SOURCES}
UI ${${CALAMARESUI_LIBRARY_TARGET}_UI}
EXPORT_MACRO UIDLLEXPORT_PRO
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
yaml-cpp
Qt5::Svg
Qt5::QuickWidgets
Qt5::QuickWidgets
${OPTIONAL_PRIVATE_LIBRARIES}
RESOURCES libcalamaresui.qrc
EXPORT CalamaresLibraryDepends
VERSION ${CALAMARES_VERSION_SHORT}

View File

@@ -0,0 +1,128 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
* Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CppJobModule.h"
#include "utils/PluginFactory.h"
#include "utils/Logger.h"
#include "CppJob.h"
#include <QDir>
#include <QPluginLoader>
namespace Calamares {
Module::Type
CppJobModule::type() const
{
return Job;
}
Module::Interface
CppJobModule::interface() const
{
return QtPlugin;
}
void
CppJobModule::loadSelf()
{
if ( m_loader )
{
PluginFactory* pf = qobject_cast< PluginFactory* >( m_loader->instance() );
if ( !pf )
{
cDebug() << Q_FUNC_INFO << m_loader->errorString();
return;
}
CppJob *cppJob = pf->create< Calamares::CppJob >();
if ( !cppJob )
{
cDebug() << Q_FUNC_INFO << m_loader->errorString();
return;
}
// cDebug() << "CppJobModule loading self for instance" << instanceKey()
// << "\nCppJobModule at address" << this
// << "\nCalamares::PluginFactory at address" << pf
// << "\nCppJob at address" << cppJob;
cppJob->setModuleInstanceKey( instanceKey() );
cppJob->setConfigurationMap( m_configurationMap );
m_job = Calamares::job_ptr( static_cast< Calamares::Job * >( cppJob ) );
m_loaded = true;
cDebug() << "CppJobModule" << instanceKey() << "loading complete.";
}
}
QList< job_ptr >
CppJobModule::jobs() const
{
return QList< job_ptr >() << m_job;
}
void
CppJobModule::initFrom( const QVariantMap& moduleDescriptor )
{
Module::initFrom( moduleDescriptor );
QDir directory( location() );
QString load;
if ( !moduleDescriptor.value( "load" ).toString().isEmpty() )
{
load = moduleDescriptor.value( "load" ).toString();
load = directory.absoluteFilePath( load );
}
// If a load path is not specified, we look for a plugin to load in the directory.
if ( load.isEmpty() || !QLibrary::isLibrary( load ) )
{
const QStringList ls = directory.entryList( QStringList{ "*.so" } );
if ( !ls.isEmpty() )
{
for ( QString entry : ls )
{
entry = directory.absoluteFilePath( entry );
if ( QLibrary::isLibrary( entry ) )
{
load = entry;
break;
}
}
}
}
m_loader = new QPluginLoader( load );
}
CppJobModule::CppJobModule()
: Module()
, m_loader( nullptr )
{
}
CppJobModule::~CppJobModule()
{
delete m_loader;
}
} // namespace Calamares

View File

@@ -0,0 +1,53 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
* Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALAMARES_CPPJOBMODULE_H
#define CALAMARES_CPPJOBMODULE_H
#include "UiDllMacro.h"
#include "Module.h"
class QPluginLoader;
namespace Calamares {
class UIDLLEXPORT CppJobModule : public Module
{
public:
Type type() const override;
Interface interface() const override;
void loadSelf() override;
QList< job_ptr > jobs() const override;
protected:
void initFrom( const QVariantMap& moduleDescriptor ) override;
private:
friend class Module; //so only the superclass can instantiate
explicit CppJobModule();
virtual ~CppJobModule();
QPluginLoader* m_loader;
job_ptr m_job;
};
} // namespace Calamares
#endif // CALAMARES_CPPJOBMODULE_H

View File

@@ -19,6 +19,7 @@
#include "Module.h"
#include "ProcessJobModule.h"
#include "CppJobModule.h"
#include "ViewModule.h"
#include "utils/CalamaresUtils.h"
#include "utils/YamlUtils.h"
@@ -76,7 +77,11 @@ Module::fromDescriptor( const QVariantMap& moduleDescriptor,
}
else if ( typeString == "job" )
{
if ( intfString == "process" )
if ( intfString == "qtplugin" )
{
m = new CppJobModule();
}
else if ( intfString == "process" )
{
m = new ProcessJobModule();
}

View File

@@ -220,21 +220,24 @@ def install_grub(efi_directory, fw_type):
"--force"])
# VFAT is weird, see issue CAL-385
efi_directory_firmware = case_insensitive_subdir(efi_directory,
["EFI", "Efi", "efi"])
if not efi_directory_firmware:
efi_directory_firmware = os.path.join(efi_directory, "EFI")
efi_directory_firmware = os.path.join(efi_directory, "EFI")
if os.path.exists(efi_directory_firmware):
efi_directory_firmware = vfat_correct_case(efi_directory, "EFI")
efi_boot_directory = case_insensitive_subdir(efi_directory_firmware,
["Boot", "boot", "BOOT"])
if not efi_boot_directory:
efi_boot_directory = os.path.join(efi_directory_firmware, "boot")
efi_boot_directory = os.path.join(efi_directory_firmware, "boot")
if os.path.exists(efi_boot_directory):
efi_boot_directory = vfat_correct_case(efi_directory_firmware, "boot")
else:
check_target_env_call(["mkdir", "-p", efi_boot_directory])
# Workaround for some UEFI firmwares
efi_file_source = {"32": os.path.join(efi_directory_firmware, efi_bootloader_id, "grubia32.efi"),
"64": os.path.join(efi_directory_firmware, efi_bootloader_id, "grubx64.efi")}
efi_file_target = {"32": os.path.join(efi_boot_directory, "bootia32.efi"),
"64": os.path.join(efi_boot_directory, "bootx64.efi")}
check_target_env_call(["cp",
os.path.join(efi_directory_firmware, efi_bootloader_id, "grubx64.efi"),
os.path.join(efi_boot_directory, "bootx64.efi")])
efi_file_source[efi_bitness],
efi_file_target[efi_bitness]])
else:
print("Bootloader: grub (bios)")
boot_loader = libcalamares.globalstorage.value("bootLoader")
@@ -251,15 +254,15 @@ def install_grub(efi_directory, fw_type):
libcalamares.job.configuration["grubCfg"]])
def case_insensitive_subdir(parent, candidate_dirnames):
for dirname in candidate_dirnames:
if os.path.isdir(os.path.join(parent, dirname)):
return os.path.join(parent, dirname)
return ""
def vfat_correct_case(parent, name):
for candidate in os.listdir(parent):
if name.lower() == candidate.lower():
return os.path.join(parent, candidate)
return os.path.join(parent, name)
def prepare_bootloader(fw_type):
""" Prepares bootloader and set proper flags to EFI boot partition (esp,boot).
""" Prepares bootloader.
Based on value 'efi_boot_loader', it either calls systemd-boot or grub to be installed.
:param fw_type:
@@ -268,33 +271,6 @@ def prepare_bootloader(fw_type):
efi_boot_loader = libcalamares.job.configuration["efiBootLoader"]
efi_directory = libcalamares.globalstorage.value("efiSystemPartition")
if fw_type == "efi":
partitions = libcalamares.globalstorage.value("partitions")
boot_p = ""
device = ""
for partition in partitions:
if partition["mountPoint"] == efi_directory:
boot_device = partition["device"]
boot_p = boot_device[-1:]
device = boot_device[:-1]
if not boot_p or not device:
return ("EFI directory \"{!s}\" not found!".format(efi_directory),
"Boot partition: \"{!s}\"".format(boot_p),
"Boot device: \"{!s}\"".format(device))
else:
print("EFI directory: \"{!s}\"".format(efi_directory))
print("Boot partition: \"{!s}\"".format(boot_p))
print("Boot device: \"{!s}\"".format(device))
if not device:
print("WARNING: no EFI system partition or EFI system partition mount point not set.")
print(" >>> no EFI bootloader will be installed <<<")
return None
print("Set 'EF00' flag")
subprocess.call(["sgdisk", "--typecode={!s}:EF00".format(boot_p), "{!s}".format(device)])
if efi_boot_loader == "systemd-boot" and fw_type == "efi":
install_systemd_boot(efi_directory)
else:

View File

@@ -3,7 +3,7 @@
#
# === This file is part of Calamares - <http://github.com/calamares> ===
#
# Copyright 2014-2015, Philip Müller <philm@manjaro.org>
# Copyright 2014-2016, Philip Müller <philm@manjaro.org>
# Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
# Copyright 2014, Kevin Kofler <kevin.kofler@chello.at>
#
@@ -24,6 +24,7 @@ import os
import collections
import re
import libcalamares
import configparser
DesktopEnvironment = collections.namedtuple('DesktopEnvironment', ['executable', 'desktop_file'])
@@ -44,6 +45,7 @@ desktop_environments = [
DesktopEnvironment('/usr/bin/budgie-session', 'budgie-session'),
DesktopEnvironment('/usr/bin/budgie-desktop', 'budgie-desktop'),
DesktopEnvironment('/usr/bin/i3', 'i3'),
DesktopEnvironment('/usr/bin/startdde', 'deepin'),
DesktopEnvironment('/usr/bin/openbox-session', 'openbox')
]
@@ -252,34 +254,29 @@ def set_autologin(username, displaymanagers, default_desktop_environment, root_m
# Systems with Sddm as Desktop Manager
sddm_conf_path = os.path.join(root_mount_point, "etc/sddm.conf")
sddm_config = configparser.ConfigParser()
# Make everything case sensitive
sddm_config.optionxform = str
if os.path.isfile(sddm_conf_path):
libcalamares.utils.debug('SDDM config file exists')
else:
libcalamares.utils.check_target_env_call(["sh", "-c", "sddm --example-config > /etc/sddm.conf"])
sddm_config.read(sddm_conf_path)
text = []
autologin_section = {}
if 'Autologin' in sddm_config:
autologin_section = sddm_config['Autologin']
with open(sddm_conf_path, 'r') as sddm_conf:
text = sddm_conf.readlines()
if do_autologin:
autologin_section['User'] = username
elif 'User' in autologin_section:
del autologin_section['User']
with open(sddm_conf_path, 'w') as sddm_conf:
for line in text:
# User= line, possibly commented out
if re.match('\\s*(?:#\\s*)?User=', line):
if do_autologin:
line = 'User={}\n'.format(username)
else:
line = '#User=\n'
if default_desktop_environment is not None:
autologin_section['Session'] = default_desktop_environment.desktop_file
# Session= line, commented out or with empty value
if re.match('\\s*#\\s*Session=|\\s*Session=$', line):
if default_desktop_environment is not None:
if do_autologin:
line = 'Session={}.desktop\n'.format(default_desktop_environment.desktop_file)
else:
line = '#Session={}.desktop\n'.format(default_desktop_environment.desktop_file)
sddm_config['Autologin'] = autologin_section
sddm_conf.write(line)
with open(sddm_conf_path, 'w') as sddm_config_file:
sddm_config.write(sddm_config_file, space_around_delimiters=False)
return None
@@ -350,6 +347,11 @@ def run():
if default_desktop_environment is not None:
os.system("sed -i -e \"s/^.*user-session=.*/user-session={!s}/\" {!s}/etc/lightdm/lightdm.conf".format(
default_desktop_environment.desktop_file, root_mount_point))
if default_desktop_environment.desktop_file == "deepin":
os.system("sed -i -e \"s/^.greeter-session=.*/greeter-session=lightdm-deepin-greeter/\" {!s}/etc/lightdm/lightdm.conf".format(
root_mount_point))
else:
libcalamares.utils.debug("lightdm selected but not installed")
displaymanagers.remove("lightdm")

View File

@@ -0,0 +1,9 @@
calamares_add_plugin( dracutlukscfg
TYPE job
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
DracutLuksCfgJob.cpp
LINK_PRIVATE_LIBRARIES
calamares
SHARED_LIB
)

View File

@@ -0,0 +1,168 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DracutLuksCfgJob.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QTextStream>
#include "CalamaresVersion.h"
#include "JobQueue.h"
#include "GlobalStorage.h"
#include "utils/Logger.h"
// static
const QString DracutLuksCfgJob::CONFIG_FILE = QStringLiteral( "/etc/dracut.conf.d/calamares-luks.conf" );
// static
const char *DracutLuksCfgJob::CONFIG_FILE_HEADER =
"# Configuration file automatically written by the Calamares system installer\n"
"# (This file is written once at install time and should be safe to edit.)\n"
"# Enables support for LUKS full disk encryption with single sign on from GRUB.\n"
"\n";
// static
const char *DracutLuksCfgJob::CONFIG_FILE_CRYPTTAB_KEYFILE_LINE =
"# force installing /etc/crypttab even if hostonly=\"no\", install the keyfile\n"
"install_items+=\" /etc/crypttab /crypto_keyfile.bin \"\n";
// static
const char *DracutLuksCfgJob::CONFIG_FILE_CRYPTTAB_LINE =
"# force installing /etc/crypttab even if hostonly=\"no\"\n"
"install_items+=\" /etc/crypttab \"\n";
// static
const QString DracutLuksCfgJob::CONFIG_FILE_SWAPLINE = QStringLiteral( "# enable automatic resume from swap\nadd_device+=\" /dev/disk/by-uuid/%1 \"\n" );
// static
QString
DracutLuksCfgJob::rootMountPoint()
{
Calamares::GlobalStorage *globalStorage = Calamares::JobQueue::instance()->globalStorage();
return globalStorage->value( QStringLiteral( "rootMountPoint" ) ).toString();
}
// static
QVariantList
DracutLuksCfgJob::partitions()
{
Calamares::GlobalStorage *globalStorage = Calamares::JobQueue::instance()->globalStorage();
return globalStorage->value( QStringLiteral( "partitions" ) ).toList();
}
// static
bool
DracutLuksCfgJob::isRootEncrypted()
{
const QVariantList partitions = DracutLuksCfgJob::partitions();
for ( const QVariant &partition : partitions )
{
QVariantMap partitionMap = partition.toMap();
QString mountPoint = partitionMap.value( QStringLiteral( "mountPoint" ) ).toString();
if ( mountPoint == QStringLiteral( "/" ) )
return partitionMap.contains( QStringLiteral( "luksMapperName" ) );
}
return false;
}
// static
bool
DracutLuksCfgJob::hasUnencryptedSeparateBoot()
{
const QVariantList partitions = DracutLuksCfgJob::partitions();
for ( const QVariant &partition : partitions )
{
QVariantMap partitionMap = partition.toMap();
QString mountPoint = partitionMap.value( QStringLiteral( "mountPoint" ) ).toString();
if ( mountPoint == QStringLiteral( "/boot" ) )
return !partitionMap.contains( QStringLiteral( "luksMapperName" ) );
}
return false;
}
// static
QString
DracutLuksCfgJob::swapOuterUuid()
{
const QVariantList partitions = DracutLuksCfgJob::partitions();
for ( const QVariant &partition : partitions )
{
QVariantMap partitionMap = partition.toMap();
QString fsType = partitionMap.value( QStringLiteral( "fs" ) ).toString();
if ( fsType == QStringLiteral( "linuxswap" ) && partitionMap.contains( QStringLiteral( "luksMapperName" ) ) )
return partitionMap.value( QStringLiteral( "luksUuid" ) ).toString();
}
return QString();
}
DracutLuksCfgJob::DracutLuksCfgJob( QObject* parent )
: Calamares::CppJob( parent )
{
}
DracutLuksCfgJob::~DracutLuksCfgJob()
{
}
QString
DracutLuksCfgJob::prettyName() const
{
if ( isRootEncrypted() )
return tr( "Write LUKS configuration for Dracut to %1" ).arg( CONFIG_FILE );
else
return tr( "Skip writing LUKS configuration for Dracut: \"/\" partition is not encrypted" );
}
Calamares::JobResult
DracutLuksCfgJob::exec()
{
if ( isRootEncrypted() )
{
const QString realConfigFilePath = rootMountPoint() + CONFIG_FILE;
cDebug() << "[DRACUTLUKSCFG]: Writing" << realConfigFilePath;
QDir( QStringLiteral( "/" ) ).mkpath( QFileInfo( realConfigFilePath ).absolutePath() );
QFile configFile( realConfigFilePath );
if ( ! configFile.open( QIODevice::WriteOnly | QIODevice::Text ) )
{
cDebug() << "[DRACUTLUKSCFG]: Failed to open" << realConfigFilePath;
return Calamares::JobResult::error( tr( "Failed to open %1" ).arg( realConfigFilePath ) );
}
QTextStream outStream( &configFile );
outStream << CONFIG_FILE_HEADER
<< ( hasUnencryptedSeparateBoot() ? CONFIG_FILE_CRYPTTAB_LINE
: CONFIG_FILE_CRYPTTAB_KEYFILE_LINE );
const QString swapOuterUuid = DracutLuksCfgJob::swapOuterUuid();
if ( ! swapOuterUuid.isEmpty() )
{
cDebug() << "[DRACUTLUKSCFG]: Swap outer UUID" << swapOuterUuid;
outStream << CONFIG_FILE_SWAPLINE.arg( swapOuterUuid ).toLatin1();
}
cDebug() << "[DRACUTLUKSCFG]: Wrote config to" << realConfigFilePath;
} else
cDebug() << "[DRACUTLUKSCFG]: / not encrypted, skipping";
return Calamares::JobResult::ok();
}
CALAMARES_PLUGIN_FACTORY_DEFINITION( DracutLuksCfgJobFactory, registerPlugin<DracutLuksCfgJob>(); )

View File

@@ -0,0 +1,59 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DRACUTLUKSCFGJOB_H
#define DRACUTLUKSCFGJOB_H
#include <QObject>
#include <QVariantMap>
#include <CppJob.h>
#include <utils/PluginFactory.h>
#include <PluginDllMacro.h>
class PLUGINDLLEXPORT DracutLuksCfgJob : public Calamares::CppJob
{
Q_OBJECT
public:
explicit DracutLuksCfgJob( QObject* parent = nullptr );
virtual ~DracutLuksCfgJob();
QString prettyName() const override;
Calamares::JobResult exec() override;
private:
static const QString CONFIG_FILE;
static const char *CONFIG_FILE_HEADER;
static const char *CONFIG_FILE_CRYPTTAB_KEYFILE_LINE;
static const char *CONFIG_FILE_CRYPTTAB_LINE;
static const QString CONFIG_FILE_SWAPLINE;
static QString rootMountPoint();
static QVariantList partitions();
static bool isRootEncrypted();
static bool hasUnencryptedSeparateBoot();
static QString swapOuterUuid();
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( DracutLuksCfgJobFactory )
#endif // DRACUTLUKSCFGJOB_H

View File

@@ -0,0 +1,7 @@
# Module metadata file for dracutlukscfg job
# Syntax is YAML 1.2
---
type: "job"
name: "dracutlukscfg"
interface: "qtplugin"
load: "libcalamares_job_dracutlukscfg.so"

View File

@@ -0,0 +1,9 @@
calamares_add_plugin( dummycpp
TYPE job
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
DummyCppJob.cpp
LINK_PRIVATE_LIBRARIES
calamares
SHARED_LIB
)

View File

@@ -0,0 +1,144 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org> (original dummypython code)
* Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DummyCppJob.h"
#include <QProcess>
#include <QDateTime>
#include <QThread>
#include "CalamaresVersion.h"
#include "JobQueue.h"
#include "GlobalStorage.h"
#include "utils/Logger.h"
DummyCppJob::DummyCppJob( QObject* parent )
: Calamares::CppJob( parent )
{
}
DummyCppJob::~DummyCppJob()
{
}
QString
DummyCppJob::prettyName() const
{
return tr( "Dummy C++ Job" );
}
static QString variantListToString( const QVariantList& variantList );
static QString variantMapToString( const QVariantMap& variantMap );
static QString variantHashToString( const QVariantHash& variantHash );
static QString
variantToString( const QVariant& variant )
{
switch ( variant.type() )
{
case QVariant::Map:
return variantMapToString( variant.toMap() );
case QVariant::Hash:
return variantHashToString( variant.toHash() );
case QVariant::List:
case QVariant::StringList:
return variantListToString( variant.toList() );
default:
return variant.toString();
}
}
static QString
variantListToString( const QVariantList& variantList )
{
QStringList result;
for ( const QVariant& variant : variantList )
result.append( variantToString( variant ) );
return '{' + result.join(',') + '}';
}
static QString
variantMapToString( const QVariantMap& variantMap )
{
QStringList result;
for ( auto it = variantMap.constBegin(); it != variantMap.constEnd(); ++it )
result.append( it.key() + '=' + variantToString( it.value() ) );
return '[' + result.join(',') + ']';
}
static QString
variantHashToString( const QVariantHash& variantHash )
{
QStringList result;
for ( auto it = variantHash.constBegin(); it != variantHash.constEnd(); ++it )
result.append( it.key() + '=' + variantToString( it.value() ) );
return '<' + result.join(',') + '>';
}
Calamares::JobResult
DummyCppJob::exec()
{
// Ported from dummypython
QProcess::execute( "/bin/sh", QStringList() << "-c" << "touch ~/calamares-dummycpp" );
QString accumulator = QDateTime::currentDateTimeUtc().toString( Qt::ISODate ) + '\n';
accumulator += QStringLiteral( "Calamares version: " ) + CALAMARES_VERSION_SHORT + '\n';
accumulator += QStringLiteral( "This job's name: " ) + prettyName() + '\n';
accumulator += QStringLiteral( "Configuration map: %1\n" ).arg( variantMapToString( m_configurationMap ) );
accumulator += QStringLiteral( " *** globalstorage test ***\n" );
Calamares::GlobalStorage *globalStorage = Calamares::JobQueue::instance()->globalStorage();
accumulator += QStringLiteral( "lala: " ) + (globalStorage->contains( "lala" ) ? QStringLiteral( "true" ) : QStringLiteral( "false" )) + '\n';
accumulator += QStringLiteral( "foo: " ) + (globalStorage->contains( "foo" ) ? QStringLiteral( "true" ) : QStringLiteral( "false" )) + '\n';
accumulator += QStringLiteral( "count: " ) + QString::number( globalStorage->count() ) + '\n';
globalStorage->insert( "item2", "value2" );
globalStorage->insert( "item3", 3 );
accumulator += QStringLiteral( "keys: %1\n" ).arg( globalStorage->keys().join( ',' ) );
accumulator += QStringLiteral( "remove: %1\n" ).arg( QString::number( globalStorage->remove( "item2" ) ) );
accumulator += QStringLiteral( "values: %1 %2 %3\n" ).arg(
globalStorage->value( "foo" ).toString(),
globalStorage->value( "item2" ).toString(),
globalStorage->value( "item3" ).toString() );
emit progress( 0.1 );
cDebug() << "[DUMMYCPP]: " << accumulator;
QThread::sleep( 3 );
return Calamares::JobResult::ok();
}
void
DummyCppJob::setConfigurationMap( const QVariantMap& configurationMap )
{
m_configurationMap = configurationMap;
}
CALAMARES_PLUGIN_FACTORY_DEFINITION( DummyCppJobFactory, registerPlugin<DummyCppJob>(); )

View File

@@ -0,0 +1,51 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DUMMYCPPJOB_H
#define DUMMYCPPJOB_H
#include <QObject>
#include <QVariantMap>
#include <CppJob.h>
#include <utils/PluginFactory.h>
#include <PluginDllMacro.h>
class PLUGINDLLEXPORT DummyCppJob : public Calamares::CppJob
{
Q_OBJECT
public:
explicit DummyCppJob( QObject* parent = nullptr );
virtual ~DummyCppJob();
QString prettyName() const override;
Calamares::JobResult exec() override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
private:
QVariantMap m_configurationMap;
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( DummyCppJobFactory )
#endif // DUMMYCPPJOB_H

View File

@@ -0,0 +1,18 @@
---
syntax: "YAML map of anything"
example:
whats_this: "module-specific configuration"
from_where: "dummycpp.conf"
a_list:
- "item1"
- "item2"
- "item3"
- "item4"
a_list_of_maps:
- name: "an Item"
contents:
- "an element"
- "another element"
- name: "another item"
contents:
- "not much"

View File

@@ -0,0 +1,7 @@
# Module metadata file for dummycpp job
# Syntax is YAML 1.2
---
type: "job"
name: "dummycpp"
interface: "qtplugin"
load: "libcalamares_job_dummycpp.so"

View File

@@ -7,7 +7,7 @@ calamares_add_plugin( finished
FinishedPage.cpp
UI
FinishedPage.ui
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
calamaresui
SHARED_LIB
)

View File

@@ -8,3 +8,6 @@ ssdExtraMountOptions:
xfs: discard
swap: discard
btrfs: discard,compress=lzo
crypttabOptions: luks
# For Debian and Debian-based distributions, change the above line to:
# crypttabOptions: luks,keyscript=/bin/cat

View File

@@ -21,6 +21,7 @@
import os
import re
import subprocess
import libcalamares
@@ -102,11 +103,13 @@ class FstabGenerator(object):
:param mount_options:
:param ssd_extra_mount_options:
"""
def __init__(self, partitions, root_mount_point, mount_options, ssd_extra_mount_options):
def __init__(self, partitions, root_mount_point, mount_options,
ssd_extra_mount_options, crypttab_options):
self.partitions = partitions
self.root_mount_point = root_mount_point
self.mount_options = mount_options
self.ssd_extra_mount_options = ssd_extra_mount_options
self.crypttab_options = crypttab_options
self.ssd_disks = set()
self.root_is_ssd = False
@@ -152,21 +155,20 @@ class FstabGenerator(object):
if not mapper_name or not luks_uuid:
return None
if mount_point == "/":
return None
return dict(
name=mapper_name,
device="UUID=" + luks_uuid,
password="/crypto_keyfile.bin",
options=self.crypttab_options,
)
def print_crypttab_line(self, dct, file=None):
""" Prints line to '/etc/crypttab' file. """
line = "{:21} {:<45} {}".format(dct["name"],
dct["device"],
dct["password"],
)
line = "{:21} {:<45} {} {}".format(dct["name"],
dct["device"],
dct["password"],
dct["options"],
)
print(line, file=file)
@@ -179,10 +181,33 @@ class FstabGenerator(object):
print(FSTAB_HEADER, file=fstab_file)
for partition in self.partitions:
dct = self.generate_fstab_line_info(partition)
# Special treatment for a btrfs root with @ and @home subvolumes
if partition["fs"] == "btrfs" and partition["mountPoint"] == "/":
output = subprocess.check_output(['btrfs',
'subvolume',
'list',
self.root_mount_point])
output_lines = output.splitlines()
for line in output_lines:
if line.endswith(b'path @'):
root_entry = partition
root_entry["subvol"] = "@"
dct = self.generate_fstab_line_info(root_entry)
if dct:
self.print_fstab_line(dct, file=fstab_file)
elif line.endswith(b'path @home'):
home_entry = partition
home_entry["mountPoint"] = "/home"
home_entry["subvol"] = "@home"
dct = self.generate_fstab_line_info(home_entry)
if dct:
self.print_fstab_line(dct, file=fstab_file)
if dct:
self.print_fstab_line(dct, file=fstab_file)
else:
dct = self.generate_fstab_line_info(partition)
if dct:
self.print_fstab_line(dct, file=fstab_file)
if self.root_is_ssd:
# Mount /tmp on a tmpfs
@@ -223,12 +248,21 @@ class FstabGenerator(object):
if mount_point == "/":
self.root_is_ssd = is_ssd
if filesystem == "btrfs" and "subvol" in partition:
return dict(device="UUID=" + partition["uuid"],
mount_point=mount_point,
fs=filesystem,
options=",".join(["subvol={}".format(partition["subvol"]),
options]),
check=check,
)
return dict(device="UUID=" + partition["uuid"],
mount_point=mount_point or "swap",
fs=filesystem,
options=options,
check=check,
)
)
def print_fstab_line(self, dct, file=None):
""" Prints line to '/etc/fstab' file. """
@@ -258,9 +292,11 @@ def run():
root_mount_point = global_storage.value("rootMountPoint")
mount_options = conf["mountOptions"]
ssd_extra_mount_options = conf.get("ssdExtraMountOptions", {})
crypttab_options = conf.get("crypttabOptions", "luks")
generator = FstabGenerator(partitions,
root_mount_point,
mount_options,
ssd_extra_mount_options)
ssd_extra_mount_options,
crypttab_options)
return generator.run()

View File

@@ -36,8 +36,10 @@ def modify_grub_default(partitions, root_mount_point, distributor):
default_grub = os.path.join(default_dir, "grub")
distributor_replace = distributor.replace("'", "'\\''")
plymouth_bin = libcalamares.utils.target_env_call(["sh", "-c", "which plymouth"])
dracut_bin = libcalamares.utils.target_env_call(["sh", "-c", "which dracut"])
use_splash = ""
swap_uuid = ""
swap_outer_uuid = ""
libcalamares.utils.debug("which plymouth exit code: {!s}".format(plymouth_bin))
@@ -46,15 +48,26 @@ def modify_grub_default(partitions, root_mount_point, distributor):
cryptdevice_params = []
for partition in partitions:
if partition["fs"] == "linuxswap":
swap_uuid = partition["uuid"]
if dracut_bin == 0:
for partition in partitions:
if partition["fs"] == "linuxswap":
swap_uuid = partition["uuid"]
if partition["mountPoint"] == "/" and "luksMapperName" in partition:
cryptdevice_params = [
"cryptdevice=UUID={!s}:{!s}".format(partition["luksUuid"],
partition["luksMapperName"]),
"root=/dev/mapper/{!s}".format(partition["luksMapperName"])
if partition["fs"] == "linuxswap" and "luksMapperName" in partition:
swap_outer_uuid = partition["luksUuid"]
if partition["mountPoint"] == "/" and "luksMapperName" in partition:
cryptdevice_params = ["rd.luks.uuid={!s}".format(partition["luksUuid"])]
else:
for partition in partitions:
if partition["fs"] == "linuxswap":
swap_uuid = partition["uuid"]
if partition["mountPoint"] == "/" and "luksMapperName" in partition:
cryptdevice_params = [
"cryptdevice=UUID={!s}:{!s}".format(partition["luksUuid"],
partition["luksMapperName"]),
"root=/dev/mapper/{!s}".format(partition["luksMapperName"])
]
kernel_params = ["quiet"]
@@ -68,7 +81,10 @@ def modify_grub_default(partitions, root_mount_point, distributor):
if swap_uuid:
kernel_params.append("resume=UUID={!s}".format(swap_uuid))
distributor_line = "GRUB_DISTRIBUTOR=\"{!s}\"".format(distributor_replace)
if dracut_bin == 0 and swap_outer_uuid:
kernel_params.append("rd.luks.uuid={!s}".format(swap_outer_uuid))
distributor_line = "GRUB_DISTRIBUTOR='{!s}'".format(distributor_replace)
if not os.path.exists(default_dir):
os.mkdir(default_dir)
@@ -126,7 +142,7 @@ def modify_grub_default(partitions, root_mount_point, distributor):
else:
escaped_value = str(value).replace("'", "'\\''")
lines.append("{!s}=\"{!s}\"".format(key, escaped_value))
lines.append("{!s}='{!s}'".format(key, escaped_value))
if not have_kernel_cmd:
kernel_cmd = "GRUB_CMDLINE_LINUX_DEFAULT=\"{!s}\"".format(" ".join(kernel_params))

View File

@@ -94,6 +94,7 @@ def modify_mkinitcpio_conf(partitions, root_mount_point):
files = []
encrypt_hook = False
openswap_hook = False
unencrypted_separate_boot = False
# It is important that the plymouth hook comes before any encrypt hook
plymouth_bin = os.path.join(root_mount_point, "usr/bin/plymouth")
@@ -112,9 +113,13 @@ def modify_mkinitcpio_conf(partitions, root_mount_point):
if partition["mountPoint"] == "/" and "luksMapperName" in partition:
encrypt_hook = True
if partition["mountPoint"] == "/boot" and "luksMapperName" not in partition:
unencrypted_separate_boot = True
if encrypt_hook:
hooks.append("encrypt")
if os.path.isfile(os.path.join(root_mount_point, "crypto_keyfile.bin")):
if not unencrypted_separate_boot and \
os.path.isfile(os.path.join(root_mount_point, "crypto_keyfile.bin")):
files.append("/crypto_keyfile.bin")
if swap_uuid is not "":

View File

@@ -0,0 +1,26 @@
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
if [ -f /crypto_keyfile.bin ]
then
cp /crypto_keyfile.bin ${DESTDIR}
fi
if [ -f /etc/crypttab ]
then
cp /etc/crypttab ${DESTDIR}/etc/
fi

View File

@@ -0,0 +1,22 @@
#!/bin/sh
PREREQ=""
prereqs()
{
echo "$PREREQ"
}
case $1 in
# get pre-requisites
prereqs)
prereqs
exit 0
;;
esac
. /usr/share/initramfs-tools/hook-functions
if [ -f /etc/crypttab ]
then
cp /etc/crypttab ${DESTDIR}/etc/
fi

View File

@@ -0,0 +1,60 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# === This file is part of Calamares - <http://github.com/calamares> ===
#
# Copyright 2014, Rohan Garg <rohan@kde.org>
# Copyright 2015, Philip Müller <philm@manjaro.org>
# Copyright 2016, David McKinney <mckinney@subgraph.com>
# Copyright 2016, Kevin Kofler <kevin.kofler@chello.at>
#
# Calamares is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Calamares is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Calamares. If not, see <http://www.gnu.org/licenses/>.
import libcalamares
import os
import shutil
def copy_initramfs_hooks(partitions, root_mount_point):
""" Copies initramfs hooks so they are picked up by update-initramfs
:param partitions:
:param root_mount_point:
"""
encrypt_hook = False
unencrypted_separate_boot = False
for partition in partitions:
if partition["mountPoint"] == "/" and "luksMapperName" in partition:
encrypt_hook = True
if partition["mountPoint"] == "/boot" and "luksMapperName" not in partition:
unencrypted_separate_boot = True
if encrypt_hook:
if unencrypted_separate_boot:
shutil.copy2("/usr/lib/calamares/modules/initramfscfg/encrypt_hook_nokey", "{!s}/usr/share/initramfs-tools/hooks/encrypt_hook".format(root_mount_point))
else:
shutil.copy2("/usr/lib/calamares/modules/initramfscfg/encrypt_hook", "{!s}/usr/share/initramfs-tools/hooks/".format(root_mount_point))
os.chmod("{!s}/usr/share/initramfs-tools/hooks/encrypt_hook".format(root_mount_point), 0o755)
def run():
""" Calls routine with given parameters to configure initramfs
:return:
"""
partitions = libcalamares.globalstorage.value("partitions")
root_mount_point = libcalamares.globalstorage.value("rootMountPoint")
copy_initramfs_hooks(partitions, root_mount_point)
return None

View File

@@ -0,0 +1,5 @@
---
type: "job"
name: "initramfscfg"
interface: "python"
script: "main.py"

View File

@@ -19,7 +19,7 @@ calamares_add_plugin( interactiveterminal
SOURCES
InteractiveTerminalViewStep.cpp
InteractiveTerminalPage.cpp
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
calamaresui
KF5::Service
KF5::Parts

View File

@@ -14,7 +14,7 @@ calamares_add_plugin( keyboard
KeyboardPage.ui
RESOURCES
keyboard.qrc
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
calamaresui
SHARED_LIB
)

View File

@@ -202,7 +202,8 @@ KeyboardPage::prettyStatus() const
QList< Calamares::job_ptr >
KeyboardPage::createJobs( const QString& xOrgConfFileName,
const QString& convertedKeymapPath )
const QString& convertedKeymapPath,
bool writeEtcDefaultKeyboard )
{
QList< Calamares::job_ptr > list;
QString selectedModel = m_models.value( ui->comboBoxModel->currentText(),
@@ -212,7 +213,8 @@ KeyboardPage::createJobs( const QString& xOrgConfFileName,
m_selectedLayout,
m_selectedVariant,
xOrgConfFileName,
convertedKeymapPath );
convertedKeymapPath,
writeEtcDefaultKeyboard );
list.append( Calamares::job_ptr( j ) );
return list;

View File

@@ -50,7 +50,8 @@ public:
QString prettyStatus() const;
QList< Calamares::job_ptr > createJobs( const QString& xOrgConfFileName,
const QString& convertedKeymapPath );
const QString& convertedKeymapPath,
bool writeEtcDefaultKeyboard );
void onActivate();
void finalize();

View File

@@ -29,6 +29,7 @@ KeyboardViewStep::KeyboardViewStep( QObject* parent )
: Calamares::ViewStep( parent )
, m_widget( new KeyboardPage() )
, m_nextEnabled( false )
, m_writeEtcDefaultKeyboard( true )
{
m_widget->init();
m_nextEnabled = true;
@@ -123,7 +124,9 @@ void
KeyboardViewStep::onLeave()
{
m_widget->finalize();
m_jobs = m_widget->createJobs( m_xOrgConfFileName, m_convertedKeymapPath );
m_jobs = m_widget->createJobs( m_xOrgConfFileName,
m_convertedKeymapPath,
m_writeEtcDefaultKeyboard );
m_prettyStatus = m_widget->prettyStatus();
}
@@ -157,4 +160,14 @@ KeyboardViewStep::setConfigurationMap( const QVariantMap& configurationMap )
{
m_convertedKeymapPath = QString();
}
if ( configurationMap.contains( "writeEtcDefaultKeyboard" ) &&
configurationMap.value( "writeEtcDefaultKeyboard" ).type() == QVariant::Bool )
{
m_writeEtcDefaultKeyboard = configurationMap.value( "writeEtcDefaultKeyboard" ).toBool();
}
else
{
m_writeEtcDefaultKeyboard = true;
}
}

View File

@@ -64,6 +64,7 @@ private:
QString m_xOrgConfFileName;
QString m_convertedKeymapPath;
bool m_writeEtcDefaultKeyboard;
QList< Calamares::job_ptr > m_jobs;
};

View File

@@ -1,6 +1,6 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
* Copyright 2014-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2014, Kevin Kofler <kevin.kofler@chello.at>
*
* Portions from systemd (localed.c):
@@ -40,13 +40,15 @@ SetKeyboardLayoutJob::SetKeyboardLayoutJob( const QString& model,
const QString& layout,
const QString& variant,
const QString& xOrgConfFileName,
const QString& convertedKeymapPath )
const QString& convertedKeymapPath,
bool writeEtcDefaultKeyboard)
: Calamares::Job()
, m_model( model )
, m_layout( layout )
, m_variant( variant )
, m_xOrgConfFileName( xOrgConfFileName )
, m_convertedKeymapPath( convertedKeymapPath )
, m_writeEtcDefaultKeyboard( writeEtcDefaultKeyboard )
{
}
@@ -240,6 +242,34 @@ SetKeyboardLayoutJob::writeX11Data( const QString& keyboardConfPath ) const
}
bool
SetKeyboardLayoutJob::writeDefaultKeyboardData( const QString& defaultKeyboardPath ) const
{
QFile file( defaultKeyboardPath );
file.open( QIODevice::WriteOnly | QIODevice::Text );
QTextStream stream( &file );
stream << "# KEYBOARD CONFIGURATION FILE\n\n"
"# Consult the keyboard(5) manual page.\n\n";
stream << "XKBMODEL=\"" << m_model << "\"\n";
stream << "XKBLAYOUT=\"" << m_layout << "\"\n";
stream << "XKBVARIANT=\"" << m_variant << "\"\n";
stream << "XKBOPTIONS=\"\"\n\n";
stream << "BACKSPACE=\"guess\"\n";
stream.flush();
file.close();
cDebug() << "Written XKBMODEL" << m_model <<
"; XKBLAYOUT" << m_layout <<
"; XKBVARIANT" << m_variant <<
"to /etc/default/keyboard file" << defaultKeyboardPath;
return ( stream.status() == QTextStream::Ok );
}
Calamares::JobResult
SetKeyboardLayoutJob::exec()
{
@@ -271,6 +301,12 @@ SetKeyboardLayoutJob::exec()
}
destDir.mkpath( xorgConfDPath );
QString defaultKeyboardPath;
if ( QDir( destDir.absoluteFilePath( "etc/default" ) ).exists() )
{
defaultKeyboardPath = destDir.absoluteFilePath( "etc/default/keyboard" );
}
// Get the path to the destination's path to the converted key mappings
QString convertedKeymapPath = m_convertedKeymapPath;
if ( !convertedKeymapPath.isEmpty() )
@@ -288,5 +324,12 @@ SetKeyboardLayoutJob::exec()
return Calamares::JobResult::error( tr( "Failed to write keyboard configuration for X11." ),
tr( "Failed to write to %1" ).arg( keyboardConfPath ) );
if ( !defaultKeyboardPath.isEmpty() && m_writeEtcDefaultKeyboard )
{
if ( !writeDefaultKeyboardData( defaultKeyboardPath ) )
return Calamares::JobResult::error( tr( "Failed to write keyboard configuration to existing /etc/default directory." ),
tr( "Failed to write to %1" ).arg( keyboardConfPath ) );
}
return Calamares::JobResult::ok();
}

View File

@@ -1,6 +1,6 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
* Copyright 2014-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2014, Kevin Kofler <kevin.kofler@chello.at>
*
* Calamares is free software: you can redistribute it and/or modify
@@ -31,7 +31,8 @@ public:
const QString& layout,
const QString& variant,
const QString& xOrgConfFileName,
const QString& convertedKeymapPath );
const QString& convertedKeymapPath,
bool writeEtcDefaultKeyboard );
QString prettyName() const override;
Calamares::JobResult exec() override;
@@ -41,13 +42,15 @@ private:
QString findLegacyKeymap() const;
bool writeVConsoleData( const QString& vconsoleConfPath,
const QString& convertedKeymapPath ) const;
bool writeX11Data( const QString& keyboardConfPath ) const;
bool writeX11Data( const QString& keyboardConfPath ) const;
bool writeDefaultKeyboardData( const QString& defaultKeyboardPath ) const;
QString m_model;
QString m_layout;
QString m_variant;
QString m_xOrgConfFileName;
QString m_convertedKeymapPath;
const bool m_writeEtcDefaultKeyboard;
};
#endif /* SETKEYBOARDLAYOUTJOB_H */

View File

@@ -3,6 +3,12 @@
# The default value is the name used by upstream systemd-localed.
# Relative paths are assumed to be relative to /etc/X11/xorg.conf.d
xOrgConfFileName: "/etc/X11/xorg.conf.d/00-keyboard.conf"
# The path to search for keymaps converted from X11 to kbd format
# Leave this empty if the setting does not make sense on your distribution.
convertedKeymapPath: "/lib/kbd/keymaps/xkb"
# Write keymap configuration to /etc/default/keyboard, usually
# found on Debian-related systems.
# Defaults to true if nothing is set.
#writeEtcDefaultKeyboard: true

View File

@@ -15,7 +15,7 @@ set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
LicensePage.cpp
UI
LicensePage.ui
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
calamaresui
SHARED_LIB
)

View File

@@ -14,7 +14,9 @@ calamares_add_plugin( locale
UI
RESOURCES
locale.qrc
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
calamaresui
Qt5::Network
yaml-cpp
SHARED_LIB
)

View File

@@ -60,7 +60,8 @@ LocaleConfiguration::fromLanguageAndLocation( const QString& languageLocale,
// FIXME: this might be useless if we already filter out non-UTF8 locales
foreach ( QString line, linesForLanguage )
{
if ( line.contains( "UTF-8" ) )
if ( line.contains( "UTF-8", Qt::CaseInsensitive ) ||
line.contains( "utf8", Qt::CaseInsensitive ) )
linesForLanguageUtf.append( line );
}

View File

@@ -365,7 +365,8 @@ LocalePage::init( const QString& initialRegion,
// because it's not 1995.
for ( auto it = m_localeGenLines.begin(); it != m_localeGenLines.end(); )
{
if ( !it->contains( "UTF-8", Qt::CaseInsensitive ) )
if ( !it->contains( "UTF-8", Qt::CaseInsensitive ) &&
!it->contains( "utf8", Qt::CaseInsensitive ) )
it = m_localeGenLines.erase( it );
else
++it;

View File

@@ -43,7 +43,8 @@ def run():
if partition["mountPoint"] == "/" and "luksMapperName" in partition:
luks_root_device = partition["device"]
luks_root_passphrase = partition["luksPassphrase"]
elif "luksMapperName" in partition:
elif "luksMapperName" in partition and\
(partition["mountPoint"] or partition["fs"] == "linuxswap"):
additional_luks_devices.append((partition["device"],
partition["luksPassphrase"]))
@@ -65,14 +66,16 @@ def run():
"luksAddKey",
luks_root_device,
"/crypto_keyfile.bin"],
luks_root_passphrase)
luks_root_passphrase,
15) # timeout 15s
for additional_device in additional_luks_devices:
check_target_env_call(["cryptsetup",
"luksAddKey",
additional_device[0],
"/crypto_keyfile.bin"],
additional_device[1])
additional_device[1],
15) # timeout 15s
check_target_env_call(["chmod",
"g-rwx,o-rwx",

View File

@@ -19,6 +19,7 @@
# along with Calamares. If not, see <http://www.gnu.org/licenses/>.
import tempfile
import subprocess
import libcalamares
@@ -55,6 +56,58 @@ def mount_partitions(root_mount_point, partitions):
partition.get("options", ""),
)
# If the root partition is btrfs, we create a subvolume "@"
# for the root mount point.
# If a separate /home partition isn't defined, we also create
# a subvolume "@home".
# Finally we remount all of the above on the correct paths.
if fstype == "btrfs" and partition["mountPoint"] == '/':
has_home_mount_point = False
for p in partitions:
if "mountPoint" not in p or not p["mountPoint"]:
continue
if p["mountPoint"] == "/home":
has_home_mount_point = True
break
subprocess.check_call(['btrfs', 'subvolume', 'create',
root_mount_point + '/@'])
if not has_home_mount_point:
subprocess.check_call(['btrfs', 'subvolume', 'create',
root_mount_point + '/@home'])
subprocess.check_call(["umount", "-v", root_mount_point])
if "luksMapperName" in partition:
libcalamares.utils.mount("/dev/mapper/{!s}".format(partition["luksMapperName"]),
mount_point,
fstype,
",".join(["subvol=@",
partition.get("options", "")]),
)
if not has_home_mount_point:
libcalamares.utils.mount("/dev/mapper/{!s}".format(partition["luksMapperName"]),
root_mount_point + "/home",
fstype,
",".join(["subvol=@home",
partition.get("options", "")]),
)
else:
libcalamares.utils.mount(partition["device"],
mount_point,
fstype,
",".join(["subvol=@",
partition.get("options", "")]),
)
if not has_home_mount_point:
libcalamares.utils.mount(partition["device"],
root_mount_point + "/home",
fstype,
",".join(["subvol=@home",
partition.get("options", "")]),
)
def run():
""" Define mountpoints.

View File

@@ -12,6 +12,9 @@ extraMounts:
- device: tmpfs
fs: tmpfs
mountPoint: /run
- device: /run/udev
mountPoint: /run/udev
options: bind
extraMountsEfi:
- device: efivarfs

View File

@@ -12,7 +12,9 @@ calamares_add_plugin( netinstall
widgets/groupselectionwidget.ui
RESOURCES
netinstall.qrc
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
calamaresui
Qt5::Network
yaml-cpp
SHARED_LIB
)

View File

@@ -111,7 +111,7 @@ NetInstallPage::dataIsHere( QNetworkReply* reply )
continue;
}
GroupSelectionWidget* groupWidget = new GroupSelectionWidget( group.name, group.description, group.packages, this );
GroupSelectionWidget* groupWidget = new GroupSelectionWidget( group.name, group.description, group.packages, group.selected, this );
m_groupWidgets.insert( groupKey, groupWidget );
ui->groupswidget->layout()->addWidget( groupWidget );

View File

@@ -20,7 +20,7 @@
#include <QtDebug>
GroupSelectionWidget::GroupSelectionWidget( QString name, QString description, QStringList packages, QWidget* parent ) :
GroupSelectionWidget::GroupSelectionWidget( QString name, QString description, QStringList packages, bool selected, QWidget* parent ) :
QWidget( parent ),
m_isToggled( false )
{
@@ -29,6 +29,7 @@ GroupSelectionWidget::GroupSelectionWidget( QString name, QString description, Q
connect( ui.group, &QCheckBox::toggled, this, &GroupSelectionWidget::toggleGroup );
ui.group->setText( name );
ui.group->setChecked( selected ); // also triggers the toggleGroup slot
ui.description->setText( description );
const int columns = 4;
const int rows = ( packages.size() - 1 ) / columns + 1;

View File

@@ -29,7 +29,7 @@ class GroupSelectionWidget : public QWidget
{
Q_OBJECT
public:
explicit GroupSelectionWidget( QString name, QString description, QStringList packages, QWidget* parent = nullptr );
explicit GroupSelectionWidget( QString name, QString description, QStringList packages, bool selected, QWidget* parent = nullptr );
// Current status of the group: is it selected in the view?
bool isToggled() const;

View File

@@ -57,6 +57,10 @@ def run():
source_resolv = "/etc/resolv.conf"
target_resolv = os.path.join(root_mount_point, "etc/resolv.conf")
if source_resolv != target_resolv and os.path.exists(source_resolv):
try:
os.remove(target_resolv)
except FileNotFoundError:
libcalamares.utils.debug("Couldn't remove {}".format(target_resolv))
try:
shutil.copy(source_resolv, target_resolv)
except FileNotFoundError:

View File

@@ -18,6 +18,7 @@
# You should have received a copy of the GNU General Public License
# along with Calamares. If not, see <http://www.gnu.org/licenses/>.
import subprocess
import libcalamares
from libcalamares.utils import check_target_env_call, target_env_call
@@ -91,6 +92,22 @@ class PackageManager:
elif self.backend == "entropy":
check_target_env_call(["equo", "rm"] + pkgs)
def update_db(self):
if self.backend == "packagekit":
check_target_env_call(["pkcon", "refresh"])
elif self.backend == "zypp":
check_target_env_call(["zypper", "update"])
elif self.backend == "urpmi":
check_target_env_call(["urpmi.update", "-a"])
elif self.backend == "apt":
check_target_env_call(["apt-get", "update"])
elif self.backend == "pacman":
check_target_env_call(["pacman", "-Sy"])
elif self.backend == "portage":
check_target_env_call(["emerge", "--sync"])
elif self.backend == "entropy":
check_target_env_call(["equo", "update"])
def run_operations(pkgman, entry):
""" Call package manager with given parameters.
@@ -101,8 +118,18 @@ def run_operations(pkgman, entry):
for key in entry.keys():
if key == "install":
pkgman.install(entry[key])
elif key == "try_install":
try:
pkgman.install(entry[key])
except subprocess.CalledProcessError:
libcalamares.utils.debug("WARNING: could not install packages {}".format(", ".join(entry[key])))
elif key == "remove":
pkgman.remove(entry[key])
elif key == "try_remove":
try:
pkgman.remove(entry[key])
except subprocess.CalledProcessError:
libcalamares.utils.debug("WARNING: could not remove packages {}".format(", ".join(entry[key])))
elif key == "localInstall":
pkgman.install(entry[key], from_local=True)
@@ -121,6 +148,10 @@ def run():
pkgman = PackageManager(backend)
operations = libcalamares.job.configuration.get("operations", [])
update_db = libcalamares.job.configuration.get("update_db", False)
if update_db and libcalamares.globalstorage.value("hasInternet"):
pkgman.update_db()
for entry in operations:
run_operations(pkgman, entry)

View File

@@ -12,6 +12,9 @@
# - entropy - Sabayon package manager
#
backend: packagekit
update_db: true
#
# List of maps with package operations such as install or remove.
# Distro developers can provide a list of packages to remove
@@ -33,12 +36,12 @@ backend: packagekit
# - remove:
# - pkg3
# - pkg4
# - install:
# - try_install: # no system install failure if a package cannot be installed
# - pkg5
# - remove:
# - try_remove: # no system install failure if a package cannot be removed
# - pkg2
# - pkg1
# install:
# - install:
# - pkgs6
# - pkg7
# - localInstall:

View File

@@ -11,6 +11,13 @@ find_package( KF5 REQUIRED CoreAddons )
find_package( KF5 REQUIRED Config I18n IconThemes KIO Service )
find_package( KPMcore 2.2 REQUIRED )
if(KPMcore_VERSION VERSION_LESS 3.0.0)
set(WITH_KPMCORE3 OFF)
else()
set(WITH_KPMCORE3 ON)
endif()
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/PartitionConfig.h.in
${CMAKE_CURRENT_BINARY_DIR}/PartitionConfig.h )
add_subdirectory( tests )
@@ -66,7 +73,7 @@ calamares_add_plugin( partition
gui/EncryptWidget.ui
gui/PartitionPage.ui
gui/ReplaceWidget.ui
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
kpmcore
calamaresui
KF5::CoreAddons

View File

@@ -0,0 +1,6 @@
#ifndef CALAMARESPARTITIONCONFIG_H
#define CALAMARESPARTITIONCONFIG_H
#cmakedefine WITH_KPMCORE3
#endif // CALAMARESPARTITIONCONFIG_H

View File

@@ -151,6 +151,12 @@ createNewEncryptedPartition( PartitionNode* parent,
FileSystemFactory::create( FileSystem::Luks,
firstSector,
lastSector ) );
if ( !fs )
{
qDebug() << "ERROR: cannot create LUKS filesystem. Giving up.";
return nullptr;
}
fs->createInnerFileSystem( fsType );
fs->setPassphrase( passphrase );
Partition* p = new Partition( parent,

View File

@@ -51,8 +51,9 @@ canBeReplaced( Partition* candidate )
qint64 requiredStorageB = ( requiredStorageGB + 0.5 ) * 1024 * 1024 * 1024;
cDebug() << "Required storage B:" << requiredStorageB
<< QString( "(%1GB)" ).arg( requiredStorageB / 1024 / 1024 / 1024 );
cDebug() << "Available storage B:" << availableStorageB
<< QString( "(%1GB)" ).arg( availableStorageB / 1024 / 1024 / 1024 );
cDebug() << "Storage capacity B:" << availableStorageB
<< QString( "(%1GB)" ).arg( availableStorageB / 1024 / 1024 / 1024 )
<< "for" << candidate->partitionPath() << " length:" << candidate->length();
if ( ok &&
availableStorageB > requiredStorageB )
@@ -102,7 +103,9 @@ canBeResized( Partition* candidate )
cDebug() << "Required storage B:" << requiredStorageB
<< QString( "(%1GB)" ).arg( requiredStorageB / 1024 / 1024 / 1024 );
cDebug() << "Available storage B:" << availableStorageB
<< QString( "(%1GB)" ).arg( availableStorageB / 1024 / 1024 / 1024 );
<< QString( "(%1GB)" ).arg( availableStorageB / 1024 / 1024 / 1024 )
<< "for" << candidate->partitionPath() << " length:" << candidate->length()
<< " sectorsUsed:" << candidate->sectorsUsed() << " fsType:" << candidate->fileSystem().name();
if ( ok &&
availableStorageB > requiredStorageB )

View File

@@ -1,6 +1,6 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
#include "JobQueue.h"
#include "utils/Logger.h"
#include "GlobalStorage.h"
#include "PartitionConfig.h"
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
@@ -128,11 +129,19 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
empty_space_size = 1;
}
#ifdef WITH_KPMCORE3
qint64 firstFreeSector = empty_space_size MiB / dev->logicalSize() + 1;
#else
qint64 firstFreeSector = empty_space_size MiB / dev->logicalSectorSize() + 1;
#endif
if ( isEfi )
{
#ifdef WITH_KPMCORE3
qint64 lastSector = firstFreeSector + ( uefisys_part_size MiB / dev->logicalSize() );
#else
qint64 lastSector = firstFreeSector + ( uefisys_part_size MiB / dev->logicalSectorSize() );
#endif
core->createPartitionTable( dev, PartitionTable::gpt );
Partition* efiPartition = KPMHelpers::createNewPartition(
dev->partitionTable(),
@@ -140,14 +149,15 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
PartitionRole( PartitionRole::Primary ),
FileSystem::Fat32,
firstFreeSector,
lastSector
lastSector,
PartitionTable::FlagEsp
);
PartitionInfo::setFormat( efiPartition, true );
PartitionInfo::setMountPoint( efiPartition, Calamares::JobQueue::instance()
->globalStorage()
->value( "efiSystemPartition" )
.toString() );
core->createPartition( dev, efiPartition );
core->createPartition( dev, efiPartition, PartitionTable::FlagEsp | PartitionTable::FlagBoot );
firstFreeSector = lastSector + 1;
}
else
@@ -156,7 +166,11 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
}
bool shouldCreateSwap = false;
#ifdef WITH_KPMCORE3
qint64 availableSpaceB = ( dev->totalLogical() - firstFreeSector ) * dev->logicalSize();
#else
qint64 availableSpaceB = ( dev->totalSectors() - firstFreeSector ) * dev->logicalSectorSize();
#endif
qint64 suggestedSwapSizeB = swapSuggestion( availableSpaceB );
qint64 requiredSpaceB =
( Calamares::JobQueue::instance()->
@@ -167,11 +181,19 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
// If there is enough room for ESP + root + swap, create swap, otherwise don't.
shouldCreateSwap = availableSpaceB > requiredSpaceB;
#ifdef WITH_KPMCORE3
qint64 lastSectorForRoot = dev->totalLogical() - 1; //last sector of the device
if ( shouldCreateSwap )
{
lastSectorForRoot -= suggestedSwapSizeB / dev->logicalSize() + 1;
}
#else
qint64 lastSectorForRoot = dev->totalSectors() - 1; //last sector of the device
if ( shouldCreateSwap )
{
lastSectorForRoot -= suggestedSwapSizeB / dev->logicalSectorSize() + 1;
}
#endif
Partition* rootPartition = nullptr;
if ( luksPassphrase.isEmpty() )
@@ -212,7 +234,11 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
PartitionRole( PartitionRole::Primary ),
FileSystem::LinuxSwap,
lastSectorForRoot + 1,
#ifdef WITH_KPMCORE3
dev->totalLogical() - 1
#else
dev->totalSectors() - 1
#endif
);
}
else
@@ -223,7 +249,11 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
PartitionRole( PartitionRole::Primary ),
FileSystem::LinuxSwap,
lastSectorForRoot + 1,
#ifdef WITH_KPMCORE3
dev->totalLogical() - 1,
#else
dev->totalSectors() - 1,
#endif
luksPassphrase
);
}

View File

@@ -547,29 +547,14 @@ PartitionCoreModule::scanForEfiSystemPartitions()
devices.append( device );
}
//FIXME: Unfortunately right now we have to call sgdisk manually because
// the KPM submodule does not expose the ESP flag from libparted.
// The following findPartitions call and lambda should be scrapped and
// rewritten based on libKPM. -- Teo 5/2015
QList< Partition* > efiSystemPartitions =
KPMHelpers::findPartitions( devices,
[]( Partition* partition ) -> bool
{
QProcess process;
process.setProgram( "sgdisk" );
process.setArguments( { "-i",
QString::number( partition->number() ),
partition->devicePath() } );
process.setProcessChannelMode( QProcess::MergedChannels );
process.start();
if ( process.waitForFinished() )
if ( partition->activeFlags().testFlag( PartitionTable::FlagEsp ) )
{
if ( process.readAllStandardOutput()
.contains( "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" ) )
{
cDebug() << "Found EFI system partition at" << partition->partitionPath();
return true;
}
cDebug() << "Found EFI system partition at" << partition->partitionPath();
return true;
}
return false;
} );

View File

@@ -22,6 +22,7 @@
#include "core/PartitionInfo.h"
#include "core/KPMHelpers.h"
#include "utils/Logger.h"
#include "PartitionConfig.h"
// CalaPM
#include <kpmcore/core/device.h>
@@ -148,7 +149,11 @@ PartitionModel::data( const QModelIndex& index, int role ) const
return PartitionInfo::mountPoint( partition );
if ( col == SizeColumn )
{
#ifdef WITH_KPMCORE3
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
#else
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSectorSize();
#endif
return KFormat().formatByteSize( size );
}
cDebug() << "Unknown column" << col;
@@ -175,12 +180,20 @@ PartitionModel::data( const QModelIndex& index, int role ) const
}
}
QString prettyFileSystem = KPMHelpers::prettyNameForFileSystemType( partition->fileSystem().type() );
#ifdef WITH_KPMCORE3
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
#else
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSectorSize();
#endif
QString prettySize = KFormat().formatByteSize( size );
return QVariant(name + " " + prettyFileSystem + " " + prettySize);
}
case SizeRole:
#ifdef WITH_KPMCORE3
return ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
#else
return ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSectorSize();
#endif
case IsFreeSpaceRole:
return KPMHelpers::isPartitionFreeSpace( partition );

View File

@@ -35,6 +35,7 @@
#include "BootInfoWidget.h"
#include "DeviceInfoWidget.h"
#include "ScanningDialog.h"
#include "PartitionConfig.h"
#include "utils/CalamaresUtilsGui.h"
#include "utils/Logger.h"
@@ -82,12 +83,16 @@ ChoicePage::ChoicePage( QWidget* parent )
, m_beforePartitionLabelsView( nullptr )
, m_bootloaderComboBox( nullptr )
, m_lastSelectedDeviceIndex( -1 )
, m_enableEncryptionWidget( true )
{
setupUi( this );
m_defaultFsType = Calamares::JobQueue::instance()->
globalStorage()->
value( "defaultFileSystemType" ).toString();
m_enableEncryptionWidget = Calamares::JobQueue::instance()->
globalStorage()->
value( "enableLuksAutomatedPartitioning" ).toBool();
if ( FileSystem::typeForName( m_defaultFsType ) == FileSystem::Unknown )
m_defaultFsType = "ext4";
@@ -590,7 +595,11 @@ ChoicePage::doAlongsideApply()
qint64 oldLastSector = candidate->lastSector();
qint64 newLastSector = firstSector +
m_afterPartitionSplitterWidget->splitPartitionSize() /
#ifdef WITH_KPMCORE3
dev->logicalSize();
#else
dev->logicalSectorSize();
#endif
m_core->resizePartition( dev, candidate, firstSector, newLastSector );
Partition* newPartition = nullptr;
@@ -884,7 +893,8 @@ ChoicePage::updateActionChoicePreview( ChoicePage::Choice choice )
{
case Alongside:
{
m_encryptWidget->show();
if ( m_enableEncryptionWidget )
m_encryptWidget->show();
m_previewBeforeLabel->setText( tr( "Current:" ) );
m_selectLabel->setText( tr( "<strong>Select a partition to shrink, "
"then drag the bottom bar to resize</strong>" ) );
@@ -930,7 +940,8 @@ ChoicePage::updateActionChoicePreview( ChoicePage::Choice choice )
case Erase:
case Replace:
{
m_encryptWidget->show();
if ( m_enableEncryptionWidget )
m_encryptWidget->show();
m_previewBeforeLabel->setText( tr( "Current:" ) );
m_afterPartitionBarsView = new PartitionBarsView( m_previewAfterFrame );
m_afterPartitionBarsView->setNestedPartitionsMode( mode );
@@ -1100,7 +1111,7 @@ ChoicePage::createBootloaderComboBox( QWidget* parent )
// When the chosen bootloader device changes, we update the choice in the PCM
connect( bcb, static_cast< void (QComboBox::*)(int) >( &QComboBox::currentIndexChanged ),
[this]( int newIndex )
this, [this]( int newIndex )
{
QComboBox* bcb = qobject_cast< QComboBox* >( sender() );
if ( bcb )

View File

@@ -123,6 +123,7 @@ private:
int m_lastSelectedDeviceIndex;
QString m_defaultFsType;
bool m_enableEncryptionWidget;
QMutex m_coreMutex;
};

View File

@@ -21,6 +21,7 @@
#include <core/PartitionModel.h>
#include <core/ColorUtils.h>
#include "PartitionConfig.h"
#include <utils/CalamaresUtilsGui.h>
#include <utils/Logger.h>
@@ -47,7 +48,11 @@ QStringList
buildUnknownDisklabelTexts( Device* dev )
{
QStringList texts = { QObject::tr( "Unpartitioned space or unknown partition table" ),
#ifdef WITH_KPMCORE3
KFormat().formatByteSize( dev->totalLogical() * dev->logicalSize() ) };
#else
KFormat().formatByteSize( dev->totalSectors() * dev->logicalSectorSize() ) };
#endif
return texts;
}

View File

@@ -21,6 +21,7 @@
#include "core/ColorUtils.h"
#include "core/KPMHelpers.h"
#include "PartitionConfig.h"
// Qt
#include <QSpinBox>
@@ -135,7 +136,11 @@ PartitionSizeController::updatePartResizerWidget()
return;
m_updating = true;
#ifdef WITH_KPMCORE3
qint64 sectorSize = qint64( m_spinBox->value() ) * 1024 * 1024 / m_device->logicalSize();
#else
qint64 sectorSize = qint64( m_spinBox->value() ) * 1024 * 1024 / m_device->logicalSectorSize();
#endif
qint64 firstSector = m_partition->firstSector();
qint64 lastSector = firstSector + sectorSize - 1;
@@ -185,7 +190,11 @@ PartitionSizeController::doUpdateSpinBox()
{
if ( !m_spinBox )
return;
#ifdef WITH_KPMCORE3
qint64 mbSize = m_partition->length() * m_device->logicalSize() / 1024 / 1024;
#else
qint64 mbSize = m_partition->length() * m_device->logicalSectorSize() / 1024 / 1024;
#endif
m_spinBox->setValue( mbSize );
if ( m_currentSpinBoxValue != -1 && //if it's not the first time we're setting it
m_currentSpinBoxValue != mbSize ) //and the operation changes the SB value

View File

@@ -250,6 +250,8 @@ PartitionViewStep::createSummaryWidget() const
previewLabels->setModel( info.partitionModelAfter );
preview->setSelectionMode( QAbstractItemView::NoSelection );
previewLabels->setSelectionMode( QAbstractItemView::NoSelection );
previewLabels->setCustomNewRootLabel( Calamares::Branding::instance()->
string( Calamares::Branding::BootloaderEntryName ) );
info.partitionModelAfter->setParent( widget );
field = new QVBoxLayout;
CalamaresUtils::unmarginLayout( field );
@@ -435,7 +437,39 @@ PartitionViewStep::onLeave()
QMessageBox::warning( m_manualPartitionPage,
message,
description );
return;
}
}
Partition* root_p = m_core->findPartitionByMountPoint( "/" );
Partition* boot_p = m_core->findPartitionByMountPoint( "/boot" );
if ( root_p and boot_p )
{
QString message;
QString description;
// If the root partition is encrypted, and there's a separate boot
// partition which is not encrypted
if ( root_p->fileSystem().type() == FileSystem::Luks &&
boot_p->fileSystem().type() != FileSystem::Luks )
{
message = tr( "Boot partition not encrypted" );
description = tr( "A separate boot partition was set up together with "
"an encrypted root partition, but the boot partition "
"is not encrypted."
"<br/><br/>"
"There are security concerns with this kind of "
"setup, because important system files are kept "
"on an unencrypted partition.<br/>"
"You may continue if you wish, but filesystem "
"unlocking will happen later during system startup."
"<br/>To encrypt the boot partition, go back and "
"recreate it, selecting <strong>Encrypt</strong> "
"in the partition creation window." );
QMessageBox::warning( m_manualPartitionPage,
message,
description );
}
}
}
@@ -508,6 +542,17 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
gs->insert( "defaultFileSystemType", QStringLiteral( "ext4" ) );
}
if ( configurationMap.contains( "enableLuksAutomatedPartitioning" ) &&
configurationMap.value( "enableLuksAutomatedPartitioning" ).type() == QVariant::Bool )
{
gs->insert( "enableLuksAutomatedPartitioning",
configurationMap.value( "enableLuksAutomatedPartitioning" ).toBool() );
}
else
{
gs->insert( "enableLuksAutomatedPartitioning", true );
}
// Now that we have the config, we load the PartitionCoreModule in the background
// because it could take a while. Then when it's done, we can set up the widgets

View File

@@ -26,6 +26,7 @@
#include "core/KPMHelpers.h"
#include "Branding.h"
#include "utils/Logger.h"
#include "PartitionConfig.h"
// CalaPM
#include <kpmcore/core/device.h>
@@ -98,7 +99,11 @@ mapForPartition( Partition* partition, const QString& uuid )
const FS::luks* luksFs = dynamic_cast< const FS::luks* >( &fsRef );
if ( luksFs )
{
#ifdef WITH_KPMCORE3
map[ "luksMapperName" ] = luksFs->mapperName().split( "/" ).last();
#else
map[ "luksMapperName" ] = luksFs->mapperName( partition->partitionPath() ).split( "/" ).last();
#endif
map[ "luksUuid" ] = getLuksUuid( partition->partitionPath() );
map[ "luksPassphrase" ] = luksFs->passphrase();
cDebug() << "luksMapperName:" << map[ "luksMapperName" ];

View File

@@ -44,6 +44,7 @@
#include "jobs/CheckFileSystemJob.h"
#include "jobs/MoveFileSystemJob.h"
#include "utils/Logger.h"
#include "PartitionConfig.h"
// KPMcore
#include <kpmcore/backend/corebackend.h>
@@ -93,7 +94,11 @@ public:
break;
case FileSystem::cmdSupportFileSystem:
{
#ifdef WITH_KPMCORE3
qint64 byteLength = m_device->logicalSize() * m_length;
#else
qint64 byteLength = m_device->logicalSectorSize() * m_length;
#endif
bool ok = fs.resize( report, m_partition->partitionPath(), byteLength );
if ( !ok )
return Calamares::JobResult::error(

View File

@@ -18,3 +18,23 @@ alwaysShowPartitionLabels: true
# Suggested values: ext2, ext3, ext4, reiser, xfs, jfs, btrfs
# If nothing is specified, Calamares defaults to "ext4".
defaultFileSystemType: "ext4"
# Show/hide LUKS related functionality in automated partitioning modes.
# Disable this if you choose not to deploy early unlocking support in GRUB2
# and/or your distribution's initramfs solution.
#
# BIG FAT WARNING:
# This option is unsupported, as it cuts out a crucial security feature.
# Disabling LUKS and shipping Calamares without a correctly configured GRUB2
# and initramfs is considered suboptimal use of the Calamares software. The
# Calamares team will not provide user support for any potential issue that
# may arise as a consequence of setting this option to false.
# It is strongly recommended that system integrators put in the work to support
# LUKS unlocking support in GRUB2 and initramfs/dracut/mkinitcpio/etc.
# Support is offered to system integrators that wish to do so, through the
# Calamares bug tracker, as well as in #calamares on Freenode.
# For more information on setting up GRUB2 for Calamares with LUKS, see
# https://github.com/calamares/calamares/wiki/LUKS-Deployment
#
# If nothing is specified, LUKS is enabled in automated modes.
#enableLuksAutomatedPartitioning: true

View File

@@ -15,3 +15,6 @@ targets:
disable:
- name: "pacman-init"
mandatory: false
# Example to express an empty list:
# disable: []

View File

@@ -6,7 +6,7 @@ calamares_add_plugin( summary
SummaryViewStep.cpp
SummaryPage.cpp
UI
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
calamaresui
SHARED_LIB
)

View File

@@ -119,7 +119,18 @@ def file_copy(source, dest, progress_cb):
process.wait()
if process.returncode != 0:
# 23 is the return code rsync returns if it cannot write extended attributes
# (with -X) because the target file system does not support it, e.g., the
# FAT EFI system partition. We need -X because distributions using file
# system capabilities and/or SELinux require the extended attributes. But
# distributions using SELinux may also have SELinux labels set on files
# under /boot/efi, and rsync complains about those. The only clean way would
# be to split the rsync into one with -X and --exclude /boot/efi and a
# separate one without -X for /boot/efi, but only if /boot/efi is actually
# an EFI system partition. For now, this hack will have to do. See also:
# https://bugzilla.redhat.com/show_bug.cgi?id=868755#c50
# for the same issue in Anaconda, which uses a similar workaround.
if process.returncode != 0 and process.returncode != 23:
return "rsync failed with error code {}.".format(process.returncode)
return None

View File

@@ -16,7 +16,7 @@ calamares_add_plugin( users
page_usersetup.ui
RESOURCES
users.qrc
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
calamaresui
${CRYPT_LIBRARIES}
SHARED_LIB

View File

@@ -153,8 +153,8 @@ CreateUserJob::exec()
"-s",
"/bin/bash",
"-U",
"-G",
defaultGroups,
"-c",
m_fullName,
m_userName } );
if ( ec )
return Calamares::JobResult::error( tr( "Cannot create user %1." )
@@ -162,11 +162,16 @@ CreateUserJob::exec()
tr( "useradd terminated with error code %1." )
.arg( ec ) );
ec = CalamaresUtils::System::instance()->targetEnvCall( { "chfn", "-f", m_fullName, m_userName } );
ec = CalamaresUtils::System::instance()->
targetEnvCall( { "usermod",
"-aG",
defaultGroups,
m_userName } );
if ( ec )
return Calamares::JobResult::error( tr( "Cannot set full name for user %1." )
.arg( m_userName ),
tr( "chfn terminated with error code %1." )
return Calamares::JobResult::error( tr( "Cannot add user %1 to groups: %2." )
.arg( m_userName )
.arg( defaultGroups ),
tr( "usermod terminated with error code %1." )
.arg( ec ) );
ec = CalamaresUtils::System::instance()->

View File

@@ -1,6 +1,6 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -59,6 +59,20 @@ SetPasswordJob::exec()
return Calamares::JobResult::error( tr( "Bad destination system path." ),
tr( "rootMountPoint is %1" ).arg( destDir.absolutePath() ) );
if ( m_userName == "root" &&
m_newPassword.isEmpty() ) //special case for disabling root account
{
int ec = CalamaresUtils::System::instance()->
targetEnvCall( { "passwd",
"-dl",
m_userName } );
if ( ec )
return Calamares::JobResult::error( tr( "Cannot disable root account." ),
tr( "passwd terminated with error code %1." )
.arg( ec ) );
return Calamares::JobResult::ok();
}
QString encrypted = QString::fromLatin1(
crypt( m_newPassword.toLatin1(),
QString( "$6$%1$" )

View File

@@ -1,6 +1,6 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
*
* Portions from the Manjaro Installation Framework
* by Roland Singer <roland@manjaro.org>
@@ -138,6 +138,12 @@ UsersPage::createJobs( const QStringList& defaultGroupsList )
ui->textBoxRootPassword->text() );
list.append( Calamares::job_ptr( j ) );
}
else
{
j = new SetPasswordJob( "root",
"" ); //explicitly disable root password
list.append( Calamares::job_ptr( j ) );
}
j = new SetHostNameJob( ui->textBoxHostname->text() );
list.append( Calamares::job_ptr( j ) );

View File

@@ -44,7 +44,7 @@ calamares_add_plugin( webview
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
WebViewStep.cpp
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
${CALA_WEBVIEW_LINK_LIBRARIES}
SHARED_LIB
)

View File

@@ -25,6 +25,7 @@
#include <QWebView>
#else
#include <QWebEngineView>
#include <QtWebEngine>
#endif
CALAMARES_PLUGIN_FACTORY_DEFINITION( WebViewStepFactory, registerPlugin<WebViewStep>(); )
@@ -33,6 +34,9 @@ WebViewStep::WebViewStep( QObject* parent )
: Calamares::ViewStep( parent )
{
emit nextStatusChanged( true );
#ifdef WEBVIEW_WITH_WEBENGINE
QtWebEngine::initialize();
#endif
m_view = new C_QWEBVIEW();
#ifdef WEBVIEW_WITH_WEBKIT
m_view->settings()->setFontFamily( QWebSettings::StandardFont,

View File

@@ -1,7 +1,7 @@
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules )
find_package( LIBPARTED REQUIRED )
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED DBus )
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED DBus Network )
set_source_files_properties( checker/partman_devices.c PROPERTIES LANGUAGE CXX )
@@ -14,6 +14,7 @@ set( CHECKER_SOURCES
set( CHECKER_LINK_LIBRARIES
${LIBPARTED_LIBS}
Qt5::DBus
Qt5::Network
)
calamares_add_plugin( welcome
@@ -25,7 +26,7 @@ calamares_add_plugin( welcome
WelcomePage.cpp
UI
WelcomePage.ui
LINK_LIBRARIES
LINK_PRIVATE_LIBRARIES
calamaresui
${CHECKER_LINK_LIBRARIES}
SHARED_LIB

View File

@@ -20,6 +20,7 @@
#include "WelcomePage.h"
#include "checker/RequirementsChecker.h"
#include "utils/Logger.h"
#include <QVariant>
@@ -128,5 +129,8 @@ WelcomeViewStep::setConfigurationMap( const QVariantMap& configurationMap )
if ( configurationMap.contains( "requirements" ) &&
configurationMap.value( "requirements" ).type() == QVariant::Map )
m_requirementsChecker->setConfigurationMap( configurationMap.value( "requirements" ).toMap() );
else
cDebug() << "WARNING: no valid requirements map found in welcome "
"module configuration.";
}

View File

@@ -36,6 +36,7 @@
#include <QFile>
#include <QFileInfo>
#include <QLabel>
#include <QNetworkAccessManager>
#include <QProcess>
#include <QTimer>
@@ -185,6 +186,7 @@ RequirementsChecker::widget() const
void
RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
{
bool incompleteConfiguration = false;
if ( configurationMap.contains( "requiredStorage" ) &&
( configurationMap.value( "requiredStorage" ).type() == QVariant::Double ||
configurationMap.value( "requiredStorage" ).type() == QVariant::Int ) )
@@ -199,6 +201,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
else
{
m_requiredStorageGB = 3.;
incompleteConfiguration = true;
}
if ( configurationMap.contains( "requiredRam" ) &&
@@ -208,11 +211,15 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
bool ok = false;
m_requiredRamGB = configurationMap.value( "requiredRam" ).toDouble( &ok );
if ( !ok )
{
m_requiredRamGB = 1.;
incompleteConfiguration = true;
}
}
else
{
m_requiredRamGB = 1.;
incompleteConfiguration = true;
}
if ( configurationMap.contains( "check" ) &&
@@ -221,6 +228,8 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
m_entriesToCheck.clear();
m_entriesToCheck.append( configurationMap.value( "check" ).toStringList() );
}
else
incompleteConfiguration = true;
if ( configurationMap.contains( "required" ) &&
configurationMap.value( "required" ).type() == QVariant::List )
@@ -228,6 +237,19 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
m_entriesToRequire.clear();
m_entriesToRequire.append( configurationMap.value( "required" ).toStringList() );
}
else
incompleteConfiguration = true;
if ( incompleteConfiguration )
{
cDebug() << "WARNING: The RequirementsChecker configuration map provided by "
"the welcome module configuration file is incomplete or "
"incorrect.\n"
"Startup will continue for debugging purposes, but one or "
"more checks might not function correctly.\n"
"RequirementsChecker configuration map:\n"
<< configurationMap;
}
}
@@ -315,30 +337,8 @@ RequirementsChecker::checkHasPower()
bool
RequirementsChecker::checkHasInternet()
{
const QString NM_SVC_NAME( "org.freedesktop.NetworkManager" );
const QString NM_INTF_NAME( "org.freedesktop.NetworkManager" );
const QString NM_PATH( "/org/freedesktop/NetworkManager" );
const int NM_STATE_CONNECTED_GLOBAL = 70;
QDBusInterface nmIntf( NM_SVC_NAME,
NM_PATH,
NM_INTF_NAME,
QDBusConnection::systemBus(), 0 );
bool ok = false;
int nmState = nmIntf.property( "state" ).toInt( &ok );
if ( !ok || !nmIntf.isValid() )
{
// We can't talk to NM, so no idea. Wild guess: we're connected
// using ssh with X forwarding, and are therefore connected. This
// allows us to proceed with a minimum of complaint.
Calamares::JobQueue::instance()->globalStorage()->insert( "hasInternet", true );
return true;
}
bool hasInternet = nmState == NM_STATE_CONNECTED_GLOBAL;
// default to true in the QNetworkAccessManager::UnknownAccessibility case
bool hasInternet = QNetworkAccessManager(this).networkAccessible() != QNetworkAccessManager::NotAccessible;
Calamares::JobQueue::instance()->globalStorage()->insert( "hasInternet", hasInternet );
return hasInternet;
}