Skip to content
Snippets Groups Projects
Commit e91be5bd authored by Philip's avatar Philip
Browse files

v2.4.4

- [partition] remove sgdisk dependency
- [displaymanager] use configparser and add better autologin handling
- [displaymanager] set a preferred Xsession for autologin
- [netinstall] Support selecting visible groups by default
- [packages] Add option of updating packages db before perfoming package operations
- [packages] Allow try_install and try_remove entries in packages module
- [unpackfs] Do not fail if rsync returns exit code 23
parent 27602cf8
No related branches found
No related tags found
No related merge requests found
...@@ -28,10 +28,8 @@ Modules: ...@@ -28,10 +28,8 @@ Modules:
* extra-cmake-modules * extra-cmake-modules
* KF5: KCoreAddons, KConfig, KI18n, KIconThemes, KIO, KService * KF5: KCoreAddons, KConfig, KI18n, KIconThemes, KIO, KService
* KPMcore >= 2.2 * KPMcore >= 2.2
* sgdisk
* bootloader: * bootloader:
* systemd-boot or GRUB * systemd-boot or GRUB
* sgdisk
* unpackfs: * unpackfs:
* squashfs-tools * squashfs-tools
* rsync * rsync
......
...@@ -258,7 +258,7 @@ def vfat_correct_case(parent, name): ...@@ -258,7 +258,7 @@ def vfat_correct_case(parent, name):
def prepare_bootloader(fw_type): 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. Based on value 'efi_boot_loader', it either calls systemd-boot or grub to be installed.
:param fw_type: :param fw_type:
...@@ -267,33 +267,6 @@ def prepare_bootloader(fw_type): ...@@ -267,33 +267,6 @@ def prepare_bootloader(fw_type):
efi_boot_loader = libcalamares.job.configuration["efiBootLoader"] efi_boot_loader = libcalamares.job.configuration["efiBootLoader"]
efi_directory = libcalamares.globalstorage.value("efiSystemPartition") 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": if efi_boot_loader == "systemd-boot" and fw_type == "efi":
install_systemd_boot(efi_directory) install_systemd_boot(efi_directory)
else: else:
......
...@@ -24,6 +24,7 @@ import os ...@@ -24,6 +24,7 @@ import os
import collections import collections
import re import re
import libcalamares import libcalamares
import configparser
DesktopEnvironment = collections.namedtuple('DesktopEnvironment', ['executable', 'desktop_file']) DesktopEnvironment = collections.namedtuple('DesktopEnvironment', ['executable', 'desktop_file'])
...@@ -253,34 +254,31 @@ def set_autologin(username, displaymanagers, default_desktop_environment, root_m ...@@ -253,34 +254,31 @@ def set_autologin(username, displaymanagers, default_desktop_environment, root_m
# Systems with Sddm as Desktop Manager # Systems with Sddm as Desktop Manager
sddm_conf_path = os.path.join(root_mount_point, "etc/sddm.conf") sddm_conf_path = os.path.join(root_mount_point, "etc/sddm.conf")
if os.path.isfile(sddm_conf_path): sddm_config = configparser.ConfigParser()
libcalamares.utils.debug('SDDM config file exists') # Make everything case sensitive
else: sddm_config.optionxform = str
libcalamares.utils.check_target_env_call(["sh", "-c", "sddm --example-config > /etc/sddm.conf"])
text = [] if os.path.isfile(sddm_conf_path):
sddm_config.read(sddm_conf_path)
with open(sddm_conf_path, 'r') as sddm_conf: autologin_section = {}
text = sddm_conf.readlines() if 'Autologin' in sddm_config:
autologin_section = sddm_config['Autologin']
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: if do_autologin:
line = 'User={!s}\n'.format(username) autologin_section['User'] = username
else:
line = '#User=\n'
# 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 default_desktop_environment is not None:
if do_autologin: autologin_section['Session'] = default_desktop_environment.desktop_file
line = 'Session={!s}.desktop\n'.format(default_desktop_environment.desktop_file)
if autologin_section:
if 'Autologin' in sddm_config:
sddm_config['Autologin'].update(autologin_section)
else: else:
line = '#Session={!s}.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 return None
......
...@@ -111,7 +111,7 @@ NetInstallPage::dataIsHere( QNetworkReply* reply ) ...@@ -111,7 +111,7 @@ NetInstallPage::dataIsHere( QNetworkReply* reply )
continue; 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 ); m_groupWidgets.insert( groupKey, groupWidget );
ui->groupswidget->layout()->addWidget( groupWidget ); ui->groupswidget->layout()->addWidget( groupWidget );
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <QtDebug> #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 ), QWidget( parent ),
m_isToggled( false ) m_isToggled( false )
{ {
...@@ -29,6 +29,7 @@ GroupSelectionWidget::GroupSelectionWidget( QString name, QString description, Q ...@@ -29,6 +29,7 @@ GroupSelectionWidget::GroupSelectionWidget( QString name, QString description, Q
connect( ui.group, &QCheckBox::toggled, this, &GroupSelectionWidget::toggleGroup ); connect( ui.group, &QCheckBox::toggled, this, &GroupSelectionWidget::toggleGroup );
ui.group->setText( name ); ui.group->setText( name );
ui.group->setChecked( selected ); // also triggers the toggleGroup slot
ui.description->setText( description ); ui.description->setText( description );
const int columns = 4; const int columns = 4;
const int rows = ( packages.size() - 1 ) / columns + 1; const int rows = ( packages.size() - 1 ) / columns + 1;
......
...@@ -29,7 +29,7 @@ class GroupSelectionWidget : public QWidget ...@@ -29,7 +29,7 @@ class GroupSelectionWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: 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? // Current status of the group: is it selected in the view?
bool isToggled() const; bool isToggled() const;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Calamares. If not, see <http://www.gnu.org/licenses/>. # along with Calamares. If not, see <http://www.gnu.org/licenses/>.
import subprocess
import libcalamares import libcalamares
from libcalamares.utils import check_target_env_call, target_env_call from libcalamares.utils import check_target_env_call, target_env_call
...@@ -91,6 +92,22 @@ class PackageManager: ...@@ -91,6 +92,22 @@ class PackageManager:
elif self.backend == "entropy": elif self.backend == "entropy":
check_target_env_call(["equo", "rm"] + pkgs) 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): def run_operations(pkgman, entry):
""" Call package manager with given parameters. """ Call package manager with given parameters.
...@@ -101,8 +118,18 @@ def run_operations(pkgman, entry): ...@@ -101,8 +118,18 @@ def run_operations(pkgman, entry):
for key in entry.keys(): for key in entry.keys():
if key == "install": if key == "install":
pkgman.install(entry[key]) 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": elif key == "remove":
pkgman.remove(entry[key]) 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": elif key == "localInstall":
pkgman.install(entry[key], from_local=True) pkgman.install(entry[key], from_local=True)
...@@ -121,6 +148,10 @@ def run(): ...@@ -121,6 +148,10 @@ def run():
pkgman = PackageManager(backend) pkgman = PackageManager(backend)
operations = libcalamares.job.configuration.get("operations", []) 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: for entry in operations:
run_operations(pkgman, entry) run_operations(pkgman, entry)
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
# - entropy - Sabayon package manager # - entropy - Sabayon package manager
# #
backend: packagekit backend: packagekit
update_db: true
# #
# List of maps with package operations such as install or remove. # List of maps with package operations such as install or remove.
# Distro developers can provide a list of packages to remove # Distro developers can provide a list of packages to remove
...@@ -33,12 +36,12 @@ backend: packagekit ...@@ -33,12 +36,12 @@ backend: packagekit
# - remove: # - remove:
# - pkg3 # - pkg3
# - pkg4 # - pkg4
# - install: # - try_install: # no system install failure if a package cannot be installed
# - pkg5 # - pkg5
# - remove: # - try_remove: # no system install failure if a package cannot be removed
# - pkg2 # - pkg2
# - pkg1 # - pkg1
# install: # - install:
# - pkgs6 # - pkgs6
# - pkg7 # - pkg7
# - localInstall: # - localInstall:
......
...@@ -140,7 +140,8 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass ...@@ -140,7 +140,8 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass
PartitionRole( PartitionRole::Primary ), PartitionRole( PartitionRole::Primary ),
FileSystem::Fat32, FileSystem::Fat32,
firstFreeSector, firstFreeSector,
lastSector lastSector,
PartitionTable::FlagEsp
); );
PartitionInfo::setFormat( efiPartition, true ); PartitionInfo::setFormat( efiPartition, true );
PartitionInfo::setMountPoint( efiPartition, Calamares::JobQueue::instance() PartitionInfo::setMountPoint( efiPartition, Calamares::JobQueue::instance()
......
...@@ -547,30 +547,15 @@ PartitionCoreModule::scanForEfiSystemPartitions() ...@@ -547,30 +547,15 @@ PartitionCoreModule::scanForEfiSystemPartitions()
devices.append( device ); 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 = QList< Partition* > efiSystemPartitions =
KPMHelpers::findPartitions( devices, KPMHelpers::findPartitions( devices,
[]( Partition* partition ) -> bool []( Partition* partition ) -> bool
{ {
QProcess process; if ( partition->activeFlags().testFlag( PartitionTable::FlagEsp ) )
process.setProgram( "sgdisk" );
process.setArguments( { "-i",
QString::number( partition->number() ),
partition->devicePath() } );
process.setProcessChannelMode( QProcess::MergedChannels );
process.start();
if ( process.waitForFinished() )
{
if ( process.readAllStandardOutput()
.contains( "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" ) )
{ {
cDebug() << "Found EFI system partition at" << partition->partitionPath(); cDebug() << "Found EFI system partition at" << partition->partitionPath();
return true; return true;
} }
}
return false; return false;
} ); } );
......
...@@ -119,7 +119,18 @@ def file_copy(source, dest, progress_cb): ...@@ -119,7 +119,18 @@ def file_copy(source, dest, progress_cb):
process.wait() 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 "rsync failed with error code {}.".format(process.returncode)
return None return None
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment