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
This commit is contained in:
parent
27602cf832
commit
e91be5bd12
@ -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
|
||||
|
@ -258,7 +258,7 @@ def vfat_correct_case(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:
|
||||
@ -267,33 +267,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:
|
||||
|
@ -24,6 +24,7 @@ import os
|
||||
import collections
|
||||
import re
|
||||
import libcalamares
|
||||
import configparser
|
||||
|
||||
|
||||
DesktopEnvironment = collections.namedtuple('DesktopEnvironment', ['executable', 'desktop_file'])
|
||||
@ -253,34 +254,31 @@ 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
|
||||
|
||||
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={!s}\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={!s}.desktop\n'.format(default_desktop_environment.desktop_file)
|
||||
else:
|
||||
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:
|
||||
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
|
||||
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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:
|
||||
|
@ -140,7 +140,8 @@ 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()
|
||||
|
@ -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;
|
||||
} );
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user