From a878c1a6109349c8f7182663fae60932a109af9c Mon Sep 17 00:00:00 2001 From: udeved Date: Mon, 28 May 2018 01:31:55 +0200 Subject: [PATCH 001/112] add openrccfg --- src/modules/openrccfg/main.py | 58 ++++++++++++++++++++++++++++ src/modules/openrccfg/module.desc | 5 +++ src/modules/openrccfg/openrccfg.conf | 8 ++++ 3 files changed, 71 insertions(+) create mode 100644 src/modules/openrccfg/main.py create mode 100644 src/modules/openrccfg/module.desc create mode 100644 src/modules/openrccfg/openrccfg.conf diff --git a/src/modules/openrccfg/main.py b/src/modules/openrccfg/main.py new file mode 100644 index 000000000..724b02c3f --- /dev/null +++ b/src/modules/openrccfg/main.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# === This file is part of Calamares - === +# +# Copyright 2016, Artoo +# Copyright 2017, Philip Müller +# Copyright 2018, Artoo +# +# 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 . + +import libcalamares + +from libcalamares.utils import target_env_call +from os.path import exists, join + + +class OpenrcController: + """This is the service controller + """ + + def __init__(self): + self.root = libcalamares.globalstorage.value('rootMountPoint') + self.services = libcalamares.job.configuration.get('services', []) + + def update(self, state): + """Update init scripts + """ + + for svc in self.services[state]: + if exists(self.root + "/etc/init.d/" + svc["name"]): + target_env_call( + ["rc-update", state, svc["name"], svc["runlevel"]] + ) + + def run(self): + """Run the controller + """ + + for state in self.services.keys(): + self.update(state) + +def run(): + """Setup services + """ + + return OpenrcController().run() diff --git a/src/modules/openrccfg/module.desc b/src/modules/openrccfg/module.desc new file mode 100644 index 000000000..1be7af923 --- /dev/null +++ b/src/modules/openrccfg/module.desc @@ -0,0 +1,5 @@ +--- +type: "job" +name: "openrccfg" +interface: "python" +script: "main.py" diff --git a/src/modules/openrccfg/openrccfg.conf b/src/modules/openrccfg/openrccfg.conf new file mode 100644 index 000000000..e10da15ce --- /dev/null +++ b/src/modules/openrccfg/openrccfg.conf @@ -0,0 +1,8 @@ +--- +services: + add: + - name: "NetworkManager" + runlevel: "default" +# del: +# - name: "hwclock" +# runlevel: "boot" From d15ce56c9703f2509fb55b3b497d66ede2c806d9 Mon Sep 17 00:00:00 2001 From: Caio Date: Mon, 4 Jun 2018 16:31:58 -0300 Subject: [PATCH 002/112] [partition] Initial implementation of VolumeGroupBaseDialog. --- src/modules/partition/CMakeLists.txt | 4 + .../partition/core/PartitionCoreModule.cpp | 48 +++++ .../partition/core/PartitionCoreModule.h | 6 + src/modules/partition/core/PartitionInfo.cpp | 4 + .../gui/ListPhysicalVolumeWidgetItem.cpp | 36 ++++ .../gui/ListPhysicalVolumeWidgetItem.h | 37 ++++ src/modules/partition/gui/PartitionPage.cpp | 18 ++ src/modules/partition/gui/PartitionPage.h | 1 + src/modules/partition/gui/PartitionPage.ui | 9 +- .../partition/gui/VolumeGroupBaseDialog.cpp | 42 ++++ .../partition/gui/VolumeGroupBaseDialog.h | 48 +++++ .../partition/gui/VolumeGroupBaseDialog.ui | 193 ++++++++++++++++++ .../partition/jobs/CreateVolumeGroupJob.cpp | 88 ++++++++ .../partition/jobs/CreateVolumeGroupJob.h | 47 +++++ 14 files changed, 580 insertions(+), 1 deletion(-) create mode 100644 src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp create mode 100644 src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h create mode 100644 src/modules/partition/gui/VolumeGroupBaseDialog.cpp create mode 100644 src/modules/partition/gui/VolumeGroupBaseDialog.h create mode 100644 src/modules/partition/gui/VolumeGroupBaseDialog.ui create mode 100644 src/modules/partition/jobs/CreateVolumeGroupJob.cpp create mode 100644 src/modules/partition/jobs/CreateVolumeGroupJob.h diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 156ff86f5..2f0e46bea 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -38,6 +38,7 @@ if ( KPMcore_FOUND ) gui/DeviceInfoWidget.cpp gui/EditExistingPartitionDialog.cpp gui/EncryptWidget.cpp + gui/ListPhysicalVolumeWidgetItem.cpp gui/PartitionPage.cpp gui/PartitionBarsView.cpp gui/PartitionLabelsView.cpp @@ -47,10 +48,12 @@ if ( KPMcore_FOUND ) gui/PrettyRadioButton.cpp gui/ScanningDialog.cpp gui/ReplaceWidget.cpp + gui/VolumeGroupBaseDialog.cpp jobs/ClearMountsJob.cpp jobs/ClearTempMountsJob.cpp jobs/CreatePartitionJob.cpp jobs/CreatePartitionTableJob.cpp + jobs/CreateVolumeGroupJob.cpp jobs/DeletePartitionJob.cpp jobs/FillGlobalStorageJob.cpp jobs/FormatPartitionJob.cpp @@ -65,6 +68,7 @@ if ( KPMcore_FOUND ) gui/EncryptWidget.ui gui/PartitionPage.ui gui/ReplaceWidget.ui + gui/VolumeGroupBaseDialog.ui LINK_PRIVATE_LIBRARIES kpmcore calamaresui diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 43ba33d7b..7229c8305 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -33,6 +33,7 @@ #include "jobs/ClearTempMountsJob.h" #include "jobs/CreatePartitionJob.h" #include "jobs/CreatePartitionTableJob.h" +#include "jobs/CreateVolumeGroupJob.h" #include "jobs/DeletePartitionJob.h" #include "jobs/FillGlobalStorageJob.h" #include "jobs/FormatPartitionJob.h" @@ -44,10 +45,12 @@ // KPMcore #include +#include #include #include #include #include +#include // Qt #include @@ -177,6 +180,8 @@ PartitionCoreModule::doInit() m_bootLoaderModel->init( bootLoaderDevices ); + scanForLVMPVs(); + //FIXME: this should be removed in favor of // proper KPM support for EFI if ( PartUtils::isEfiSystem() ) @@ -263,6 +268,27 @@ PartitionCoreModule::createPartition( Device* device, refresh(); } +void +PartitionCoreModule::createVolumeGroup( QString &vgName, + QVector< const Partition* > pvList, + qint32 peSize ) +{ + CreateVolumeGroupJob* job = new CreateVolumeGroupJob( vgName, pvList, peSize ); + job->updatePreview(); + + LvmDevice* device = new LvmDevice(vgName); + + for ( const Partition* p : pvList ) + device->physicalVolumes() << p; + + DeviceInfo* deviceInfo = new DeviceInfo( device ); + + m_deviceInfos << deviceInfo; + deviceInfo->jobs << Calamares::job_ptr( job ); + + refresh(); +} + void PartitionCoreModule::deletePartition( Device* device, Partition* partition ) { @@ -432,6 +458,12 @@ PartitionCoreModule::efiSystemPartitions() const return m_efiSystemPartitions; } +QList< const Partition* > +PartitionCoreModule::lvmPVs() const +{ + return m_lvmPVs; +} + void PartitionCoreModule::dumpQueue() const { @@ -523,6 +555,22 @@ PartitionCoreModule::scanForEfiSystemPartitions() m_efiSystemPartitions = efiSystemPartitions; } +void +PartitionCoreModule::scanForLVMPVs() +{ + m_lvmPVs.clear(); + + QList< Device* > devices; + + for ( DeviceInfo* deviceInfo : m_deviceInfos ) + devices << deviceInfo->device.data(); + + LvmDevice::scanSystemLVM( devices ); + + for ( auto p : LVM::pvList ) + m_lvmPVs << p.partition().data(); +} + PartitionCoreModule::DeviceInfo* PartitionCoreModule::infoForDevice( const Device* device ) const { diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index 49564dad1..05c029381 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -111,6 +111,8 @@ public: void createPartition( Device* device, Partition* partition, PartitionTable::Flags flags = PartitionTable::FlagNone ); + void createVolumeGroup( QString &vgName, QVector< const Partition* > pvList, qint32 peSize ); + void deletePartition( Device* device, Partition* partition ); void formatPartition( Device* device, Partition* partition ); @@ -132,6 +134,8 @@ public: QList< Partition* > efiSystemPartitions() const; + QList< const Partition* > lvmPVs() const; + /** * @brief findPartitionByMountPoint returns a Partition* for a given mount point. * @param mountPoint the mount point to find a partition for. @@ -194,6 +198,7 @@ private: }; QList< DeviceInfo* > m_deviceInfos; QList< Partition* > m_efiSystemPartitions; + QList< const Partition* > m_lvmPVs; DeviceModel* m_deviceModel; BootLoaderModel* m_bootLoaderModel; @@ -205,6 +210,7 @@ private: void updateHasRootMountPoint(); void updateIsDirty(); void scanForEfiSystemPartitions(); + void scanForLVMPVs(); DeviceInfo* infoForDevice( const Device* ) const; diff --git a/src/modules/partition/core/PartitionInfo.cpp b/src/modules/partition/core/PartitionInfo.cpp index 72cca8976..20cd6f8a9 100644 --- a/src/modules/partition/core/PartitionInfo.cpp +++ b/src/modules/partition/core/PartitionInfo.cpp @@ -19,6 +19,7 @@ #include "core/PartitionInfo.h" // KPMcore +#include #include // Qt @@ -64,6 +65,9 @@ reset( Partition* partition ) bool isDirty( Partition* partition ) { + if ( LvmDevice::s_DirtyPVs.contains( partition ) ) + return true; + return !mountPoint( partition ).isEmpty() || format( partition ); } diff --git a/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp new file mode 100644 index 000000000..cd480aa55 --- /dev/null +++ b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp @@ -0,0 +1,36 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "ListPhysicalVolumeWidgetItem.h" + +#include + +ListPhysicalVolumeWidgetItem::ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked ) + : QListWidgetItem(QString("%1 | %2").arg( partition->deviceNode(), Capacity::formatByteSize( partition->capacity() ))) + , m_partition(partition) +{ + setToolTip( partition->deviceNode() ); + setSizeHint( QSize(0, 32) ); + setCheckState( checked ? Qt::Checked : Qt::Unchecked ); +} + +const Partition* +ListPhysicalVolumeWidgetItem::partition() const +{ + return m_partition; +} diff --git a/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h new file mode 100644 index 000000000..44ba8c3bf --- /dev/null +++ b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h @@ -0,0 +1,37 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef LISTPHYSICALVOLUMEWIDGETITEM_H +#define LISTPHYSICALVOLUMEWIDGETITEM_H + +#include + +#include + +class ListPhysicalVolumeWidgetItem : public QListWidgetItem +{ +public: + ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked ); + + const Partition* partition() const; + +private: + const Partition* m_partition; +}; + +#endif // LISTPHYSICALVOLUMEWIDGETITEM_H diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index c521604fb..adebb3418 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -30,6 +30,7 @@ #include "gui/CreatePartitionDialog.h" #include "gui/EditExistingPartitionDialog.h" #include "gui/ScanningDialog.h" +#include "gui/VolumeGroupBaseDialog.h" #include "ui_PartitionPage.h" #include "ui_CreatePartitionTableDialog.h" @@ -99,6 +100,7 @@ PartitionPage::PartitionPage( PartitionCoreModule* core, QWidget* parent ) connect( m_ui->partitionTreeView, &QAbstractItemView::doubleClicked, this, &PartitionPage::onPartitionViewActivated ); connect( m_ui->revertButton, &QAbstractButton::clicked, this, &PartitionPage::onRevertClicked ); + connect( m_ui->newVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onNewVolumeGroupClicked ); connect( m_ui->newPartitionTableButton, &QAbstractButton::clicked, this, &PartitionPage::onNewPartitionTableClicked ); connect( m_ui->createButton, &QAbstractButton::clicked, this, &PartitionPage::onCreateClicked ); connect( m_ui->editButton, &QAbstractButton::clicked, this, &PartitionPage::onEditClicked ); @@ -178,6 +180,22 @@ PartitionPage::onNewPartitionTableClicked() updateBootLoaderIndex(); } +void +PartitionPage::onNewVolumeGroupClicked() +{ + QString vgName; + qint32 peSize = 4; + + QPointer< VolumeGroupBaseDialog > dlg = new VolumeGroupBaseDialog( vgName, m_core->lvmPVs(), peSize, this ); + + if ( dlg->exec() == QDialog::Accepted ) + { + + } + + delete dlg; +} + void PartitionPage::onCreateClicked() { diff --git a/src/modules/partition/gui/PartitionPage.h b/src/modules/partition/gui/PartitionPage.h index 24cf65675..ef6eeea15 100644 --- a/src/modules/partition/gui/PartitionPage.h +++ b/src/modules/partition/gui/PartitionPage.h @@ -50,6 +50,7 @@ private: PartitionCoreModule* m_core; void updateButtons(); void onNewPartitionTableClicked(); + void onNewVolumeGroupClicked(); void onCreateClicked(); void onEditClicked(); void onDeleteClicked(); diff --git a/src/modules/partition/gui/PartitionPage.ui b/src/modules/partition/gui/PartitionPage.ui index 7d24204c9..2b3d568cf 100644 --- a/src/modules/partition/gui/PartitionPage.ui +++ b/src/modules/partition/gui/PartitionPage.ui @@ -88,6 +88,13 @@ + + + + New Volume Group + + + @@ -145,7 +152,7 @@ - Install boot &loader on: + I&nstall boot loader on: bootLoaderComboBox diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp new file mode 100644 index 000000000..b3535a004 --- /dev/null +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp @@ -0,0 +1,42 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "VolumeGroupBaseDialog.h" +#include "ui_VolumeGroupBaseDialog.h" + +#include "gui/ListPhysicalVolumeWidgetItem.h" + +VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, + QList< const Partition* > pvList, + qint32& peSize, + QWidget *parent) + : QDialog(parent) + , ui(new Ui::VolumeGroupBaseDialog) + , m_vgName(vgName) + , m_peSize(peSize) +{ + ui->setupUi(this); + + for ( const Partition* p : pvList ) + ui->pvList->addItem( new ListPhysicalVolumeWidgetItem(p, false) ); +} + +VolumeGroupBaseDialog::~VolumeGroupBaseDialog() +{ + delete ui; +} diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.h b/src/modules/partition/gui/VolumeGroupBaseDialog.h new file mode 100644 index 000000000..294effb1d --- /dev/null +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.h @@ -0,0 +1,48 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef VOLUMEGROUPBASEDIALOG_H +#define VOLUMEGROUPBASEDIALOG_H + +#include + +#include + +namespace Ui { +class VolumeGroupBaseDialog; +} + +class VolumeGroupBaseDialog : public QDialog +{ + Q_OBJECT + +public: + explicit VolumeGroupBaseDialog(QString& vgName, + QList< const Partition* > pvList, + qint32& peSize, + QWidget* parent = 0); + ~VolumeGroupBaseDialog(); + +private: + Ui::VolumeGroupBaseDialog *ui; + + QString &m_vgName; + qint32 &m_peSize; +}; + +#endif // VOLUMEGROUPBASEDIALOG_H diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.ui b/src/modules/partition/gui/VolumeGroupBaseDialog.ui new file mode 100644 index 000000000..c9cb853b8 --- /dev/null +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.ui @@ -0,0 +1,193 @@ + + + VolumeGroupBaseDialog + + + + 0 + 0 + 611 + 367 + + + + VolumeGroupDialog + + + + + + List of Physical Volumes + + + + + + + + + + Volume Group Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Volume Group Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Physical Extent Size: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Total Size: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + --- + + + Qt::AlignCenter + + + + + + + Used Size: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + --- + + + Qt::AlignCenter + + + + + + + Total Sectors: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + --- + + + Qt::AlignCenter + + + + + + + Quantity of LVs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + --- + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + VolumeGroupBaseDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + VolumeGroupBaseDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/modules/partition/jobs/CreateVolumeGroupJob.cpp b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp new file mode 100644 index 000000000..3b05b684a --- /dev/null +++ b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp @@ -0,0 +1,88 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "CreateVolumeGroupJob.h" + +// KPMcore +#include +#include +#include +#include + +CreateVolumeGroupJob::CreateVolumeGroupJob( QString& vgName, QVector< const Partition* > pvList, const qint32 peSize ) + : m_vgName(vgName) + , m_pvList(pvList) + , m_peSize(peSize) +{ + +} + +QString +CreateVolumeGroupJob::prettyName() const +{ + return tr( "Create new volume group named %1." ) + .arg( m_vgName ); +} + +QString +CreateVolumeGroupJob::prettyDescription() const +{ + return tr( "Create new volume group named %1." ) + .arg( m_vgName ); +} + +QString +CreateVolumeGroupJob::prettyStatusMessage() const +{ + return tr( "Creating new volume group named %1." ) + .arg( m_vgName ); +} + +Calamares::JobResult +CreateVolumeGroupJob::exec() +{ + Report report( nullptr ); + + QVector< const Partition* > pvList; + + pvList << m_pvList; + + CreateVolumeGroupOperation op( m_vgName, m_pvList, m_peSize ); + + op.setStatus( Operation::StatusRunning ); + + QString message = tr( "The installer failed to create a volume group named '%1'.").arg( m_vgName ); + if (op.execute(report)) + return Calamares::JobResult::ok(); + + return Calamares::JobResult::error(message, report.toText()); +} + +void +CreateVolumeGroupJob::updatePreview() +{ + LvmDevice::s_DirtyPVs << m_pvList; +} + +void +CreateVolumeGroupJob::undoPreview() +{ + for ( const auto& pv : m_pvList ) + if ( LvmDevice::s_DirtyPVs.contains( pv )) + LvmDevice::s_DirtyPVs.removeAll( pv ); +} diff --git a/src/modules/partition/jobs/CreateVolumeGroupJob.h b/src/modules/partition/jobs/CreateVolumeGroupJob.h new file mode 100644 index 000000000..9e84fba73 --- /dev/null +++ b/src/modules/partition/jobs/CreateVolumeGroupJob.h @@ -0,0 +1,47 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef CREATEVOLUMEGROUPJOB_H +#define CREATEVOLUMEGROUPJOB_H + +#include + +#include + +#include + +class CreateVolumeGroupJob : public Calamares::Job +{ +public: + CreateVolumeGroupJob( QString& vgName, QVector< const Partition* > pvList, const qint32 peSize ); + + QString prettyName() const override; + QString prettyDescription() const override; + QString prettyStatusMessage() const override; + Calamares::JobResult exec() override; + + void updatePreview(); + void undoPreview(); + +private: + QString m_vgName; + QVector< const Partition* > m_pvList; + qint32 m_peSize; +}; + +#endif // CREATEVOLUMEGROUPJOB_H From 208d58bcd93edfa31e80e8d1a99425573f929de5 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Jun 2018 17:22:22 -0300 Subject: [PATCH 003/112] [partition] Including CreateVolumeGroupDialog and fixing some of its GUI issues. --- src/modules/partition/CMakeLists.txt | 1 + src/modules/partition/core/DeviceModel.cpp | 16 ++ src/modules/partition/core/DeviceModel.h | 2 + .../partition/core/PartitionCoreModule.cpp | 37 ++++- .../partition/core/PartitionCoreModule.h | 9 +- .../partition/gui/CreateVolumeGroupDialog.cpp | 53 +++++++ .../partition/gui/CreateVolumeGroupDialog.h | 39 +++++ src/modules/partition/gui/PartitionPage.cpp | 47 +++++- .../partition/gui/VolumeGroupBaseDialog.cpp | 148 +++++++++++++++++- .../partition/gui/VolumeGroupBaseDialog.h | 49 +++++- .../partition/gui/VolumeGroupBaseDialog.ui | 41 +++-- .../partition/jobs/CreateVolumeGroupJob.cpp | 4 - 12 files changed, 409 insertions(+), 37 deletions(-) create mode 100644 src/modules/partition/gui/CreateVolumeGroupDialog.cpp create mode 100644 src/modules/partition/gui/CreateVolumeGroupDialog.h diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 2f0e46bea..279eaf0ef 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -35,6 +35,7 @@ if ( KPMcore_FOUND ) gui/BootInfoWidget.cpp gui/ChoicePage.cpp gui/CreatePartitionDialog.cpp + gui/CreateVolumeGroupDialog.cpp gui/DeviceInfoWidget.cpp gui/EditExistingPartitionDialog.cpp gui/EncryptWidget.cpp diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index 00058bac4..95d7ddb72 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -25,10 +25,12 @@ // KPMcore #include +#include // KF5 #include +#include #include // STL @@ -116,3 +118,17 @@ DeviceModel::swapDevice( Device* oldDevice, Device* newDevice ) emit dataChanged( index( indexOfOldDevice ), index( indexOfOldDevice ) ); } + +void +DeviceModel::addDevice( Device *device ) +{ + beginResetModel(); + + m_devices << device; + std::sort( m_devices.begin(), m_devices.end(), []( const Device* dev1, const Device* dev2 ) + { + return dev1->deviceNode() < dev2->deviceNode(); + } ); + + endResetModel(); +} diff --git a/src/modules/partition/core/DeviceModel.h b/src/modules/partition/core/DeviceModel.h index ccca426bd..84f1c3c9d 100644 --- a/src/modules/partition/core/DeviceModel.h +++ b/src/modules/partition/core/DeviceModel.h @@ -49,6 +49,8 @@ public: void swapDevice( Device* oldDevice, Device* newDevice ); + void addDevice( Device* device ); + private: QList< Device* > m_devices; }; diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 7229c8305..710f85378 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -273,6 +273,10 @@ PartitionCoreModule::createVolumeGroup( QString &vgName, QVector< const Partition* > pvList, qint32 peSize ) { + // Appending '_' character in case of repeated VG name + while ( hasVGwithThisName( vgName ) ) + vgName.append('_'); + CreateVolumeGroupJob* job = new CreateVolumeGroupJob( vgName, pvList, peSize ); job->updatePreview(); @@ -283,6 +287,10 @@ PartitionCoreModule::createVolumeGroup( QString &vgName, DeviceInfo* deviceInfo = new DeviceInfo( device ); + deviceInfo->partitionModel->init( device, osproberEntries() ); + + m_deviceModel->addDevice( device ); + m_deviceInfos << deviceInfo; deviceInfo->jobs << Calamares::job_ptr( job ); @@ -458,12 +466,37 @@ PartitionCoreModule::efiSystemPartitions() const return m_efiSystemPartitions; } -QList< const Partition* > +QVector< const Partition* > PartitionCoreModule::lvmPVs() const { return m_lvmPVs; } +bool +PartitionCoreModule::hasVGwithThisName( const QString& name ) const +{ + for ( DeviceInfo* d : m_deviceInfos ) + if ( dynamic_cast(d->device.data()) && + d->device.data()->name() == name) + return true; + + return false; +} + +bool +PartitionCoreModule::isInVG( const Partition *partition ) const +{ + for ( DeviceInfo* d : m_deviceInfos ) + { + LvmDevice* vg = dynamic_cast( d->device.data() ); + + if ( vg && vg->physicalVolumes().contains( partition )) + return true; + } + + return false; +} + void PartitionCoreModule::dumpQueue() const { @@ -503,6 +536,8 @@ PartitionCoreModule::refresh() updateIsDirty(); m_bootLoaderModel->update(); + scanForLVMPVs(); + //FIXME: this should be removed in favor of // proper KPM support for EFI if ( PartUtils::isEfiSystem() ) diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index 05c029381..cedda391d 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -24,6 +24,7 @@ #include "Typedefs.h" // KPMcore +#include #include // Qt @@ -134,7 +135,11 @@ public: QList< Partition* > efiSystemPartitions() const; - QList< const Partition* > lvmPVs() const; + QVector< const Partition* > lvmPVs() const; + + bool hasVGwithThisName( const QString& name ) const; + + bool isInVG( const Partition* partition ) const; /** * @brief findPartitionByMountPoint returns a Partition* for a given mount point. @@ -198,7 +203,7 @@ private: }; QList< DeviceInfo* > m_deviceInfos; QList< Partition* > m_efiSystemPartitions; - QList< const Partition* > m_lvmPVs; + QVector< const Partition* > m_lvmPVs; DeviceModel* m_deviceModel; BootLoaderModel* m_bootLoaderModel; diff --git a/src/modules/partition/gui/CreateVolumeGroupDialog.cpp b/src/modules/partition/gui/CreateVolumeGroupDialog.cpp new file mode 100644 index 000000000..f1ed32551 --- /dev/null +++ b/src/modules/partition/gui/CreateVolumeGroupDialog.cpp @@ -0,0 +1,53 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "CreateVolumeGroupDialog.h" + +#include +#include + +#include +#include +#include + +CreateVolumeGroupDialog::CreateVolumeGroupDialog( QString& vgName, + QVector< const Partition* >& selectedPVs, + QVector< const Partition* > pvList, + qint32& peSize, + QWidget* parent ) + : VolumeGroupBaseDialog( vgName, pvList, peSize, parent ) + , m_selectedPVs( selectedPVs ) +{ + setWindowTitle( "Create Volume Group" ); + + vgType()->setEnabled( false ); +} + +void +CreateVolumeGroupDialog::accept() +{ + QString& name = vgNameValue(); + name = vgName()->text(); + + m_selectedPVs << checkedItems(); + + qint32& pe = peSizeValue(); + pe = peSize()->value(); + + QDialog::accept(); +} diff --git a/src/modules/partition/gui/CreateVolumeGroupDialog.h b/src/modules/partition/gui/CreateVolumeGroupDialog.h new file mode 100644 index 000000000..eb2ced137 --- /dev/null +++ b/src/modules/partition/gui/CreateVolumeGroupDialog.h @@ -0,0 +1,39 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef CREATEVOLUMEGROUPDIALOG_H +#define CREATEVOLUMEGROUPDIALOG_H + +#include "gui/VolumeGroupBaseDialog.h" + +class CreateVolumeGroupDialog : public VolumeGroupBaseDialog +{ +public: + CreateVolumeGroupDialog( QString& vgName, + QVector< const Partition* >& selectedPVs, + QVector< const Partition* > pvList, + qint32& peSize, + QWidget* parent ); + + void accept() override; + +private: + QVector< const Partition* >& m_selectedPVs; +}; + +#endif // CREATEVOLUMEGROUPDIALOG_H diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index adebb3418..503a4e2ea 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -28,9 +28,9 @@ #include "core/PartUtils.h" #include "core/KPMHelpers.h" #include "gui/CreatePartitionDialog.h" +#include "gui/CreateVolumeGroupDialog.h" #include "gui/EditExistingPartitionDialog.h" #include "gui/ScanningDialog.h" -#include "gui/VolumeGroupBaseDialog.h" #include "ui_PartitionPage.h" #include "ui_CreatePartitionTableDialog.h" @@ -133,6 +133,8 @@ PartitionPage::updateButtons() bool isFree = KPMHelpers::isPartitionFreeSpace( partition ); bool isExtended = partition->roles().has( PartitionRole::Extended ); + bool isInVG = m_core->isInVG( partition ); + create = isFree; // Keep it simple for now: do not support editing extended partitions as // it does not work with our current edit implementation which is @@ -140,8 +142,9 @@ PartitionPage::updateButtons() // because they need to be created *before* creating logical partitions // inside them, so an edit must be applied without altering the job // order. + // TODO: See if LVM PVs can be edited in Calamares edit = !isFree && !isExtended; - del = !isFree; + del = !isFree && !isInVG; } if ( m_ui->deviceComboBox->currentIndex() >= 0 ) @@ -184,13 +187,51 @@ void PartitionPage::onNewVolumeGroupClicked() { QString vgName; + QVector< const Partition* > selectedPVs; qint32 peSize = 4; - QPointer< VolumeGroupBaseDialog > dlg = new VolumeGroupBaseDialog( vgName, m_core->lvmPVs(), peSize, this ); + QVector< const Partition* > availablePVs; + + for ( const Partition* p : m_core->lvmPVs() ) + if ( !m_core->isInVG( p ) ) + availablePVs << p; + + QPointer< CreateVolumeGroupDialog > dlg = new CreateVolumeGroupDialog( vgName, + selectedPVs, + availablePVs, + peSize, + this ); if ( dlg->exec() == QDialog::Accepted ) { + QModelIndex partitionIndex = m_ui->partitionTreeView->currentIndex(); + if ( partitionIndex.isValid() ) + { + const PartitionModel* model = static_cast< const PartitionModel* >( partitionIndex.model() ); + Q_ASSERT( model ); + Partition* partition = model->partitionForIndex( partitionIndex ); + Q_ASSERT( partition ); + + // Disable delete button if current partition was selected to be in VG + // TODO: Should Calamares edit LVM PVs which are in VGs? + if ( selectedPVs.contains( partition ) ) + m_ui->deleteButton->setEnabled( false ); + } + + QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); + Q_ASSERT( deviceIndex.isValid() ); + + QVariant previousDeviceData = m_core->deviceModel()->data( deviceIndex, Qt::ToolTipRole ); + + m_core->createVolumeGroup( vgName, selectedPVs, peSize ); + + // As createVolumeGroup method call resets deviceModel, + // is needed to set the current index in deviceComboBox as the previous one + int previousIndex = m_ui->deviceComboBox->findData( previousDeviceData, Qt::ToolTipRole ); + + if ( previousIndex != -1 ) + m_ui->deviceComboBox->setCurrentIndex( previousIndex ); } delete dlg; diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp index b3535a004..e5da2c0ad 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp @@ -21,22 +21,160 @@ #include "gui/ListPhysicalVolumeWidgetItem.h" +#include + +#include +#include +#include +#include +#include +#include + VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, - QList< const Partition* > pvList, + QVector< const Partition* > pvList, qint32& peSize, - QWidget *parent) + QWidget *parent ) : QDialog(parent) , ui(new Ui::VolumeGroupBaseDialog) - , m_vgName(vgName) - , m_peSize(peSize) + , m_vgNameValue(vgName) + , m_peSizeValue(peSize) + , m_totalSizeValue(0) + , m_usedSizeValue(0) { ui->setupUi(this); for ( const Partition* p : pvList ) - ui->pvList->addItem( new ListPhysicalVolumeWidgetItem(p, false) ); + ui->pvList->addItem( new ListPhysicalVolumeWidgetItem( p, false ) ); + + ui->vgType->addItems( QStringList() << "LVM" << "RAID" ); + ui->vgType->setCurrentIndex(0); + + QRegularExpression re(R"(^(?!_|\.)[\w\-.+]+)"); + ui->vgName->setValidator( new QRegularExpressionValidator( re, this ) ); + ui->vgName->setText( m_vgNameValue ); + + ui->peSize->setValue( m_peSizeValue ); + + updateOkButton(); + updateTotalSize(); + + connect( ui->pvList, &QListWidget::itemChanged, this, + [&](QListWidgetItem*) { + updateTotalSize(); + updateOkButton(); + } ); + + connect( ui->peSize, qOverload(&QSpinBox::valueChanged), this, + [&](int) { + updateTotalSectors(); + updateOkButton(); + }); + + connect( ui->vgName, &QLineEdit::textChanged, this, + [&](const QString&) { + updateOkButton(); + }); } VolumeGroupBaseDialog::~VolumeGroupBaseDialog() { delete ui; } + +QVector< const Partition* > +VolumeGroupBaseDialog::checkedItems() const +{ + QVector< const Partition* > items; + + for ( int i = 0; i < ui->pvList->count(); i++) { + ListPhysicalVolumeWidgetItem* item = dynamic_cast< ListPhysicalVolumeWidgetItem* >( ui->pvList->item(i) ); + + if ( item && item->checkState() == Qt::Checked ) + items << item->partition(); + } + + return items; +} + +bool +VolumeGroupBaseDialog::isSizeValid() const +{ + return m_totalSizeValue >= m_usedSizeValue; +} + +void +VolumeGroupBaseDialog::updateOkButton() +{ + okButton()->setEnabled(isSizeValid() && + !checkedItems().empty() && + !ui->vgName->text().isEmpty() && + ui->peSize->value() > 0); +} + +void +VolumeGroupBaseDialog::updateTotalSize() +{ + m_totalSizeValue = 0; + + for ( const Partition *p : checkedItems()) + m_totalSizeValue += p->capacity() - p->capacity() % (ui->peSize->value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB)); + + ui->totalSize->setText(Capacity::formatByteSize(m_totalSizeValue)); + + updateTotalSectors(); +} + +void +VolumeGroupBaseDialog::updateTotalSectors() +{ + qint32 totalSectors = 0; + + qint32 extentSize = ui->peSize->value() * Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB); + + if ( extentSize > 0 ) + totalSectors = m_totalSizeValue / extentSize; + + ui->totalSectors->setText( QString::number( totalSectors ) ); +} + +QString& +VolumeGroupBaseDialog::vgNameValue() const +{ + return m_vgNameValue; +} + +qint32& +VolumeGroupBaseDialog::peSizeValue() const +{ + return m_peSizeValue; +} + +QLineEdit* +VolumeGroupBaseDialog::vgName() const +{ + return ui->vgName; +} + +QComboBox* +VolumeGroupBaseDialog::vgType() const +{ + return ui->vgType; +} + +QSpinBox* +VolumeGroupBaseDialog::peSize() const +{ + return ui->peSize; +} + +QListWidget* +VolumeGroupBaseDialog::pvList() const +{ + return ui->pvList; +} + +QPushButton* +VolumeGroupBaseDialog::okButton() const +{ + return ui->buttonBox->button( QDialogButtonBox::StandardButton::Ok ); +} diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.h b/src/modules/partition/gui/VolumeGroupBaseDialog.h index 294effb1d..0b4a48372 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.h +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.h @@ -27,22 +27,55 @@ namespace Ui { class VolumeGroupBaseDialog; } +class QComboBox; +class QLineEdit; +class QListWidget; +class QSpinBox; + class VolumeGroupBaseDialog : public QDialog { Q_OBJECT public: - explicit VolumeGroupBaseDialog(QString& vgName, - QList< const Partition* > pvList, - qint32& peSize, - QWidget* parent = 0); + explicit VolumeGroupBaseDialog( QString& vgName, + QVector< const Partition* > pvList, + qint32& peSize, + QWidget* parent = nullptr ); ~VolumeGroupBaseDialog(); -private: - Ui::VolumeGroupBaseDialog *ui; +protected: + virtual void updateOkButton(); - QString &m_vgName; - qint32 &m_peSize; + void updateTotalSize(); + + void updateTotalSectors(); + + QVector< const Partition* > checkedItems() const; + + bool isSizeValid() const; + + QString& vgNameValue() const; + + qint32& peSizeValue() const; + + QLineEdit* vgName() const; + + QComboBox* vgType() const; + + QSpinBox* peSize() const; + + QListWidget* pvList() const; + + QPushButton* okButton() const; + +private: + Ui::VolumeGroupBaseDialog* ui; + + QString& m_vgNameValue; + qint32& m_peSizeValue; + + qint64 m_totalSizeValue; + qint64 m_usedSizeValue; }; #endif // VOLUMEGROUPBASEDIALOG_H diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.ui b/src/modules/partition/gui/VolumeGroupBaseDialog.ui index c9cb853b8..b45d204e2 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.ui +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.ui @@ -25,7 +25,7 @@ - + Volume Group Name: @@ -35,10 +35,10 @@ - + - + Volume Group Type: @@ -48,10 +48,10 @@ - + - + Physical Extent Size: @@ -61,10 +61,23 @@ - + + + MiB + + + 1 + + + 999 + + + 4 + + - + Total Size: @@ -74,7 +87,7 @@ - + --- @@ -84,7 +97,7 @@ - + Used Size: @@ -94,7 +107,7 @@ - + --- @@ -104,7 +117,7 @@ - + Total Sectors: @@ -114,7 +127,7 @@ - + --- @@ -124,7 +137,7 @@ - + Quantity of LVs: @@ -134,7 +147,7 @@ - + --- diff --git a/src/modules/partition/jobs/CreateVolumeGroupJob.cpp b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp index 3b05b684a..7debd9475 100644 --- a/src/modules/partition/jobs/CreateVolumeGroupJob.cpp +++ b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp @@ -58,10 +58,6 @@ CreateVolumeGroupJob::exec() { Report report( nullptr ); - QVector< const Partition* > pvList; - - pvList << m_pvList; - CreateVolumeGroupOperation op( m_vgName, m_pvList, m_peSize ); op.setStatus( Operation::StatusRunning ); From e5351cdf3c0d3d548ed4f82456acb942fe960eef Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 7 Jun 2018 17:49:25 -0300 Subject: [PATCH 004/112] [partition] Don't show capacity of new LVM VGs in DeviceModel. --- src/modules/partition/core/DeviceModel.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index 95d7ddb72..fe4f71b4f 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -79,10 +79,18 @@ DeviceModel::data( const QModelIndex& index, int role ) const if ( device->name().isEmpty() ) return device->deviceNode(); else - return tr( "%1 - %2 (%3)" ) - .arg( device->name() ) - .arg( KFormat().formatByteSize( device->capacity() ) ) - .arg( device->deviceNode() ); + { + if ( device->capacity() != 1 ) + return tr( "%1 - %2 (%3)" ) + .arg( device->name() ) + .arg( KFormat().formatByteSize( device->capacity() ) ) + .arg( device->deviceNode() ); + // Newly LVM VGs don't have capacity property yet (i.e. always has 1B capacity), so don't show it for a while + else + return tr( "%1 - (%2)" ) + .arg( device->name() ) + .arg( device->deviceNode() ); + } case Qt::DecorationRole: return CalamaresUtils::defaultPixmap( CalamaresUtils::PartitionDisk, CalamaresUtils::Original, From f8897e0e0b7800dbac9f5d95fd7a05debf697702 Mon Sep 17 00:00:00 2001 From: Caio Date: Fri, 8 Jun 2018 18:52:53 -0300 Subject: [PATCH 005/112] [partition] Including new LVM PVs in LVM VG creation GUI. --- src/modules/partition/core/DeviceModel.cpp | 3 +-- .../partition/core/PartitionCoreModule.cpp | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index fe4f71b4f..ba0df2c18 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -25,7 +25,6 @@ // KPMcore #include -#include // KF5 #include @@ -80,7 +79,7 @@ DeviceModel::data( const QModelIndex& index, int role ) const return device->deviceNode(); else { - if ( device->capacity() != 1 ) + if ( device->logicalSize() >= 0 && device->totalLogical() >= 0 ) return tr( "%1 - %2 (%3)" ) .arg( device->name() ) .arg( KFormat().formatByteSize( device->capacity() ) ) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 710f85378..d6be78844 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include // Qt @@ -604,6 +605,30 @@ PartitionCoreModule::scanForLVMPVs() for ( auto p : LVM::pvList ) m_lvmPVs << p.partition().data(); + + for ( DeviceInfo* d : m_deviceInfos ) + { + for ( auto job : d->jobs ) + { + // Including new LVM PVs + CreatePartitionJob* partJob = dynamic_cast( job.data() ); + if ( partJob ) + { + Partition* p = partJob->partition(); + + if ( p->fileSystem().type() == FileSystem::Type::Lvm2_PV ) + m_lvmPVs << p; + else if ( p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2 ) + { + // Encrypted LVM PVs + FileSystem* innerFS = static_cast(&p->fileSystem())->innerFS(); + + if ( innerFS && innerFS->type() == FileSystem::Type::Lvm2_PV ) + m_lvmPVs << p; + } + } + } + } } PartitionCoreModule::DeviceInfo* From 0465cc4214cf6fc47c15c003067cb731eb1d021e Mon Sep 17 00:00:00 2001 From: Caio Date: Fri, 8 Jun 2018 20:20:05 -0300 Subject: [PATCH 006/112] [partition] Including revert on creation of LVM VGs. --- src/modules/partition/core/DeviceModel.cpp | 14 +++++++++ src/modules/partition/core/DeviceModel.h | 2 ++ .../partition/core/PartitionCoreModule.cpp | 30 +++++++++++++++++-- src/modules/partition/gui/PartitionPage.cpp | 11 +++---- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index ba0df2c18..260315729 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -139,3 +139,17 @@ DeviceModel::addDevice( Device *device ) endResetModel(); } + +void +DeviceModel::removeDevice( Device *device ) +{ + beginResetModel(); + + m_devices.removeAll( device ); + std::sort( m_devices.begin(), m_devices.end(), []( const Device* dev1, const Device* dev2 ) + { + return dev1->deviceNode() < dev2->deviceNode(); + } ); + + endResetModel(); +} diff --git a/src/modules/partition/core/DeviceModel.h b/src/modules/partition/core/DeviceModel.h index 84f1c3c9d..2e2f99342 100644 --- a/src/modules/partition/core/DeviceModel.h +++ b/src/modules/partition/core/DeviceModel.h @@ -51,6 +51,8 @@ public: void addDevice( Device* device ); + void removeDevice( Device* device ); + private: QList< Device* > m_devices; }; diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index d6be78844..fc7ce9753 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -680,8 +680,33 @@ PartitionCoreModule::revert() void PartitionCoreModule::revertAllDevices() { - foreach ( DeviceInfo* devInfo, m_deviceInfos ) - revertDevice( devInfo->device.data() ); + for ( auto it = m_deviceInfos.begin(); it != m_deviceInfos.end(); ) + { + // In new VGs device info, there will be always a CreateVolumeGroupJob as the first job in jobs list + if ( !( *it )->jobs.empty() ) + { + CreateVolumeGroupJob* vgJob = dynamic_cast( ( *it )->jobs[0].data() ); + + if ( vgJob ) + { + vgJob->undoPreview(); + + ( *it )->forgetChanges(); + + m_deviceModel->removeDevice( ( *it )->device.data() ); + + it = m_deviceInfos.erase( it ); + + scanForLVMPVs(); + } + } + else + { + revertDevice( ( *it )->device.data() ); + ++it; + } + } + refresh(); } @@ -691,6 +716,7 @@ PartitionCoreModule::revertDevice( Device* dev ) { QMutexLocker locker( &m_revertMutex ); DeviceInfo* devInfo = infoForDevice( dev ); + if ( !devInfo ) return; devInfo->forgetChanges(); diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index 503a4e2ea..550e356c0 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -222,16 +222,17 @@ PartitionPage::onNewVolumeGroupClicked() QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); Q_ASSERT( deviceIndex.isValid() ); - QVariant previousDeviceData = m_core->deviceModel()->data( deviceIndex, Qt::ToolTipRole ); + QVariant previousIndexDeviceData = m_core->deviceModel()->data( deviceIndex, Qt::ToolTipRole ); + // Creating new VG m_core->createVolumeGroup( vgName, selectedPVs, peSize ); // As createVolumeGroup method call resets deviceModel, // is needed to set the current index in deviceComboBox as the previous one - int previousIndex = m_ui->deviceComboBox->findData( previousDeviceData, Qt::ToolTipRole ); + int previousIndex = m_ui->deviceComboBox->findData( previousIndexDeviceData, Qt::ToolTipRole ); - if ( previousIndex != -1 ) - m_ui->deviceComboBox->setCurrentIndex( previousIndex ); + m_ui->deviceComboBox->setCurrentIndex( ( previousIndex < 0 ) ? 0 : previousIndex ); + updateFromCurrentDevice(); } delete dlg; @@ -301,7 +302,7 @@ PartitionPage::onRevertClicked() int oldIndex = m_ui->deviceComboBox->currentIndex(); m_core->revertAllDevices(); - m_ui->deviceComboBox->setCurrentIndex( oldIndex ); + m_ui->deviceComboBox->setCurrentIndex( ( oldIndex < 0 ) ? 0 : oldIndex ); updateFromCurrentDevice(); } ), [ this ]{ From 3b6c764f753f92cac394c4b57b371719b8c2cc5c Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Mon, 11 Jun 2018 18:38:57 -0300 Subject: [PATCH 007/112] [partition] Fixing revert device loop error in PartitionCoreModule::revertAllDevices. --- src/modules/partition/core/PartitionCoreModule.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index fc7ce9753..1f84e55be 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -683,7 +683,7 @@ PartitionCoreModule::revertAllDevices() for ( auto it = m_deviceInfos.begin(); it != m_deviceInfos.end(); ) { // In new VGs device info, there will be always a CreateVolumeGroupJob as the first job in jobs list - if ( !( *it )->jobs.empty() ) + if ( dynamic_cast( ( *it )->device.data() ) && !( *it )->jobs.empty() ) { CreateVolumeGroupJob* vgJob = dynamic_cast( ( *it )->jobs[0].data() ); @@ -697,14 +697,12 @@ PartitionCoreModule::revertAllDevices() it = m_deviceInfos.erase( it ); - scanForLVMPVs(); + continue; } } - else - { - revertDevice( ( *it )->device.data() ); - ++it; - } + + revertDevice( ( *it )->device.data() ); + ++it; } refresh(); From 98a158c6e5d3920cd92423921c3b25805a914e74 Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Thu, 14 Jun 2018 15:37:00 -0300 Subject: [PATCH 008/112] [partition] kpmcore latest release doesn't support FileSystem::Type::Luks2 --- src/modules/partition/CMakeLists.txt | 4 ++++ src/modules/partition/core/PartitionCoreModule.cpp | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 279eaf0ef..874440177 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -12,6 +12,10 @@ set_package_properties( ) if ( KPMcore_FOUND ) + if ( KPMcore_VERSION VERSION_GREATER "3.3.0") + add_definitions(-DWITH_KPMCOREGT33) # kpmcore greater than 3.3 + endif() + include_directories( ${KPMCORE_INCLUDE_DIR} ) include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui ) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 1f84e55be..9646d31cd 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -618,7 +618,7 @@ PartitionCoreModule::scanForLVMPVs() if ( p->fileSystem().type() == FileSystem::Type::Lvm2_PV ) m_lvmPVs << p; - else if ( p->fileSystem().type() == FileSystem::Type::Luks || p->fileSystem().type() == FileSystem::Type::Luks2 ) + else if ( p->fileSystem().type() == FileSystem::Type::Luks ) { // Encrypted LVM PVs FileSystem* innerFS = static_cast(&p->fileSystem())->innerFS(); @@ -626,6 +626,16 @@ PartitionCoreModule::scanForLVMPVs() if ( innerFS && innerFS->type() == FileSystem::Type::Lvm2_PV ) m_lvmPVs << p; } +#ifdef WITH_KPMCOREGT33 + else if ( p->fileSystem().type() == FileSystem::Type::Luks2 ) + { + // Encrypted LVM PVs + FileSystem* innerFS = static_cast(&p->fileSystem())->innerFS(); + + if ( innerFS && innerFS->type() == FileSystem::Type::Lvm2_PV ) + m_lvmPVs << p; + } +#endif } } } From 88e082d53185b1b559feaca2c3062279a27111b3 Mon Sep 17 00:00:00 2001 From: udeved Date: Sun, 3 Jun 2018 22:30:08 +0200 Subject: [PATCH 009/112] openrccfg: add small documentation in conf, make service location configurable --- src/modules/openrccfg/main.py | 15 ++++++----- src/modules/openrccfg/openrccfg.conf | 37 +++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/modules/openrccfg/main.py b/src/modules/openrccfg/main.py index 724b02c3f..9dc6bf1ff 100644 --- a/src/modules/openrccfg/main.py +++ b/src/modules/openrccfg/main.py @@ -27,22 +27,25 @@ from os.path import exists, join class OpenrcController: - """This is the service controller + """This is the openrc service controller """ def __init__(self): self.root = libcalamares.globalstorage.value('rootMountPoint') self.services = libcalamares.job.configuration.get('services', []) + self.initdDir = libcalamares.job.configuration['initdDir'] + self.runlevelsDir = libcalamares.job.configuration['runlevelsDir'] def update(self, state): - """Update init scripts + """call rc-update for each service listed """ for svc in self.services[state]: - if exists(self.root + "/etc/init.d/" + svc["name"]): - target_env_call( - ["rc-update", state, svc["name"], svc["runlevel"]] - ) + if exists(self.root + self.initdDir + "/" + svc["name"]): + if exists(self.root + self.runlevelsDir + "/" + svc["runlevel"]): + target_env_call( + ["rc-update", state, svc["name"], svc["runlevel"]] + ) def run(self): """Run the controller diff --git a/src/modules/openrccfg/openrccfg.conf b/src/modules/openrccfg/openrccfg.conf index e10da15ce..efd56bc14 100644 --- a/src/modules/openrccfg/openrccfg.conf +++ b/src/modules/openrccfg/openrccfg.conf @@ -1,8 +1,39 @@ +# operccfg +# openrc services module to set service runlevels via rc-update in the chroot +# +# format of the conf +### +# services: +# add: +# - name: foo1 +# runlevel: default +# - name: foo2 +# runlevel: nonetwork +# del: +# - name: foo3 +# runlevel: default +# +# initdDir: /etc/init.d +# +# runlevelsDir: /etc/runlevels +#### +# add: list of services and their runlevels to add +# del: list of services and their runlevels to delete +# name: the service name +# runlevel: can hold any runlevel present on the target system +# initdDir: holds the openrc service directory location +# runlevelsDir: holds the runlevels directory location +# +# handle del with care and only use it if absolutely necessary +# if a service is listed in the conf but is not present/detected on the target system, +# or a runlevel does not exist, it will be ignored and skipped +# --- services: add: - name: "NetworkManager" runlevel: "default" -# del: -# - name: "hwclock" -# runlevel: "boot" + +initdDir: /etc/init.d + +runlevelsDir: /etc/runlevels From 295e14530e4e1f3c1ae86032962d048ff3259597 Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Tue, 26 Jun 2018 00:38:52 -0300 Subject: [PATCH 012/112] [partition] Adding resizing, deactivating and removing procedures for LVM VGs. --- src/modules/partition/CMakeLists.txt | 4 + .../partition/core/PartitionCoreModule.cpp | 116 ++++++++++++++++-- .../partition/core/PartitionCoreModule.h | 11 ++ .../partition/gui/CreateVolumeGroupDialog.cpp | 9 +- .../partition/gui/CreateVolumeGroupDialog.h | 4 +- src/modules/partition/gui/PartitionPage.cpp | 80 +++++++++++- src/modules/partition/gui/PartitionPage.h | 3 + src/modules/partition/gui/PartitionPage.ui | 54 ++++++-- .../partition/gui/ResizeVolumeGroupDialog.cpp | 62 ++++++++++ .../partition/gui/ResizeVolumeGroupDialog.h | 40 ++++++ .../partition/gui/VolumeGroupBaseDialog.cpp | 24 ++-- .../partition/gui/VolumeGroupBaseDialog.h | 8 +- .../jobs/DeactivateVolumeGroupJob.cpp | 69 +++++++++++ .../partition/jobs/DeactivateVolumeGroupJob.h | 40 ++++++ .../partition/jobs/RemoveVolumeGroupJob.cpp | 66 ++++++++++ .../partition/jobs/RemoveVolumeGroupJob.h | 40 ++++++ .../partition/jobs/ResizeVolumeGroupJob.cpp | 101 +++++++++++++++ .../partition/jobs/ResizeVolumeGroupJob.h | 48 ++++++++ 18 files changed, 738 insertions(+), 41 deletions(-) create mode 100644 src/modules/partition/gui/ResizeVolumeGroupDialog.cpp create mode 100644 src/modules/partition/gui/ResizeVolumeGroupDialog.h create mode 100644 src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp create mode 100644 src/modules/partition/jobs/DeactivateVolumeGroupJob.h create mode 100644 src/modules/partition/jobs/RemoveVolumeGroupJob.cpp create mode 100644 src/modules/partition/jobs/RemoveVolumeGroupJob.h create mode 100644 src/modules/partition/jobs/ResizeVolumeGroupJob.cpp create mode 100644 src/modules/partition/jobs/ResizeVolumeGroupJob.h diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 874440177..bfc967f3d 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -51,6 +51,7 @@ if ( KPMcore_FOUND ) gui/PartitionSplitterWidget.cpp gui/PartitionViewStep.cpp gui/PrettyRadioButton.cpp + gui/ResizeVolumeGroupDialog.cpp gui/ScanningDialog.cpp gui/ReplaceWidget.cpp gui/VolumeGroupBaseDialog.cpp @@ -59,11 +60,14 @@ if ( KPMcore_FOUND ) jobs/CreatePartitionJob.cpp jobs/CreatePartitionTableJob.cpp jobs/CreateVolumeGroupJob.cpp + jobs/DeactivateVolumeGroupJob.cpp jobs/DeletePartitionJob.cpp jobs/FillGlobalStorageJob.cpp jobs/FormatPartitionJob.cpp jobs/PartitionJob.cpp + jobs/RemoveVolumeGroupJob.cpp jobs/ResizePartitionJob.cpp + jobs/ResizeVolumeGroupJob.cpp jobs/SetPartitionFlagsJob.cpp UI gui/ChoicePage.ui diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 9646d31cd..e82c7c64d 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -34,10 +34,13 @@ #include "jobs/CreatePartitionJob.h" #include "jobs/CreatePartitionTableJob.h" #include "jobs/CreateVolumeGroupJob.h" +#include "jobs/DeactivateVolumeGroupJob.h" #include "jobs/DeletePartitionJob.h" #include "jobs/FillGlobalStorageJob.h" #include "jobs/FormatPartitionJob.h" +#include "jobs/RemoveVolumeGroupJob.h" #include "jobs/ResizePartitionJob.h" +#include "jobs/ResizeVolumeGroupJob.h" #include "jobs/SetPartitionFlagsJob.h" #include "Typedefs.h" @@ -65,6 +68,7 @@ PartitionCoreModule::DeviceInfo::DeviceInfo( Device* _device ) : device( _device ) , partitionModel( new PartitionModel ) , immutableDevice( new Device( *_device ) ) + , isAvailable( true ) {} PartitionCoreModule::DeviceInfo::~DeviceInfo() @@ -298,6 +302,48 @@ PartitionCoreModule::createVolumeGroup( QString &vgName, refresh(); } +void +PartitionCoreModule::resizeVolumeGroup( LvmDevice *device, QVector< const Partition* >& pvList ) +{ + DeviceInfo* deviceInfo = infoForDevice( device ); + Q_ASSERT( deviceInfo ); + + ResizeVolumeGroupJob* job = new ResizeVolumeGroupJob( device, pvList ); + + deviceInfo->jobs << Calamares::job_ptr( job ); + + refresh(); +} + +void +PartitionCoreModule::deactivateVolumeGroup( LvmDevice *device ) +{ + DeviceInfo* deviceInfo = infoForDevice( device ); + Q_ASSERT( deviceInfo ); + + deviceInfo->isAvailable = false; + + DeactivateVolumeGroupJob* job = new DeactivateVolumeGroupJob( device ); + + // DeactivateVolumeGroupJob needs to be immediately called + job->exec(); + + refresh(); +} + +void +PartitionCoreModule::removeVolumeGroup( LvmDevice *device ) +{ + DeviceInfo* deviceInfo = infoForDevice( device ); + Q_ASSERT( deviceInfo ); + + RemoveVolumeGroupJob* job = new RemoveVolumeGroupJob( device ); + + deviceInfo->jobs << Calamares::job_ptr( job ); + + refresh(); +} + void PartitionCoreModule::deletePartition( Device* device, Partition* partition ) { @@ -596,16 +642,40 @@ PartitionCoreModule::scanForLVMPVs() { m_lvmPVs.clear(); - QList< Device* > devices; + QList< Device* > physicalDevices; + QList< LvmDevice* > vgDevices; for ( DeviceInfo* deviceInfo : m_deviceInfos ) - devices << deviceInfo->device.data(); + { + if ( deviceInfo->device.data()->type() == Device::Type::Disk_Device) + physicalDevices << deviceInfo->device.data(); + else if ( deviceInfo->device.data()->type() == Device::Type::LVM_Device ) + { + LvmDevice* device = dynamic_cast(deviceInfo->device.data()); - LvmDevice::scanSystemLVM( devices ); + // Restoring physical volume list + device->physicalVolumes().clear(); + + vgDevices << device; + } + } + + // Update LVM::pvList + LvmDevice::scanSystemLVM( physicalDevices ); for ( auto p : LVM::pvList ) + { m_lvmPVs << p.partition().data(); + for ( LvmDevice* device : vgDevices ) + if ( p.vgName() == device->name() ) + { + // Adding scanned VG to PV list + device->physicalVolumes() << p.partition(); + break; + } + } + for ( DeviceInfo* d : m_deviceInfos ) { for ( auto job : d->jobs ) @@ -693,21 +763,26 @@ PartitionCoreModule::revertAllDevices() for ( auto it = m_deviceInfos.begin(); it != m_deviceInfos.end(); ) { // In new VGs device info, there will be always a CreateVolumeGroupJob as the first job in jobs list - if ( dynamic_cast( ( *it )->device.data() ) && !( *it )->jobs.empty() ) + if ( dynamic_cast( ( *it )->device.data() ) ) { - CreateVolumeGroupJob* vgJob = dynamic_cast( ( *it )->jobs[0].data() ); + ( *it )->isAvailable = true; - if ( vgJob ) + if ( !( *it )->jobs.empty() ) { - vgJob->undoPreview(); + CreateVolumeGroupJob* vgJob = dynamic_cast( ( *it )->jobs[0].data() ); - ( *it )->forgetChanges(); + if ( vgJob ) + { + vgJob->undoPreview(); - m_deviceModel->removeDevice( ( *it )->device.data() ); + ( *it )->forgetChanges(); - it = m_deviceInfos.erase( it ); + m_deviceModel->removeDevice( ( *it )->device.data() ); - continue; + it = m_deviceInfos.erase( it ); + + continue; + } } } @@ -736,8 +811,13 @@ PartitionCoreModule::revertDevice( Device* dev ) m_deviceModel->swapDevice( dev, newDev ); QList< Device* > devices; - foreach ( auto info, m_deviceInfos ) - devices.append( info->device.data() ); + for ( auto info : m_deviceInfos ) + { + if ( info->device.data()->type() != Device::Type::Disk_Device ) + continue; + else + devices.append( info->device.data() ); + } m_bootLoaderModel->init( devices ); @@ -777,6 +857,16 @@ PartitionCoreModule::isDirty() return m_isDirty; } +bool +PartitionCoreModule::isVGdeactivated( LvmDevice *device ) +{ + for ( DeviceInfo* deviceInfo : m_deviceInfos ) + if ( device == deviceInfo->device.data() && !deviceInfo->isAvailable ) + return true; + + return false; +} + QList< PartitionCoreModule::SummaryInfo > PartitionCoreModule::createSummaryInfo() const { diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index cedda391d..d61311c8a 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -114,6 +114,12 @@ public: void createVolumeGroup( QString &vgName, QVector< const Partition* > pvList, qint32 peSize ); + void resizeVolumeGroup( LvmDevice* device, QVector< const Partition* >& pvList ); + + void deactivateVolumeGroup( LvmDevice* device ); + + void removeVolumeGroup( LvmDevice* device ); + void deletePartition( Device* device, Partition* partition ); void formatPartition( Device* device, Partition* partition ); @@ -160,6 +166,8 @@ public: bool isDirty(); // true if there are pending changes, otherwise false + bool isVGdeactivated( LvmDevice* device ); + /** * To be called when a partition has been altered, but only for changes * which do not affect its size, because changes which affect the partition size @@ -198,6 +206,9 @@ private: const QScopedPointer< Device > immutableDevice; QList< Calamares::job_ptr > jobs; + // To check if LVM VGs are deactivated + bool isAvailable; + void forgetChanges(); bool isDirty() const; }; diff --git a/src/modules/partition/gui/CreateVolumeGroupDialog.cpp b/src/modules/partition/gui/CreateVolumeGroupDialog.cpp index f1ed32551..fe5c40be8 100644 --- a/src/modules/partition/gui/CreateVolumeGroupDialog.cpp +++ b/src/modules/partition/gui/CreateVolumeGroupDialog.cpp @@ -28,13 +28,16 @@ CreateVolumeGroupDialog::CreateVolumeGroupDialog( QString& vgName, QVector< const Partition* >& selectedPVs, QVector< const Partition* > pvList, - qint32& peSize, + qint64& pSize, QWidget* parent ) - : VolumeGroupBaseDialog( vgName, pvList, peSize, parent ) + : VolumeGroupBaseDialog( vgName, pvList, parent ) , m_selectedPVs( selectedPVs ) + , m_peSize( pSize ) { setWindowTitle( "Create Volume Group" ); + peSize()->setValue( pSize ); + vgType()->setEnabled( false ); } @@ -46,7 +49,7 @@ CreateVolumeGroupDialog::accept() m_selectedPVs << checkedItems(); - qint32& pe = peSizeValue(); + qint64& pe = m_peSize; pe = peSize()->value(); QDialog::accept(); diff --git a/src/modules/partition/gui/CreateVolumeGroupDialog.h b/src/modules/partition/gui/CreateVolumeGroupDialog.h index eb2ced137..b0d5b874c 100644 --- a/src/modules/partition/gui/CreateVolumeGroupDialog.h +++ b/src/modules/partition/gui/CreateVolumeGroupDialog.h @@ -27,13 +27,15 @@ public: CreateVolumeGroupDialog( QString& vgName, QVector< const Partition* >& selectedPVs, QVector< const Partition* > pvList, - qint32& peSize, + qint64& pSize, QWidget* parent ); void accept() override; private: QVector< const Partition* >& m_selectedPVs; + + qint64& m_peSize; }; #endif // CREATEVOLUMEGROUPDIALOG_H diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index 550e356c0..ada6cc15b 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -30,6 +30,7 @@ #include "gui/CreatePartitionDialog.h" #include "gui/CreateVolumeGroupDialog.h" #include "gui/EditExistingPartitionDialog.h" +#include "gui/ResizeVolumeGroupDialog.h" #include "gui/ScanningDialog.h" #include "ui_PartitionPage.h" @@ -43,6 +44,8 @@ // KPMcore #include #include +#include +#include // Qt #include @@ -101,6 +104,9 @@ PartitionPage::PartitionPage( PartitionCoreModule* core, QWidget* parent ) connect( m_ui->partitionTreeView, &QAbstractItemView::doubleClicked, this, &PartitionPage::onPartitionViewActivated ); connect( m_ui->revertButton, &QAbstractButton::clicked, this, &PartitionPage::onRevertClicked ); connect( m_ui->newVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onNewVolumeGroupClicked ); + connect( m_ui->resizeVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onResizeVolumeGroupClicked ); + connect( m_ui->deactivateVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onDeactivateVolumeGroupClicked ); + connect( m_ui->removeVolumeGroupButton, &QAbstractButton::clicked, this, &PartitionPage::onRemoveVolumeGroupClicked ); connect( m_ui->newPartitionTableButton, &QAbstractButton::clicked, this, &PartitionPage::onNewPartitionTableClicked ); connect( m_ui->createButton, &QAbstractButton::clicked, this, &PartitionPage::onCreateClicked ); connect( m_ui->editButton, &QAbstractButton::clicked, this, &PartitionPage::onEditClicked ); @@ -121,7 +127,8 @@ PartitionPage::~PartitionPage() void PartitionPage::updateButtons() { - bool create = false, createTable = false, edit = false, del = false; + bool create = false, createTable = false, edit = false, del = false, currentDeviceIsVG = false, isDeactivable = false; + bool isRemovable = false, isVGdeactivated = false; QModelIndex index = m_ui->partitionTreeView->currentIndex(); if ( index.isValid() ) @@ -152,12 +159,28 @@ PartitionPage::updateButtons() QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); if ( m_core->deviceModel()->deviceForIndex( deviceIndex )->type() != Device::Type::LVM_Device ) createTable = true; + else + { + currentDeviceIsVG = true; + + LvmDevice* lvmDevice = dynamic_cast(m_core->deviceModel()->deviceForIndex( deviceIndex )); + + isDeactivable = DeactivateVolumeGroupOperation::isDeactivatable( lvmDevice ); + isRemovable = RemoveVolumeGroupOperation::isRemovable( lvmDevice ); + + isVGdeactivated = m_core->isVGdeactivated( lvmDevice ); + + m_ui->revertButton->setEnabled( isVGdeactivated ); + } } m_ui->createButton->setEnabled( create ); m_ui->editButton->setEnabled( edit ); m_ui->deleteButton->setEnabled( del ); m_ui->newPartitionTableButton->setEnabled( createTable ); + m_ui->resizeVolumeGroupButton->setEnabled( currentDeviceIsVG && !isVGdeactivated ); + m_ui->deactivateVolumeGroupButton->setEnabled( currentDeviceIsVG && isDeactivable && !isVGdeactivated ); + m_ui->removeVolumeGroupButton->setEnabled( currentDeviceIsVG && isRemovable ); } void @@ -188,7 +211,7 @@ PartitionPage::onNewVolumeGroupClicked() { QString vgName; QVector< const Partition* > selectedPVs; - qint32 peSize = 4; + qint64 peSize = 4; QVector< const Partition* > availablePVs; @@ -238,6 +261,59 @@ PartitionPage::onNewVolumeGroupClicked() delete dlg; } +void +PartitionPage::onResizeVolumeGroupClicked() +{ + QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); + LvmDevice* device = dynamic_cast< LvmDevice* >( m_core->deviceModel()->deviceForIndex( deviceIndex ) ); + + Q_ASSERT( device && device->type() == Device::Type::LVM_Device ); + + QVector< const Partition* > availablePVs; + QVector< const Partition* > selectedPVs; + + for ( const Partition* p : m_core->lvmPVs() ) + if ( !m_core->isInVG( p ) ) + availablePVs << p; + + QPointer< ResizeVolumeGroupDialog > dlg = new ResizeVolumeGroupDialog( device, + availablePVs, + selectedPVs, + this ); + + if ( dlg->exec() == QDialog::Accepted ) + m_core->resizeVolumeGroup( device, selectedPVs ); + + delete dlg; +} + +void +PartitionPage::onDeactivateVolumeGroupClicked() +{ + QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); + LvmDevice* device = dynamic_cast< LvmDevice* >( m_core->deviceModel()->deviceForIndex( deviceIndex ) ); + + Q_ASSERT( device && device->type() == Device::Type::LVM_Device ); + + m_core->deactivateVolumeGroup( device ); + + updateFromCurrentDevice(); + + PartitionModel* model = m_core->partitionModelForDevice( device ); + model->update(); +} + +void +PartitionPage::onRemoveVolumeGroupClicked() +{ + QModelIndex deviceIndex = m_core->deviceModel()->index( m_ui->deviceComboBox->currentIndex(), 0 ); + LvmDevice* device = dynamic_cast< LvmDevice* >( m_core->deviceModel()->deviceForIndex( deviceIndex ) ); + + Q_ASSERT( device && device->type() == Device::Type::LVM_Device ); + + m_core->removeVolumeGroup( device ); +} + void PartitionPage::onCreateClicked() { diff --git a/src/modules/partition/gui/PartitionPage.h b/src/modules/partition/gui/PartitionPage.h index ef6eeea15..f4ce330dd 100644 --- a/src/modules/partition/gui/PartitionPage.h +++ b/src/modules/partition/gui/PartitionPage.h @@ -51,6 +51,9 @@ private: void updateButtons(); void onNewPartitionTableClicked(); void onNewVolumeGroupClicked(); + void onResizeVolumeGroupClicked(); + void onDeactivateVolumeGroupClicked(); + void onRemoveVolumeGroupClicked(); void onCreateClicked(); void onEditClicked(); void onDeleteClicked(); diff --git a/src/modules/partition/gui/PartitionPage.ui b/src/modules/partition/gui/PartitionPage.ui index 2b3d568cf..612bff7ba 100644 --- a/src/modules/partition/gui/PartitionPage.ui +++ b/src/modules/partition/gui/PartitionPage.ui @@ -6,7 +6,7 @@ 0 0 - 655 + 684 304 @@ -88,13 +88,6 @@ - - - - New Volume Group - - - @@ -131,6 +124,51 @@ + + + + + + New Volume Group + + + + + + + Resize Volume Group + + + + + + + Deactivate Volume Group + + + + + + + Remove Volume Group + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + diff --git a/src/modules/partition/gui/ResizeVolumeGroupDialog.cpp b/src/modules/partition/gui/ResizeVolumeGroupDialog.cpp new file mode 100644 index 000000000..b3173096d --- /dev/null +++ b/src/modules/partition/gui/ResizeVolumeGroupDialog.cpp @@ -0,0 +1,62 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "ResizeVolumeGroupDialog.h" + +#include "gui/ListPhysicalVolumeWidgetItem.h" + +#include +#include + +#include +#include +#include +#include + +ResizeVolumeGroupDialog::ResizeVolumeGroupDialog( LvmDevice *device, + QVector< const Partition* > availablePVs, + QVector< const Partition* >& selectedPVs, + QWidget* parent ) + : VolumeGroupBaseDialog( device->name(), device->physicalVolumes(), parent ) + , m_selectedPVs( selectedPVs ) +{ + setWindowTitle( "Resize Volume Group" ); + + for ( int i = 0; i < pvList()->count(); i++ ) + pvList()->item(i)->setCheckState( Qt::Checked ); + + for ( const Partition* p : availablePVs ) + pvList()->addItem( new ListPhysicalVolumeWidgetItem( p, false ) ); + + peSize()->setValue( device->peSize() / Capacity::unitFactor(Capacity::Unit::Byte, Capacity::Unit::MiB) ); + + vgName()->setEnabled( false ); + peSize()->setEnabled( false ); + vgType()->setEnabled( false ); + + setUsedSizeValue( device->allocatedPE() * device->peSize() ); + setLVQuantity( device->partitionTable()->children().count() ); +} + +void +ResizeVolumeGroupDialog::accept() +{ + m_selectedPVs << checkedItems(); + + QDialog::accept(); +} diff --git a/src/modules/partition/gui/ResizeVolumeGroupDialog.h b/src/modules/partition/gui/ResizeVolumeGroupDialog.h new file mode 100644 index 000000000..1d6015329 --- /dev/null +++ b/src/modules/partition/gui/ResizeVolumeGroupDialog.h @@ -0,0 +1,40 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef RESIZEVOLUMEGROUPDIALOG_H +#define RESIZEVOLUMEGROUPDIALOG_H + +#include "gui/VolumeGroupBaseDialog.h" + +class LvmDevice; + +class ResizeVolumeGroupDialog : public VolumeGroupBaseDialog +{ +public: + ResizeVolumeGroupDialog( LvmDevice *device, + QVector< const Partition* > availablePVs, + QVector< const Partition* >& selectedPVs, + QWidget* parent ); + + void accept() override; + +private: + QVector< const Partition* >& m_selectedPVs; +}; + +#endif // RESIZEVOLUMEGROUPDIALOG_H diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp index e5da2c0ad..a727fe42a 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp @@ -32,12 +32,10 @@ VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, QVector< const Partition* > pvList, - qint32& peSize, QWidget *parent ) : QDialog(parent) , ui(new Ui::VolumeGroupBaseDialog) , m_vgNameValue(vgName) - , m_peSizeValue(peSize) , m_totalSizeValue(0) , m_usedSizeValue(0) { @@ -53,8 +51,6 @@ VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, ui->vgName->setValidator( new QRegularExpressionValidator( re, this ) ); ui->vgName->setText( m_vgNameValue ); - ui->peSize->setValue( m_peSizeValue ); - updateOkButton(); updateTotalSize(); @@ -111,6 +107,20 @@ VolumeGroupBaseDialog::updateOkButton() ui->peSize->value() > 0); } +void +VolumeGroupBaseDialog::setUsedSizeValue( qint64 usedSize ) +{ + m_usedSizeValue = usedSize; + + ui->usedSize->setText( Capacity::formatByteSize(m_usedSizeValue) ); +} + +void +VolumeGroupBaseDialog::setLVQuantity( qint32 lvQuantity ) +{ + ui->lvQuantity->setText( QString::number( lvQuantity ) ); +} + void VolumeGroupBaseDialog::updateTotalSize() { @@ -143,12 +153,6 @@ VolumeGroupBaseDialog::vgNameValue() const return m_vgNameValue; } -qint32& -VolumeGroupBaseDialog::peSizeValue() const -{ - return m_peSizeValue; -} - QLineEdit* VolumeGroupBaseDialog::vgName() const { diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.h b/src/modules/partition/gui/VolumeGroupBaseDialog.h index 0b4a48372..e6011ce62 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.h +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.h @@ -39,13 +39,16 @@ class VolumeGroupBaseDialog : public QDialog public: explicit VolumeGroupBaseDialog( QString& vgName, QVector< const Partition* > pvList, - qint32& peSize, QWidget* parent = nullptr ); ~VolumeGroupBaseDialog(); protected: virtual void updateOkButton(); + void setUsedSizeValue( qint64 usedSize ); + + void setLVQuantity( qint32 lvQuantity ); + void updateTotalSize(); void updateTotalSectors(); @@ -56,8 +59,6 @@ protected: QString& vgNameValue() const; - qint32& peSizeValue() const; - QLineEdit* vgName() const; QComboBox* vgType() const; @@ -72,7 +73,6 @@ private: Ui::VolumeGroupBaseDialog* ui; QString& m_vgNameValue; - qint32& m_peSizeValue; qint64 m_totalSizeValue; qint64 m_usedSizeValue; diff --git a/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp b/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp new file mode 100644 index 000000000..f772b3e5a --- /dev/null +++ b/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp @@ -0,0 +1,69 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "DeactivateVolumeGroupJob.h" + +#include +#include +#include + +DeactivateVolumeGroupJob::DeactivateVolumeGroupJob( LvmDevice* device ) + : m_device( device ) +{ + +} + +QString +DeactivateVolumeGroupJob::prettyName() const +{ + return tr( "Deactivate volume group named %1." ) + .arg( m_device->name() ); +} + +QString +DeactivateVolumeGroupJob::prettyDescription() const +{ + return tr( "Deactivate volume group named %1." ) + .arg( m_device->name() ); +} + +QString +DeactivateVolumeGroupJob::prettyStatusMessage() const +{ + return tr( "Deactivate volume group named %1." ) + .arg( m_device->name() ); +} + +Calamares::JobResult +DeactivateVolumeGroupJob::exec() +{ + Report report( nullptr ); + + DeactivateVolumeGroupOperation op( *m_device ); + + op.setStatus( Operation::OperationStatus::StatusRunning ); + + QString message = tr( "The installer failed to deactivate a volume group named %1." ).arg( m_device->name() ); + if ( op.execute( report ) ) + { + op.preview(); + return Calamares::JobResult::ok(); + } + + return Calamares::JobResult::error(message, report.toText()); +} diff --git a/src/modules/partition/jobs/DeactivateVolumeGroupJob.h b/src/modules/partition/jobs/DeactivateVolumeGroupJob.h new file mode 100644 index 000000000..5b59c2c4f --- /dev/null +++ b/src/modules/partition/jobs/DeactivateVolumeGroupJob.h @@ -0,0 +1,40 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef DEACTIVATEVOLUMEGROUPJOB_H +#define DEACTIVATEVOLUMEGROUPJOB_H + +#include "Job.h" + +class LvmDevice; + +class DeactivateVolumeGroupJob : public Calamares::Job +{ +public: + DeactivateVolumeGroupJob( LvmDevice* device ); + + QString prettyName() const override; + QString prettyDescription() const override; + QString prettyStatusMessage() const override; + Calamares::JobResult exec() override; + +private: + LvmDevice* m_device; +}; + +#endif // DEACTIVATEVOLUMEGROUPJOB_H diff --git a/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp b/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp new file mode 100644 index 000000000..69b510754 --- /dev/null +++ b/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp @@ -0,0 +1,66 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "RemoveVolumeGroupJob.h" + +#include +#include +#include + +RemoveVolumeGroupJob::RemoveVolumeGroupJob( LvmDevice* device ) + : m_device( device ) +{ + +} + +QString +RemoveVolumeGroupJob::prettyName() const +{ + return tr( "Remove Volume Group named %1." ) + .arg( m_device->name() ); +} + +QString +RemoveVolumeGroupJob::prettyDescription() const +{ + return tr( "Remove Volume Group named %1.") + .arg( m_device->name() ); +} + +QString +RemoveVolumeGroupJob::prettyStatusMessage() const +{ + return tr( "Remove Volume Group named %1." ) + .arg( m_device->name() ); +} + +Calamares::JobResult +RemoveVolumeGroupJob::exec() +{ + Report report( nullptr ); + + RemoveVolumeGroupOperation op( *m_device ); + + op.setStatus( Operation::OperationStatus::StatusRunning ); + + QString message = tr( "The installer failed to remove a volume group named '%1'." ).arg( m_device->name() ); + if ( op.execute( report ) ) + return Calamares::JobResult::ok(); + + return Calamares::JobResult::error(message, report.toText()); +} diff --git a/src/modules/partition/jobs/RemoveVolumeGroupJob.h b/src/modules/partition/jobs/RemoveVolumeGroupJob.h new file mode 100644 index 000000000..426dde7fb --- /dev/null +++ b/src/modules/partition/jobs/RemoveVolumeGroupJob.h @@ -0,0 +1,40 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef REMOVEVOLUMEGROUPJOB_H +#define REMOVEVOLUMEGROUPJOB_H + +#include + +class LvmDevice; + +class RemoveVolumeGroupJob : public Calamares::Job +{ +public: + RemoveVolumeGroupJob( LvmDevice* device ); + + QString prettyName() const override; + QString prettyDescription() const override; + QString prettyStatusMessage() const override; + Calamares::JobResult exec() override; + +private: + LvmDevice* m_device; +}; + +#endif // REMOVEVOLUMEGROUPJOB_H diff --git a/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp b/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp new file mode 100644 index 000000000..bc7ef264d --- /dev/null +++ b/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp @@ -0,0 +1,101 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#include "ResizeVolumeGroupJob.h" + +// KPMcore +#include +#include +#include +#include + +ResizeVolumeGroupJob::ResizeVolumeGroupJob( LvmDevice* device, QVector< const Partition* >& partitionList ) + : m_device( device ) + , m_partitionList( partitionList ) +{ + +} + +QString +ResizeVolumeGroupJob::prettyName() const +{ + return tr( "Resize volume group named %1 from %2 to %3." ) + .arg( m_device->name() ) + .arg( currentPartitions() ) + .arg( targetPartitions() ); +} + +QString +ResizeVolumeGroupJob::prettyDescription() const +{ + return tr( "Resize volume group named %1 from %2 to %3." ) + .arg( m_device->name() ) + .arg( currentPartitions() ) + .arg( targetPartitions() ); +} + +QString +ResizeVolumeGroupJob::prettyStatusMessage() const +{ + return tr( "Resize volume group named %1 from %2 to %3." ) + .arg( m_device->name() ) + .arg( currentPartitions() ) + .arg( targetPartitions() ); +} + +Calamares::JobResult +ResizeVolumeGroupJob::exec() +{ + Report report( nullptr ); + + ResizeVolumeGroupOperation op( *m_device, m_partitionList ); + + op.setStatus( Operation::OperationStatus::StatusRunning ); + + QString message = tr( "The installer failed to resize a volume group named '%1'." ).arg( m_device->name() ); + if ( op.execute( report ) ) + return Calamares::JobResult::ok(); + + return Calamares::JobResult::error( message, report.toText() ); +} + +QString +ResizeVolumeGroupJob::currentPartitions() const +{ + QString result; + + for ( const Partition *p : m_device->physicalVolumes() ) + result += p->deviceNode() + ", "; + + result.chop(2); + + return result; +} + +QString +ResizeVolumeGroupJob::targetPartitions() const +{ + QString result; + + for ( const Partition *p : m_partitionList ) + result += p->deviceNode() + ", "; + + result.chop(2); + + return result; +} diff --git a/src/modules/partition/jobs/ResizeVolumeGroupJob.h b/src/modules/partition/jobs/ResizeVolumeGroupJob.h new file mode 100644 index 000000000..380bee416 --- /dev/null +++ b/src/modules/partition/jobs/ResizeVolumeGroupJob.h @@ -0,0 +1,48 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, Caio Jordão Carvalho + * + * 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 . + */ + +#ifndef RESIZEVOLUMEGROUPJOB_H +#define RESIZEVOLUMEGROUPJOB_H + +#include + +#include + +class LvmDevice; +class Partition; + +class ResizeVolumeGroupJob : public Calamares::Job +{ +public: + ResizeVolumeGroupJob( LvmDevice* device, QVector< const Partition* >& partitionList ); + + QString prettyName() const override; + QString prettyDescription() const override; + QString prettyStatusMessage() const override; + Calamares::JobResult exec() override; + +private: + QString currentPartitions() const; + QString targetPartitions() const; + +private: + LvmDevice* m_device; + QVector< const Partition* > m_partitionList; +}; + +#endif // RESIZEVOLUMEGROUPJOB_H From 67d9ebbfc0b4195b0576f04f285a7d2585d6700f Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Tue, 26 Jun 2018 01:29:57 -0300 Subject: [PATCH 013/112] [partition] Setting revertButton enabled after deactivating VG. --- src/modules/partition/gui/PartitionPage.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index ada6cc15b..37d90f65d 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -170,7 +170,8 @@ PartitionPage::updateButtons() isVGdeactivated = m_core->isVGdeactivated( lvmDevice ); - m_ui->revertButton->setEnabled( isVGdeactivated ); + if ( isVGdeactivated ) + m_ui->revertButton->setEnabled( true ); } } From 589628bb9af32fcd5315fa91d544cef812e9e0f0 Mon Sep 17 00:00:00 2001 From: Caio Carvalho Date: Tue, 26 Jun 2018 01:44:35 -0300 Subject: [PATCH 014/112] [partition] Removing unnecessary horizontal spacer on Partition Page. --- src/modules/partition/gui/PartitionPage.ui | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/modules/partition/gui/PartitionPage.ui b/src/modules/partition/gui/PartitionPage.ui index 612bff7ba..e72f08518 100644 --- a/src/modules/partition/gui/PartitionPage.ui +++ b/src/modules/partition/gui/PartitionPage.ui @@ -154,19 +154,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - From a6688504e801e1eecc2a3e68bcb51e3f8ff7ad1e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 04:17:03 -0400 Subject: [PATCH 015/112] CMake: switch INSTALL_CONFIG to OFF by default - The examples files are not harmless, so distro's should take a explicit decision to install the config examples (instead of putting files in /etc/calamares). --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eed360f8..d72463bbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ cmake_minimum_required( VERSION 3.2 ) ### OPTIONS # -option( INSTALL_CONFIG "Install configuration files" ON ) +option( INSTALL_CONFIG "Install configuration files" OFF ) option( INSTALL_POLKIT "Install Polkit configuration" ON ) option( BUILD_TESTING "Build the testing tree." ON ) option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON ) From 29830bc1e12c0a4481fd7b7e58701a73d03768ec Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 04:35:00 -0400 Subject: [PATCH 016/112] [services] Document the configuration file. - Change the example to be harmless (empty) - Document the structure of the entries --- src/modules/services/services.conf | 57 +++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/modules/services/services.conf b/src/modules/services/services.conf index d9c8895ea..eb971b222 100644 --- a/src/modules/services/services.conf +++ b/src/modules/services/services.conf @@ -1,20 +1,45 @@ +# Systemd services manipulation. +# +# This module can enable services and targets for systemd +# (if packaging doesn't already do that). It can calso +# disable services (but not targets). +# +# First, services are enabled; then targets; then services +# are disabled -- this order of operations is fixed. --- -#systemd services and targets are enabled in this precise order -services: - - name: "NetworkManager" #name of the service file - mandatory: false #true=> if enabling fails the installer errors out and quits - #false=>if enabling fails print warning to console and continue - - name: "cups" - mandatory: false +# There are three configuration keys for this module: +# *services*, *targets* and *disable*. The value of each +# key is a list of entries. Each entry has two keys: +# - *name* is the (string) name of the service or target that is being +# changed. Use quotes. +# - *mandatory* is a boolean option, which states whether the change +# must be done successfully. If systemd reports an error while changing +# a mandatory entry, the installation will fail. When mandatory is false, +# errors for that entry (service or target) are ignored. +# +# Use [] to express an empty list. -targets: - - name: "graphical" - mandatory: true +# # This example enables NetworkManager (and fails if it can't), +# # disables cups (and ignores failure). Then it enables the +# # graphical target (e.g. so that SDDM runs for login), and +# # finally disables pacman-init (an ArchLinux-only service). +# # +# services: +# - name: "NetworkManager" +# mandatory: true +# - name: "cups" +# mandatory: false +# +# targets: +# - name: "graphical" +# mandatory: true +# +# disable: +# - name: "pacman-init" +# mandatory: false -disable: - - name: "pacman-init" - mandatory: false - -# Example to express an empty list: -# disable: [] +# By default, no changes are made. +services: [] +targets: [] +disable: [] From b2c2b916456972b5ce5e0ac140c3a568b7c48a8a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 05:18:10 -0400 Subject: [PATCH 017/112] CMake: introduce USE_ When there are multiple modules doing a thing and it really only makes sense to have one of them in a given Calamares compilation, the USE_ variables allow you to select one, while ignoring all the other implementations. If USE_ is not set, all implementations are included (as usual). --- CMakeLists.txt | 16 ++++++++++++++++ src/modules/CMakeLists.txt | 20 +++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d72463bbd..1fa59421c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,22 @@ option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON ) option( WITH_PYTHONQT "Enable next generation Python modules API (experimental, requires PythonQt)." ON ) option( WITH_KF5Crash "Enable crash reporting with KCrash." ON ) +### USE_* +# +# By convention, when there are multiple modules that implement similar +# functionality, and it only makes sense to have **at most one** of them +# enabled at any time, those modules are named -. +# For example, services-systemd and services-openrc. +# +# Setting up SKIP_MODULES to ignore "the ones you don't want" can be +# annoying and error-prone (e.g. if a new module shows up). The USE_* +# modules provide a way to do automatic selection. To pick exactly +# one of the implementations from group , set USE_ to the +# name of the implementation. If USE_ is unset, or empty, then +# all the implementations are enabled (this just means they are +# **available** to `settings.conf`, not that they are used). +# +# Currently, no USE_ variables exist. ### Calamares application info # diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 514d6b4f6..bf1817b52 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -15,13 +15,31 @@ string( REPLACE " " ";" SKIP_LIST "${SKIP_MODULES}" ) file( GLOB SUBDIRECTORIES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*" ) list( SORT SUBDIRECTORIES ) +# Handle the USE_ variables by looking for subdirectories +# with a - kind of name. +foreach( SUBDIRECTORY ${SUBDIRECTORIES} ) +endforeach() + foreach( SUBDIRECTORY ${SUBDIRECTORIES} ) list( FIND SKIP_LIST ${SUBDIRECTORY} DO_SKIP ) + set( _skip_reason "user request" ) + if( SUBDIRECTORY MATCHES "^[a-zA-Z0-9_]+-" ) + string( REGEX REPLACE "^[^-]+-" "" _implementation ${SUBDIRECTORY} ) + string( REGEX REPLACE "-.*" "" _category ${SUBDIRECTORY} ) + if( USE_${_category} ) + if( NOT "${_implementation}" STREQUAL "${USE_${_category}}" ) + list( APPEND SKIP_LIST ${SUBDIRECTORY} ) + set( _skip_reason "USE_${_category}=${USE_${_category}}" ) + set( DO_SKIP 1 ) + endif() + endif() + endif() + if( NOT DO_SKIP EQUAL -1 ) message( "${ColorReset}-- Skipping module ${BoldRed}${SUBDIRECTORY}${ColorReset}." ) message( "" ) - list( APPEND LIST_SKIPPED_MODULES "${SUBDIRECTORY} (user request)" ) + list( APPEND LIST_SKIPPED_MODULES "${SUBDIRECTORY} (${_skip_reason})" ) elseif( ( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}" ) AND ( DO_SKIP EQUAL -1 ) ) set( SKIPPED_MODULES ) From c086d18a26a5f2d62f9dc1fb2ef646b47585b622 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 05:33:01 -0400 Subject: [PATCH 018/112] CMake: improve error-handling for USE_* If USE_ is given a value that doesn't match **anything**, then bail out. Since USE_* is an explicit distro choice for a specific implementation, it's an error if that implementation is not there. --- src/modules/CMakeLists.txt | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index bf1817b52..0a8d1db70 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -15,20 +15,23 @@ string( REPLACE " " ";" SKIP_LIST "${SKIP_MODULES}" ) file( GLOB SUBDIRECTORIES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*" ) list( SORT SUBDIRECTORIES ) -# Handle the USE_ variables by looking for subdirectories -# with a - kind of name. -foreach( SUBDIRECTORY ${SUBDIRECTORIES} ) -endforeach() +set( _use_categories "" ) +set( _found_categories "" ) foreach( SUBDIRECTORY ${SUBDIRECTORIES} ) list( FIND SKIP_LIST ${SUBDIRECTORY} DO_SKIP ) set( _skip_reason "user request" ) + # Handle the USE_ variables by looking for subdirectories + # with a - kind of name. if( SUBDIRECTORY MATCHES "^[a-zA-Z0-9_]+-" ) string( REGEX REPLACE "^[^-]+-" "" _implementation ${SUBDIRECTORY} ) string( REGEX REPLACE "-.*" "" _category ${SUBDIRECTORY} ) if( USE_${_category} ) - if( NOT "${_implementation}" STREQUAL "${USE_${_category}}" ) + list( APPEND _use_categories ${_category} ) + if( "${_implementation}" STREQUAL "${USE_${_category}}" ) + list( APPEND _found_categories ${_category} ) + else() list( APPEND SKIP_LIST ${SUBDIRECTORY} ) set( _skip_reason "USE_${_category}=${USE_${_category}}" ) set( DO_SKIP 1 ) @@ -54,5 +57,12 @@ endforeach() # both before and after the feature summary. calamares_explain_skipped_modules( ${LIST_SKIPPED_MODULES} ) +foreach( _category ${_use_categories} ) + list( FIND _found_categories ${_category} _found ) + if ( _found EQUAL -1 ) + message( FATAL_ERROR "USE_${_category} is set to ${USE_${_category}} and no module matches." ) + endif() +endforeach() + include( CalamaresAddTranslations ) add_calamares_python_translations( ${CALAMARES_TRANSLATION_LANGUAGES} ) From 52f09f7f462c36d559b1bd536bc1f140f0620365 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 05:47:23 -0400 Subject: [PATCH 019/112] [modules] Minor documentation work on modules a-g --- src/modules/bootloader/bootloader.conf | 2 ++ src/modules/displaymanager/displaymanager.conf | 2 ++ src/modules/dummycpp/dummycpp.conf | 5 ++++- src/modules/dummypython/dummypython.conf | 5 ++++- src/modules/dummypythonqt/dummypythonqt.conf | 3 +++ src/modules/grubcfg/grubcfg.conf | 1 + 6 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/modules/bootloader/bootloader.conf b/src/modules/bootloader/bootloader.conf index ee8680f72..808a5e6d0 100644 --- a/src/modules/bootloader/bootloader.conf +++ b/src/modules/bootloader/bootloader.conf @@ -12,8 +12,10 @@ kernel: "/vmlinuz-linux" img: "/initramfs-linux.img" fallback: "/initramfs-linux-fallback.img" timeout: "10" + # Optionally set the menu entry name and kernel name to use in systemd-boot. # If not specified here, these settings will be taken from branding.desc. +# # bootloaderEntryName: "Generic GNU/Linux" # kernelLine: ", with Stable-Kernel" # fallbackKernelLine: ", with Stable-Kernel (fallback initramfs)" diff --git a/src/modules/displaymanager/displaymanager.conf b/src/modules/displaymanager/displaymanager.conf index 1c30ed637..8f8e9c704 100644 --- a/src/modules/displaymanager/displaymanager.conf +++ b/src/modules/displaymanager/displaymanager.conf @@ -1,3 +1,5 @@ +# Configure one or more display managers (e.g. SDDM) +# with a "best effort" approach. --- #The DM module attempts to set up all the DMs found in this list, in that precise order. #It also sets up autologin, if the feature is enabled in globalstorage. diff --git a/src/modules/dummycpp/dummycpp.conf b/src/modules/dummycpp/dummycpp.conf index c90b6f3b9..1f2e1daee 100644 --- a/src/modules/dummycpp/dummycpp.conf +++ b/src/modules/dummycpp/dummycpp.conf @@ -1,3 +1,6 @@ +# This is a dummy (example) module for C++ Jobs. +# +# The code is the documentation for the configuration file. --- syntax: "YAML map of anything" example: @@ -15,4 +18,4 @@ a_list_of_maps: - "another element" - name: "another item" contents: - - "not much" \ No newline at end of file + - "not much" diff --git a/src/modules/dummypython/dummypython.conf b/src/modules/dummypython/dummypython.conf index fc985089a..c700120e7 100644 --- a/src/modules/dummypython/dummypython.conf +++ b/src/modules/dummypython/dummypython.conf @@ -1,3 +1,6 @@ +# This is a dummy (example) module for a Python Job Module. +# +# The code is the documentation for the configuration file. --- syntax: "YAML map of anything" example: @@ -15,4 +18,4 @@ a_list_of_maps: - "another element" - name: "another item" contents: - - "not much" \ No newline at end of file + - "not much" diff --git a/src/modules/dummypythonqt/dummypythonqt.conf b/src/modules/dummypythonqt/dummypythonqt.conf index f60e778e1..5bc64abfa 100644 --- a/src/modules/dummypythonqt/dummypythonqt.conf +++ b/src/modules/dummypythonqt/dummypythonqt.conf @@ -1,3 +1,6 @@ +# This is a dummy (example) module for PythonQt. +# +# The code is the documentation for the configuration file. --- syntax: "YAML map of anything" example: diff --git a/src/modules/grubcfg/grubcfg.conf b/src/modules/grubcfg/grubcfg.conf index 608c9b2b4..18951a8a6 100644 --- a/src/modules/grubcfg/grubcfg.conf +++ b/src/modules/grubcfg/grubcfg.conf @@ -2,6 +2,7 @@ # If set to true, always creates /etc/default/grub from scratch even if the file # already existed. If set to false, edits the existing file instead. overwrite: false + # Default entries to write to /etc/default/grub if it does not exist yet or if # we are overwriting it. Note that in addition, GRUB_CMDLINE_LINUX_DEFAULT and # GRUB_DISTRIBUTOR will always be written, with automatically detected values. From 63c03068c0cda4f71b8bd0bf2a8c1b870eaa3008 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 06:39:30 -0400 Subject: [PATCH 020/112] [modules] Documentation for fstab, grubcfg, mkinitcpio - These modules were entirely documented as "use the source", - The sources aren't terribly clear either. --- src/modules/fstab/fstab.conf | 15 +++++++++++++++ src/modules/grubcfg/grubcfg.conf | 15 +++++++++++++-- src/modules/initcpio/initcpio.conf | 1 + 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/modules/fstab/fstab.conf b/src/modules/fstab/fstab.conf index c3dbfc309..11adff2ed 100644 --- a/src/modules/fstab/fstab.conf +++ b/src/modules/fstab/fstab.conf @@ -1,13 +1,28 @@ +# Creates /etc/fstab and /etc/crypttab in the target system. +# Also creates mount points for all the filesystems. +# +# When creating fstab entries for a filesystem, this module +# uses the options for the filesystem type to write to the +# options field of the file. --- +# Mount options to use for all filesystems. If a specific filesystem +# is listed here, use those options, otherwise use the *default* +# options from this mapping. mountOptions: default: defaults,noatime btrfs: defaults,noatime,space_cache,autodefrag + +# If a filesystem is on an SSD, add the following options. If a specific +# filesystem is listed here, use those options, otherwise no additional +# options are set (i.e. there is no *default* like in *mountOptions*). ssdExtraMountOptions: ext4: discard jfs: discard xfs: discard swap: discard btrfs: discard,compress=lzo + +# Additional options added to each line in /etc/crypttab crypttabOptions: luks # For Debian and Debian-based distributions, change the above line to: # crypttabOptions: luks,keyscript=/bin/cat diff --git a/src/modules/grubcfg/grubcfg.conf b/src/modules/grubcfg/grubcfg.conf index 18951a8a6..b354ec35a 100644 --- a/src/modules/grubcfg/grubcfg.conf +++ b/src/modules/grubcfg/grubcfg.conf @@ -1,11 +1,22 @@ +# Write lines to /etc/default/grub (in the target system) based +# on calculated values and the values set in the *defaults* key +# in this configuration file. +# +# Calculated values are: +# - GRUB_DISTRIBUTOR, branding module, *bootloaderEntryName* +# - GRUB_ENABLE_CRYPTODISK, based on the presence of filesystems +# that use LUKS +# - GRUB_CMDLINE_LINUX_DEFAULT, adding LUKS setup and plymouth +# support to the kernel. + --- # If set to true, always creates /etc/default/grub from scratch even if the file # already existed. If set to false, edits the existing file instead. overwrite: false # Default entries to write to /etc/default/grub if it does not exist yet or if -# we are overwriting it. Note that in addition, GRUB_CMDLINE_LINUX_DEFAULT and -# GRUB_DISTRIBUTOR will always be written, with automatically detected values. +# we are overwriting it. +# defaults: GRUB_TIMEOUT: 5 GRUB_DEFAULT: "saved" diff --git a/src/modules/initcpio/initcpio.conf b/src/modules/initcpio/initcpio.conf index 21f5704cc..466a8785d 100644 --- a/src/modules/initcpio/initcpio.conf +++ b/src/modules/initcpio/initcpio.conf @@ -1,2 +1,3 @@ +# Run mkinitcpio(8) with the given preset value --- kernel: linux312 From 1eede6f79719377bac7004bdebed5ef54abc5232 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 06:50:16 -0400 Subject: [PATCH 021/112] [modules] Configuration documentation for mount and luksopenswaphookcfg --- .../luksopenswaphookcfg/luksopenswaphookcfg.conf | 2 ++ src/modules/mount/mount.conf | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/modules/luksopenswaphookcfg/luksopenswaphookcfg.conf b/src/modules/luksopenswaphookcfg/luksopenswaphookcfg.conf index 886867f8d..f5610cd7c 100644 --- a/src/modules/luksopenswaphookcfg/luksopenswaphookcfg.conf +++ b/src/modules/luksopenswaphookcfg/luksopenswaphookcfg.conf @@ -1,2 +1,4 @@ +# Writes an openswap configuration with LUKS settings to the given path --- +# Path of the configuration file to write (in the target system) configFilePath: /etc/openswap.conf diff --git a/src/modules/mount/mount.conf b/src/modules/mount/mount.conf index d8f8fb8cc..bb28eed66 100644 --- a/src/modules/mount/mount.conf +++ b/src/modules/mount/mount.conf @@ -1,4 +1,18 @@ +# Mount filesystems in the target (generally, before treating the +# target as a usable chroot / "live" system). Filesystems are +# automatically mounted from the partitioning module. Filesystems +# listed here are **extra**. The filesystems listed in *extraMounts* +# are mounted in all target systems. The filesystems listed in +# *extraMountsEfi* are mounted in the target system **only** if +# the host machine uses UEFI. --- +# Extra filesystems to mount. The key's value is a list of entries; each +# entry has four keys: +# - device The device node to mount +# - fs The filesystem type to use +# - mountPoint Where to mount the filesystem +# - options (optional) Extra options to pass to mount(8) +# extraMounts: - device: proc fs: proc From 40252f1000eb2453dc6661e4bc300bf0e462170f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 06:52:37 -0400 Subject: [PATCH 022/112] [removeuser] Minor documentation --- src/modules/removeuser/removeuser.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/removeuser/removeuser.conf b/src/modules/removeuser/removeuser.conf index a59961ec5..dab4b2526 100644 --- a/src/modules/removeuser/removeuser.conf +++ b/src/modules/removeuser/removeuser.conf @@ -1,2 +1,6 @@ +# Removes a single user (with userdel) from the system. +# This is typically used in OEM setups or if the live user +# spills into the target system. --- +# Username in the target system to be removed. username: live From 731594fb40456b1676725659e13213760bc180a2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 08:07:36 -0400 Subject: [PATCH 023/112] [libcalamaresui] Remove the requiredModules setting - The value set in module.desc was never stored for use, but isn't an attribute of the instance, either. It belongs with the descriptor, in ModuleManager. --- src/libcalamaresui/modulesystem/Module.cpp | 8 -------- src/libcalamaresui/modulesystem/Module.h | 8 -------- 2 files changed, 16 deletions(-) diff --git a/src/libcalamaresui/modulesystem/Module.cpp b/src/libcalamaresui/modulesystem/Module.cpp index c820b98b3..ed1cb33ea 100644 --- a/src/libcalamaresui/modulesystem/Module.cpp +++ b/src/libcalamaresui/modulesystem/Module.cpp @@ -224,13 +224,6 @@ Module::instanceKey() const } -QStringList -Module::requiredModules() const -{ - return m_requiredModules; -} - - QString Module::location() const { @@ -286,7 +279,6 @@ void Module::initFrom( const QVariantMap& moduleDescriptor ) { m_name = moduleDescriptor.value( "name" ).toString(); - if ( moduleDescriptor.contains( EMERGENCY ) ) m_maybe_emergency = moduleDescriptor[ EMERGENCY ].toBool(); } diff --git a/src/libcalamaresui/modulesystem/Module.h b/src/libcalamaresui/modulesystem/Module.h index 18c2e4cbe..f89c9eedb 100644 --- a/src/libcalamaresui/modulesystem/Module.h +++ b/src/libcalamaresui/modulesystem/Module.h @@ -106,13 +106,6 @@ public: */ virtual QString instanceKey() const final; - /** - * @brief requiredModules a list of names of modules required by this one. - * @return the list of names. - * The module dependencies system is currently incomplete and unused. - */ - virtual QStringList requiredModules() const; - /** * @brief location returns the full path of this module's directory. * @return the path. @@ -198,7 +191,6 @@ private: void loadConfigurationFile( const QString& configFileName ); //throws YAML::Exception QString m_name; - QStringList m_requiredModules; QString m_directory; QString m_instanceId; From 08966ff9334cc28ee01524bce5a113aff5466cf2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 08:29:33 -0400 Subject: [PATCH 024/112] [libcalamaresui] Check module dependencies - Module dependency-checking is done in two phases: first, catch any unknown modules that are listed in *requiredModules* and bail out before loading anything. Second, check that the modules required by X occur before X in the sequence. --- .../modulesystem/ModuleManager.cpp | 54 +++++++++++++++++-- .../modulesystem/ModuleManager.h | 20 ++++++- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/libcalamaresui/modulesystem/ModuleManager.cpp b/src/libcalamaresui/modulesystem/ModuleManager.cpp index ed1e52f9f..24bc6bc53 100644 --- a/src/libcalamaresui/modulesystem/ModuleManager.cpp +++ b/src/libcalamaresui/modulesystem/ModuleManager.cpp @@ -126,7 +126,6 @@ ModuleManager::doInit() } // At this point m_availableModules is filled with whatever was found in the // search paths. - checkDependencies(); emit initDone(); } @@ -176,7 +175,13 @@ ModuleManager::loadModules() { QTimer::singleShot( 0, this, [ this ]() { - QStringList failedModules; + QStringList failedModules = checkDependencies(); + if ( !failedModules.isEmpty() ) + { + emit modulesFailed( failedModules ); + return; + } + Settings::InstanceDescriptionList customInstances = Settings::instance()->customModuleInstances(); @@ -262,6 +267,14 @@ ModuleManager::loadModules() failedModules.append( instanceKey ); continue; } + + if ( !checkDependencies( *thisModule ) ) + { + // Error message is already printed + failedModules.append( instanceKey ); + continue; + } + // If it's a ViewModule, it also appends the ViewStep to the ViewManager. thisModule->loadSelf(); m_loadedModulesByInstanceKey.insert( instanceKey, thisModule ); @@ -301,24 +314,29 @@ ModuleManager::loadModules() } -void +QStringList ModuleManager::checkDependencies() { + QStringList failed; + // This goes through the map of available modules, and deletes those whose // dependencies are not met, if any. - bool somethingWasRemovedBecauseOfUnmetDependencies = false; forever { + bool somethingWasRemovedBecauseOfUnmetDependencies = false; for ( auto it = m_availableDescriptorsByModuleName.begin(); it != m_availableDescriptorsByModuleName.end(); ++it ) { foreach ( const QString& depName, - ( *it ).value( "requiredModules" ).toStringList() ) + it->value( "requiredModules" ).toStringList() ) { if ( !m_availableDescriptorsByModuleName.contains( depName ) ) { + QString moduleName = it->value( "name" ).toString(); somethingWasRemovedBecauseOfUnmetDependencies = true; m_availableDescriptorsByModuleName.erase( it ); + failed << moduleName; + cWarning() << "Module" << moduleName << "has unmet requirement" << depName; break; } } @@ -328,7 +346,33 @@ ModuleManager::checkDependencies() if ( !somethingWasRemovedBecauseOfUnmetDependencies ) break; } + + return failed; } +bool +ModuleManager::checkDependencies( const Module& m ) +{ + bool allRequirementsFound = true; + QStringList requiredModules = m_availableDescriptorsByModuleName[ m.name() ].value( "requiredModules" ).toStringList(); + + for ( const QString& required : requiredModules ) + { + bool requirementFound = false; + for( const Module* v : m_loadedModulesByInstanceKey ) + if ( required == v->name() ) + { + requirementFound = true; + break; + } + if ( !requirementFound ) + { + cError() << "Module" << m.name() << "requires" << required << "before it in sequence."; + allRequirementsFound = false; + } + } + + return allRequirementsFound; +} } diff --git a/src/libcalamaresui/modulesystem/ModuleManager.h b/src/libcalamaresui/modulesystem/ModuleManager.h index eff09b321..a0edc2528 100644 --- a/src/libcalamaresui/modulesystem/ModuleManager.h +++ b/src/libcalamaresui/modulesystem/ModuleManager.h @@ -90,7 +90,25 @@ private slots: void doInit(); private: - void checkDependencies(); + /** + * Check in a general sense whether the dependencies between + * modules are valid. Returns a list of module names that + * do **not** have their requirements met. + * + * Returns an empty list on success. + * + * Also modifies m_availableDescriptorsByModuleName to remove + * all the entries that fail. + */ + QStringList checkDependencies(); + + /** + * Check for this specific module if its required modules have + * already been loaded (i.e. are in sequence before it). + * + * Returns true if the requirements are met. + */ + bool checkDependencies( const Module& ); QMap< QString, QVariantMap > m_availableDescriptorsByModuleName; QMap< QString, QString > m_moduleDirectoriesByModuleName; From 0db8082ae1972f0d882c071427a3bc7ab8d5600a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 08:41:16 -0400 Subject: [PATCH 025/112] [libcalamares] Convenience type --- src/libcalamares/Settings.cpp | 2 +- src/libcalamares/Settings.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libcalamares/Settings.cpp b/src/libcalamares/Settings.cpp index 1fdfc6daa..8fd4eeac3 100644 --- a/src/libcalamares/Settings.cpp +++ b/src/libcalamares/Settings.cpp @@ -212,7 +212,7 @@ Settings::customModuleInstances() const } -QList< QPair< ModuleAction, QStringList > > +Settings::ModuleSequence Settings::modulesSequence() const { return m_modulesSequence; diff --git a/src/libcalamares/Settings.h b/src/libcalamares/Settings.h index 2330f5747..4da65f710 100644 --- a/src/libcalamares/Settings.h +++ b/src/libcalamares/Settings.h @@ -47,7 +47,8 @@ public: using InstanceDescriptionList = QList< InstanceDescription >; InstanceDescriptionList customModuleInstances() const; - QList< QPair< ModuleAction, QStringList > > modulesSequence() const; + using ModuleSequence = QList< QPair< ModuleAction, QStringList > >; + ModuleSequence modulesSequence() const; QString brandingComponentName() const; @@ -63,7 +64,7 @@ private: QStringList m_modulesSearchPaths; InstanceDescriptionList m_customModuleInstances; - QList< QPair< ModuleAction, QStringList > > m_modulesSequence; + ModuleSequence m_modulesSequence; QString m_brandingComponentName; From d66393f1aeac1efbfa8b990bca6ff8f69df48429 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 08:43:23 -0400 Subject: [PATCH 026/112] [libcalamares] Fix early failure mode - There is more to failing out of loadModules() than just emitting modulesFailed, so instead share the failure code with the code after loading modules -- but don't load any. --- src/libcalamaresui/modulesystem/ModuleManager.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libcalamaresui/modulesystem/ModuleManager.cpp b/src/libcalamaresui/modulesystem/ModuleManager.cpp index 24bc6bc53..86d97d2db 100644 --- a/src/libcalamaresui/modulesystem/ModuleManager.cpp +++ b/src/libcalamaresui/modulesystem/ModuleManager.cpp @@ -176,16 +176,10 @@ ModuleManager::loadModules() QTimer::singleShot( 0, this, [ this ]() { QStringList failedModules = checkDependencies(); - if ( !failedModules.isEmpty() ) - { - emit modulesFailed( failedModules ); - return; - } - Settings::InstanceDescriptionList customInstances = Settings::instance()->customModuleInstances(); - const auto modulesSequence = Settings::instance()->modulesSequence(); + const auto modulesSequence = failedModules.isEmpty() ? Settings::instance()->modulesSequence() : Settings::ModuleSequence(); for ( const auto& modulePhase : modulesSequence ) { ModuleAction currentAction = modulePhase.first; @@ -336,7 +330,7 @@ ModuleManager::checkDependencies() somethingWasRemovedBecauseOfUnmetDependencies = true; m_availableDescriptorsByModuleName.erase( it ); failed << moduleName; - cWarning() << "Module" << moduleName << "has unmet requirement" << depName; + cWarning() << "Module" << moduleName << "has unknown requirement" << depName; break; } } From 08fc93f13775735968534ce2a2a25fa2aba554e3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 10:46:55 -0400 Subject: [PATCH 027/112] [services] Rename to services-systemd --- settings.conf | 2 +- src/modules/{services => services-systemd}/main.py | 0 src/modules/{services => services-systemd}/module.desc | 2 +- .../services.conf => services-systemd/services-systemd.conf} | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename src/modules/{services => services-systemd}/main.py (100%) rename src/modules/{services => services-systemd}/module.desc (72%) rename src/modules/{services/services.conf => services-systemd/services-systemd.conf} (100%) diff --git a/settings.conf b/settings.conf index 546b08d39..1c95721b7 100644 --- a/settings.conf +++ b/settings.conf @@ -102,7 +102,7 @@ sequence: - displaymanager - networkcfg - hwclock - - services + - services-systemd # - dracut - initramfs # - grubcfg diff --git a/src/modules/services/main.py b/src/modules/services-systemd/main.py similarity index 100% rename from src/modules/services/main.py rename to src/modules/services-systemd/main.py diff --git a/src/modules/services/module.desc b/src/modules/services-systemd/module.desc similarity index 72% rename from src/modules/services/module.desc rename to src/modules/services-systemd/module.desc index eff1dcc63..4a72b658b 100644 --- a/src/modules/services/module.desc +++ b/src/modules/services-systemd/module.desc @@ -1,6 +1,6 @@ --- type: "job" -name: "services" +name: "services-systemd" interface: "python" requires: [] script: "main.py" diff --git a/src/modules/services/services.conf b/src/modules/services-systemd/services-systemd.conf similarity index 100% rename from src/modules/services/services.conf rename to src/modules/services-systemd/services-systemd.conf From 0e314447eca6f5503cb9db7042bb108c7af04ba9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 26 Jun 2018 10:55:27 -0400 Subject: [PATCH 028/112] CMake: show the USE variable for services --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fa59421c..c06beba29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ option( WITH_KF5Crash "Enable crash reporting with KCrash." ON ) # **available** to `settings.conf`, not that they are used). # # Currently, no USE_ variables exist. +set( USE_services "" CACHE STRING "Select the services module to use" ) ### Calamares application info # From 0520fc3b7e73754a330e8c3ced0227cc2a93fd51 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 05:07:18 -0400 Subject: [PATCH 029/112] [services-systemd] Refactor to repeat less code - The three steps of modifying services in the target system do basically the same thing, so factor out the loops and logging into a systemctl() function. - Log to warning() instead of just debugging, on failure. --- src/modules/services-systemd/main.py | 99 +++++++++++----------------- 1 file changed, 40 insertions(+), 59 deletions(-) diff --git a/src/modules/services-systemd/main.py b/src/modules/services-systemd/main.py index 48e61d882..a2b2dd4f4 100644 --- a/src/modules/services-systemd/main.py +++ b/src/modules/services-systemd/main.py @@ -23,6 +23,36 @@ import libcalamares +def systemctl(targets, command, suffix): + """ + For each entry in @p targets, run "systemctl ", + where is the entry's name plus the given @p suffix. + A dot is added between name and suffix. + + Returns a failure message, or None if this was successful. + Services that are not mandatory have their failures suppressed + silently. + """ + for svc in targets: + ec = libcalamares.utils.target_env_call( + ['systemctl', command, "{}.{}".format(svc['name'], suffix)] + ) + + if ec != 0: + if svc['mandatory']: + return ("Cannot {} systemd {} {}".format(command, suffix, svc['name']), + "systemctl {} call in chroot returned error code {}".format(command, ec) + ) + else: + libcalamares.utils.warning( + "Cannot {} systemd {} {}".format(command, suffix, svc['name']) + ) + libcalamares.utils.warning( + "systemctl {} call in chroot returned error code {}".format(command, ec) + ) + return None + + def run(): """ Setup systemd services @@ -36,66 +66,17 @@ def run(): # that support that, see: # http://0pointer.de/blog/projects/changing-roots.html - # enable services - for svc in services: - ec = libcalamares.utils.target_env_call( - ['systemctl', 'enable', '{}.service'.format(svc['name'])] - ) + r = systemctl(services, "enable", "service") + if r is not None: + return r - if ec != 0: - if svc['mandatory']: - return ("Cannot enable systemd service {}".format(svc['name']), - "systemctl enable call in chroot returned error code " - "{}".format(ec) - ) - else: - libcalamares.utils.debug( - "Cannot enable systemd service {}".format(svc['name']) - ) - libcalamares.utils.debug( - "systemctl enable call in chroot returned error code " - "{}".format(ec) - ) + r = systemctl(targets, "enable", "target") + if r is not None: + return r - # enable targets - for tgt in targets: - ec = libcalamares.utils.target_env_call( - ['systemctl', 'enable', '{}.target'.format(tgt['name'])] - ) - - if ec != 0: - if tgt['mandatory']: - return ("Cannot enable systemd target {}".format(tgt['name']), - "systemctl enable call in chroot returned error code" - "{}".format(ec) - ) - else: - libcalamares.utils.debug( - "Cannot enable systemd target {}".format(tgt['name']) - ) - libcalamares.utils.debug( - "systemctl enable call in chroot returned error code " - "{}".format(ec) - ) - - for dbl in disable: - ec = libcalamares.utils.target_env_call( - ['systemctl', 'disable', '{}.service'.format(dbl['name'])] - ) - - if ec != 0: - if dbl['mandatory']: - return ("Cannot disable systemd service" - "{}".format(dbl['name']), - "systemctl disable call in chroot returned error code" - "{}".format(ec)) - else: - libcalamares.utils.debug( - "Cannot disable systemd service {}".format(dbl['name']) - ) - libcalamares.utils.debug( - "systemctl disable call in chroot returned error code " - "{}".format(ec) - ) + r = systemctl(disable, "disable", "service") + if r is not None: + return r + # This could have just been return r return None From 5d6e07712b6831b2e759c06e3eeefdae2b2bc1bd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 05:14:18 -0400 Subject: [PATCH 030/112] [services-systemd] Refactor getting config - Don't create temporary variables - Change API slightly to accomodate more (kinds of) suffixes --- src/modules/services-systemd/main.py | 14 ++++++-------- src/modules/services-systemd/services-systemd.conf | 6 +++++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/modules/services-systemd/main.py b/src/modules/services-systemd/main.py index a2b2dd4f4..31d205318 100644 --- a/src/modules/services-systemd/main.py +++ b/src/modules/services-systemd/main.py @@ -27,7 +27,7 @@ def systemctl(targets, command, suffix): """ For each entry in @p targets, run "systemctl ", where is the entry's name plus the given @p suffix. - A dot is added between name and suffix. + (No dot is added between name and suffix; suffix may be empty) Returns a failure message, or None if this was successful. Services that are not mandatory have their failures suppressed @@ -35,7 +35,7 @@ def systemctl(targets, command, suffix): """ for svc in targets: ec = libcalamares.utils.target_env_call( - ['systemctl', command, "{}.{}".format(svc['name'], suffix)] + ['systemctl', command, "{}{}".format(svc['name'], suffix)] ) if ec != 0: @@ -57,24 +57,22 @@ def run(): """ Setup systemd services """ - services = libcalamares.job.configuration['services'] - targets = libcalamares.job.configuration['targets'] - disable = libcalamares.job.configuration['disable'] + cfg = libcalamares.job.configuration # note that the "systemctl enable" and "systemctl disable" commands used # here will work in a chroot; in fact, they are the only systemctl commands # that support that, see: # http://0pointer.de/blog/projects/changing-roots.html - r = systemctl(services, "enable", "service") + r = systemctl(cfg["services"], "enable", ".service") if r is not None: return r - r = systemctl(targets, "enable", "target") + r = systemctl(cfg["targets"], "enable", ".target") if r is not None: return r - r = systemctl(disable, "disable", "service") + r = systemctl(cfg["disable"], "disable", ".service") if r is not None: return r diff --git a/src/modules/services-systemd/services-systemd.conf b/src/modules/services-systemd/services-systemd.conf index eb971b222..64b95e125 100644 --- a/src/modules/services-systemd/services-systemd.conf +++ b/src/modules/services-systemd/services-systemd.conf @@ -12,7 +12,8 @@ # *services*, *targets* and *disable*. The value of each # key is a list of entries. Each entry has two keys: # - *name* is the (string) name of the service or target that is being -# changed. Use quotes. +# changed. Use quotes. Don't include ".target" or ".service" +# in the name. # - *mandatory* is a boolean option, which states whether the change # must be done successfully. If systemd reports an error while changing # a mandatory entry, the installation will fail. When mandatory is false, @@ -25,16 +26,19 @@ # # graphical target (e.g. so that SDDM runs for login), and # # finally disables pacman-init (an ArchLinux-only service). # # +# # Enables .service # services: # - name: "NetworkManager" # mandatory: true # - name: "cups" # mandatory: false # +# # Enables .target # targets: # - name: "graphical" # mandatory: true # +# # Disables .service # disable: # - name: "pacman-init" # mandatory: false From c9c777b055f6a95871d17a1d3773a0aa39281ad4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 07:09:03 -0400 Subject: [PATCH 031/112] [services-systemd] Introduce disable-targets and mask - With refactored code, introducing new kinds of actions is very few lines of code. Allow disabling targets (services was already possible). Allow masking units, but as a special case require the complete name. FIXES #975 --- src/modules/services-systemd/main.py | 9 +++++++++ src/modules/services-systemd/services-systemd.conf | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/modules/services-systemd/main.py b/src/modules/services-systemd/main.py index 31d205318..dce571384 100644 --- a/src/modules/services-systemd/main.py +++ b/src/modules/services-systemd/main.py @@ -76,5 +76,14 @@ def run(): if r is not None: return r + r = systemctl(cfg["disable-targets"], "disable", ".target") + if r is not None: + return r + + r = systemctl(cfg["mask"], "mask", "") + if r is not None: + return r + + # This could have just been return r return None diff --git a/src/modules/services-systemd/services-systemd.conf b/src/modules/services-systemd/services-systemd.conf index 64b95e125..082d63657 100644 --- a/src/modules/services-systemd/services-systemd.conf +++ b/src/modules/services-systemd/services-systemd.conf @@ -42,8 +42,22 @@ # disable: # - name: "pacman-init" # mandatory: false +# +# # Disables .target +# disable-targets: [] +# +# # Masks (stronger version of disable). This section +# # is unusual because you **must** include the suffix +# # (e.g. ".service") as part of the name, so, e.g. to mask +# # NetworkManager (rather than just disable it) you must +# # specify "NetworkManager.service" as name. +# mask: +# - name: "NetworkManager.service" +# - mandatory: true # By default, no changes are made. services: [] targets: [] disable: [] +disable-targets: [] +mask: [] From 59b07cc720dd3cb077e69e591b1a467abb01c057 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 07:14:18 -0400 Subject: [PATCH 032/112] [services-systemd] Be more resilient in the config - If a key is not given, use [] instead of crashing. --- src/modules/services-systemd/main.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/services-systemd/main.py b/src/modules/services-systemd/main.py index dce571384..5ebe9066b 100644 --- a/src/modules/services-systemd/main.py +++ b/src/modules/services-systemd/main.py @@ -64,23 +64,23 @@ def run(): # that support that, see: # http://0pointer.de/blog/projects/changing-roots.html - r = systemctl(cfg["services"], "enable", ".service") + r = systemctl(cfg.get("services", []), "enable", ".service") if r is not None: return r - r = systemctl(cfg["targets"], "enable", ".target") + r = systemctl(cfg.get("targets", []), "enable", ".target") if r is not None: return r - r = systemctl(cfg["disable"], "disable", ".service") + r = systemctl(cfg.get("disable", []), "disable", ".service") if r is not None: return r - r = systemctl(cfg["disable-targets"], "disable", ".target") + r = systemctl(cfg.get("disable-targets", []), "disable", ".target") if r is not None: return r - r = systemctl(cfg["mask"], "mask", "") + r = systemctl(cfg.get("mask", []), "mask", "") if r is not None: return r From e1d306dc2fae9c5a41262c4d465f33864f57bc65 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 09:11:51 -0400 Subject: [PATCH 033/112] [services-openrc] Adjust documentation and follow renaming --- src/modules/openrccfg/openrccfg.conf | 39 ------------------- .../{openrccfg => services-openrc}/main.py | 0 .../module.desc | 2 +- .../services-openrc/services-openrc.conf | 34 ++++++++++++++++ 4 files changed, 35 insertions(+), 40 deletions(-) delete mode 100644 src/modules/openrccfg/openrccfg.conf rename src/modules/{openrccfg => services-openrc}/main.py (100%) rename src/modules/{openrccfg => services-openrc}/module.desc (68%) create mode 100644 src/modules/services-openrc/services-openrc.conf diff --git a/src/modules/openrccfg/openrccfg.conf b/src/modules/openrccfg/openrccfg.conf deleted file mode 100644 index efd56bc14..000000000 --- a/src/modules/openrccfg/openrccfg.conf +++ /dev/null @@ -1,39 +0,0 @@ -# operccfg -# openrc services module to set service runlevels via rc-update in the chroot -# -# format of the conf -### -# services: -# add: -# - name: foo1 -# runlevel: default -# - name: foo2 -# runlevel: nonetwork -# del: -# - name: foo3 -# runlevel: default -# -# initdDir: /etc/init.d -# -# runlevelsDir: /etc/runlevels -#### -# add: list of services and their runlevels to add -# del: list of services and their runlevels to delete -# name: the service name -# runlevel: can hold any runlevel present on the target system -# initdDir: holds the openrc service directory location -# runlevelsDir: holds the runlevels directory location -# -# handle del with care and only use it if absolutely necessary -# if a service is listed in the conf but is not present/detected on the target system, -# or a runlevel does not exist, it will be ignored and skipped -# ---- -services: - add: - - name: "NetworkManager" - runlevel: "default" - -initdDir: /etc/init.d - -runlevelsDir: /etc/runlevels diff --git a/src/modules/openrccfg/main.py b/src/modules/services-openrc/main.py similarity index 100% rename from src/modules/openrccfg/main.py rename to src/modules/services-openrc/main.py diff --git a/src/modules/openrccfg/module.desc b/src/modules/services-openrc/module.desc similarity index 68% rename from src/modules/openrccfg/module.desc rename to src/modules/services-openrc/module.desc index 1be7af923..4b0b51614 100644 --- a/src/modules/openrccfg/module.desc +++ b/src/modules/services-openrc/module.desc @@ -1,5 +1,5 @@ --- type: "job" -name: "openrccfg" +name: "services-openrc" interface: "python" script: "main.py" diff --git a/src/modules/services-openrc/services-openrc.conf b/src/modules/services-openrc/services-openrc.conf new file mode 100644 index 000000000..1d507e578 --- /dev/null +++ b/src/modules/services-openrc/services-openrc.conf @@ -0,0 +1,34 @@ +# openrc services module to modify service runlevels via rc-update in the chroot +# +# Services can be added (to any runlevel, or multiple runlevels) or deleted. +# Handle del with care and only use it if absolutely necessary. +# +# if a service is listed in the conf but is not present/detected on the target system, +# or a runlevel does not exist, it will be ignored and skipped; a warning is logged. +# +--- +# initdDir: holds the openrc service directory location +initdDir: /etc/init.d + +# runlevelsDir: holds the runlevels directory location +runlevelsDir: /etc/runlevels + +# services: each subkey of *services* is an action to take; +# supported actions are "add" and "del". The each subkey +# has a list of entries as value, and each entry has two +# fields: +# - name: the service name +# - runlevel: can hold any runlevel present on the target system +# +# # Example services: +# services: +# add: +# - name: foo1 +# runlevel: default +# - name: foo2 +# runlevel: nonetwork +# del: +# - name: foo3 +# runlevel: default +services: [] + From b1881d1cd2c1421ef125b755eff31e263a69cb2f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 09:19:05 -0400 Subject: [PATCH 034/112] [services-*] Adjust Copyright notices --- src/modules/services-openrc/main.py | 3 ++- src/modules/services-systemd/main.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/services-openrc/main.py b/src/modules/services-openrc/main.py index 9dc6bf1ff..a3b273141 100644 --- a/src/modules/services-openrc/main.py +++ b/src/modules/services-openrc/main.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- # -# === This file is part of Calamares - === +# === This file is part of Calamares - === # # Copyright 2016, Artoo # Copyright 2017, Philip Müller # Copyright 2018, Artoo +# Copyright 2018, Adriaan de Groot # # Calamares is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/src/modules/services-systemd/main.py b/src/modules/services-systemd/main.py index 5ebe9066b..54a731cf8 100644 --- a/src/modules/services-systemd/main.py +++ b/src/modules/services-systemd/main.py @@ -6,6 +6,7 @@ # Copyright 2014, Philip Müller # Copyright 2014, Teo Mrnjavac # Copyright 2017, Alf Gaida +# Copyright 2018, Adriaan de Groot # # Calamares is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by From cd640bda9fb682c63bebc46363e0dce90e23b2f9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 09:21:31 -0400 Subject: [PATCH 035/112] [services-openrc] Restrict actions - Document the functions some more - Only "state" (i.e. action) "add" and "del" make sense, avoid calling rc-update for other keys (e.g. typo's). This matches the documentation, although there might be other actions that make sense (see also services-systemd, with its enable, disable and mask actions). --- src/modules/services-openrc/main.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/modules/services-openrc/main.py b/src/modules/services-openrc/main.py index a3b273141..eb0da046e 100644 --- a/src/modules/services-openrc/main.py +++ b/src/modules/services-openrc/main.py @@ -28,7 +28,10 @@ from os.path import exists, join class OpenrcController: - """This is the openrc service controller + """ + This is the openrc service controller. + All of its state comes from global storage and the job + configuration at initialization time. """ def __init__(self): @@ -38,7 +41,10 @@ class OpenrcController: self.runlevelsDir = libcalamares.job.configuration['runlevelsDir'] def update(self, state): - """call rc-update for each service listed + """ + Call rc-update for each service listed + in services for the given @p state. rc-update + is called with @p state as the command as well. """ for svc in self.services[state]: @@ -52,11 +58,12 @@ class OpenrcController: """Run the controller """ - for state in self.services.keys(): + for state in ("add", "del"): self.update(state) def run(): - """Setup services + """ + Setup services """ return OpenrcController().run() From 8f0db9dc743c854af96fd2cf19802483ce514de5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 09:31:02 -0400 Subject: [PATCH 036/112] [services-openrc] Log configuration failures - If services don't exist, or runlevels don't exist, log them instead of failing completely silently. --- src/modules/services-openrc/main.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/modules/services-openrc/main.py b/src/modules/services-openrc/main.py index eb0da046e..52e4838b3 100644 --- a/src/modules/services-openrc/main.py +++ b/src/modules/services-openrc/main.py @@ -23,7 +23,7 @@ import libcalamares -from libcalamares.utils import target_env_call +from libcalamares.utils import target_env_call, warning from os.path import exists, join @@ -47,12 +47,17 @@ class OpenrcController: is called with @p state as the command as well. """ - for svc in self.services[state]: - if exists(self.root + self.initdDir + "/" + svc["name"]): - if exists(self.root + self.runlevelsDir + "/" + svc["runlevel"]): - target_env_call( - ["rc-update", state, svc["name"], svc["runlevel"]] - ) + for svc in self.services.get(state, []): + service_path = self.root + self.initdDir + "/" + svc["name"] + runlevel_path = self.root + self.runlevelsDir + "/" + svc["runlevel"] + if exists(service_path): + if exists(runlevel_path): + target_env_call(["rc-update", state, svc["name"], svc["runlevel"]]) + else: + warning("Target runlevel {} does not exist for {}.".format(svc["runlevel"], svc["name"])) + else: + warning("Target service {} does not exist int {}.".format(svc["name"], self.initDir)) + def run(self): """Run the controller From 5a2ae7a250b77391fcc6b656fb91b00720abe5d3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 09:33:02 -0400 Subject: [PATCH 037/112] [services-openrc] Simplify name extraction, default runlevel - If runlevel isn't set (at all) then use "default". For most systems that do not use multiple runlevels, this simplifies the configuration to just a list of service names to add or delete. --- src/modules/services-openrc/main.py | 13 ++++++++----- src/modules/services-openrc/services-openrc.conf | 7 +++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/modules/services-openrc/main.py b/src/modules/services-openrc/main.py index 52e4838b3..27ea6ebb6 100644 --- a/src/modules/services-openrc/main.py +++ b/src/modules/services-openrc/main.py @@ -48,15 +48,18 @@ class OpenrcController: """ for svc in self.services.get(state, []): - service_path = self.root + self.initdDir + "/" + svc["name"] - runlevel_path = self.root + self.runlevelsDir + "/" + svc["runlevel"] + name = svc["name"] + runlevel = svc.get("runlevel", "default") + + service_path = self.root + self.initdDir + "/" + name + runlevel_path = self.root + self.runlevelsDir + "/" + runlevel if exists(service_path): if exists(runlevel_path): - target_env_call(["rc-update", state, svc["name"], svc["runlevel"]]) + target_env_call(["rc-update", state, name, runlevel]) else: - warning("Target runlevel {} does not exist for {}.".format(svc["runlevel"], svc["name"])) + warning("Target runlevel {} does not exist for {}.".format(runlevel, name)) else: - warning("Target service {} does not exist int {}.".format(svc["name"], self.initDir)) + warning("Target service {} does not exist int {}.".format(name, self.initDir)) def run(self): diff --git a/src/modules/services-openrc/services-openrc.conf b/src/modules/services-openrc/services-openrc.conf index 1d507e578..61440f692 100644 --- a/src/modules/services-openrc/services-openrc.conf +++ b/src/modules/services-openrc/services-openrc.conf @@ -18,13 +18,16 @@ runlevelsDir: /etc/runlevels # has a list of entries as value, and each entry has two # fields: # - name: the service name -# - runlevel: can hold any runlevel present on the target system +# - runlevel: can hold any runlevel present on the target system; +# if no runlevel is provided, "default" is assumed. # # # Example services: +# # - add foo1 to default +# # - add foo2 to nonetwork +# # - remove foo3 from default # services: # add: # - name: foo1 -# runlevel: default # - name: foo2 # runlevel: nonetwork # del: From dbcc419218b2409f925d059b030d79d4eca1bea3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 09:39:30 -0400 Subject: [PATCH 038/112] [services-openrc] Log failures - If the rc-update command fails for some reason, log that failure instead of skipping it completely silently. - Fix syntax error as well --- src/modules/services-openrc/main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/modules/services-openrc/main.py b/src/modules/services-openrc/main.py index 27ea6ebb6..cfa7fd457 100644 --- a/src/modules/services-openrc/main.py +++ b/src/modules/services-openrc/main.py @@ -53,13 +53,16 @@ class OpenrcController: service_path = self.root + self.initdDir + "/" + name runlevel_path = self.root + self.runlevelsDir + "/" + runlevel + if exists(service_path): if exists(runlevel_path): - target_env_call(["rc-update", state, name, runlevel]) + ec = target_env_call(["rc-update", state, name, runlevel]) + if ec != 0: + warning("Could not {} service {} in {}, error {!s}".format(state, name, runlevel, ec)) else: warning("Target runlevel {} does not exist for {}.".format(runlevel, name)) else: - warning("Target service {} does not exist int {}.".format(name, self.initDir)) + warning("Target service {} does not exist in {}.".format(name, self.initdDir)) def run(self): From b02ee3cd8d033660bfdbaf1d21ad407115e67be3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 09:46:43 -0400 Subject: [PATCH 039/112] [services-openrc] Follow services-systemd configuration example - Based on comments from #974, follow the configuration scheme from services-systemd, so with separate lists "services" and "disable". This ties it **slightly** less closely to the commands passed to rc-config. --- src/modules/services-openrc/main.py | 7 +++++- .../services-openrc/services-openrc.conf | 24 +++++++++---------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/modules/services-openrc/main.py b/src/modules/services-openrc/main.py index cfa7fd457..63d17bcc0 100644 --- a/src/modules/services-openrc/main.py +++ b/src/modules/services-openrc/main.py @@ -36,7 +36,12 @@ class OpenrcController: def __init__(self): self.root = libcalamares.globalstorage.value('rootMountPoint') - self.services = libcalamares.job.configuration.get('services', []) + + # Translate the entries in the config to the actions passed to rc-config + self.services = dict() + self.services["add"] = libcalamares.job.configuration.get('services', []) + self.services["del"] = libcalamares.job.configuration.get('disable', []) + self.initdDir = libcalamares.job.configuration['initdDir'] self.runlevelsDir = libcalamares.job.configuration['runlevelsDir'] diff --git a/src/modules/services-openrc/services-openrc.conf b/src/modules/services-openrc/services-openrc.conf index 61440f692..c89c82a32 100644 --- a/src/modules/services-openrc/services-openrc.conf +++ b/src/modules/services-openrc/services-openrc.conf @@ -13,25 +13,25 @@ initdDir: /etc/init.d # runlevelsDir: holds the runlevels directory location runlevelsDir: /etc/runlevels -# services: each subkey of *services* is an action to take; -# supported actions are "add" and "del". The each subkey -# has a list of entries as value, and each entry has two -# fields: +# services: a list of entries to **enable** +# disable: a list of entries to **disable** +# +# Each entry has two fields: # - name: the service name # - runlevel: can hold any runlevel present on the target system; # if no runlevel is provided, "default" is assumed. # -# # Example services: +# # Example services and disable settings: # # - add foo1 to default # # - add foo2 to nonetwork # # - remove foo3 from default # services: -# add: -# - name: foo1 -# - name: foo2 -# runlevel: nonetwork -# del: -# - name: foo3 -# runlevel: default +# - name: foo1 +# - name: foo2 +# runlevel: nonetwork +# disable: +# - name: foo3 +# runlevel: default services: [] +disable: [] From 72c0d1a1012266168cd85923f426f02678d0ccc0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 10:28:32 -0400 Subject: [PATCH 040/112] [services-openrc] Make list of services more flexible - Allow just a name entry, instead of requiring an object entry; this makes "foo" equal to { name: "foo", runlevel: "default" } and simplifies more for the straightfoward case of #974. --- src/modules/services-openrc/main.py | 8 ++++++-- src/modules/services-openrc/services-openrc.conf | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/modules/services-openrc/main.py b/src/modules/services-openrc/main.py index 63d17bcc0..6f1d7352b 100644 --- a/src/modules/services-openrc/main.py +++ b/src/modules/services-openrc/main.py @@ -53,8 +53,12 @@ class OpenrcController: """ for svc in self.services.get(state, []): - name = svc["name"] - runlevel = svc.get("runlevel", "default") + if isinstance(svc, str): + name = svc + runlevel = "default" + else: + name = svc["name"] + runlevel = svc.get("runlevel", "default") service_path = self.root + self.initdDir + "/" + name runlevel_path = self.root + self.runlevelsDir + "/" + runlevel diff --git a/src/modules/services-openrc/services-openrc.conf b/src/modules/services-openrc/services-openrc.conf index c89c82a32..168fa190a 100644 --- a/src/modules/services-openrc/services-openrc.conf +++ b/src/modules/services-openrc/services-openrc.conf @@ -20,11 +20,14 @@ runlevelsDir: /etc/runlevels # - name: the service name # - runlevel: can hold any runlevel present on the target system; # if no runlevel is provided, "default" is assumed. +# an entry may also be a single string, which is interpreted +# as the name field (runlevel "default" is assumed then). # # # Example services and disable settings: # # - add foo1 to default # # - add foo2 to nonetwork # # - remove foo3 from default +# # - remove foo4 from default # services: # - name: foo1 # - name: foo2 @@ -32,6 +35,7 @@ runlevelsDir: /etc/runlevels # disable: # - name: foo3 # runlevel: default +# - foo4 services: [] disable: [] From 73ecd7320c1b44c4406268e2d2a7866c2e69379b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 11:11:21 -0400 Subject: [PATCH 041/112] [services-openrc] Introduce *mandatory* subkey - Follow services-systemd and have a *mandatory* subkey that selects for install-failure instead of just a warning. FIXES #992 --- src/modules/services-openrc/main.py | 25 ++++++++++++++++--- .../services-openrc/services-openrc.conf | 15 +++++++---- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/modules/services-openrc/main.py b/src/modules/services-openrc/main.py index 6f1d7352b..c3e14b481 100644 --- a/src/modules/services-openrc/main.py +++ b/src/modules/services-openrc/main.py @@ -56,9 +56,11 @@ class OpenrcController: if isinstance(svc, str): name = svc runlevel = "default" + mandatory = False else: name = svc["name"] runlevel = svc.get("runlevel", "default") + mandatory = svc.get("mandatory", False) service_path = self.root + self.initdDir + "/" + name runlevel_path = self.root + self.runlevelsDir + "/" + runlevel @@ -67,11 +69,24 @@ class OpenrcController: if exists(runlevel_path): ec = target_env_call(["rc-update", state, name, runlevel]) if ec != 0: - warning("Could not {} service {} in {}, error {!s}".format(state, name, runlevel, ec)) + if mandatory: + return ("Cannot {} service {} to {}".format(state, name, runlevel), + "rc-update {} call in chroot returned error code {}".format(state, ec) + ) + else: + warning("Could not {} service {} in {}, error {!s}".format(state, name, runlevel, ec)) else: - warning("Target runlevel {} does not exist for {}.".format(runlevel, name)) + if mandatory: + return ("Target runlevel {} does not exist for {}.".format(runlevel, name), + "No {} found.".format(runlevel_path)) + else: + warning("Target runlevel {} does not exist for {}.".format(runlevel, name)) else: - warning("Target service {} does not exist in {}.".format(name, self.initdDir)) + if mandatory: + return ("Target service {} does not exist.".format(name), + "No {} found.".format(service_path)) + else: + warning("Target service {} does not exist in {}.".format(name, self.initdDir)) def run(self): @@ -79,7 +94,9 @@ class OpenrcController: """ for state in ("add", "del"): - self.update(state) + r = self.update(state) + if r is not None: + return r def run(): """ diff --git a/src/modules/services-openrc/services-openrc.conf b/src/modules/services-openrc/services-openrc.conf index 168fa190a..b8255b21a 100644 --- a/src/modules/services-openrc/services-openrc.conf +++ b/src/modules/services-openrc/services-openrc.conf @@ -16,20 +16,25 @@ runlevelsDir: /etc/runlevels # services: a list of entries to **enable** # disable: a list of entries to **disable** # -# Each entry has two fields: +# Each entry has three fields: # - name: the service name -# - runlevel: can hold any runlevel present on the target system; -# if no runlevel is provided, "default" is assumed. +# - (optional) runlevel: can hold any runlevel present on the target +# system; if no runlevel is provided, "default" is assumed. +# - (optional) mandatory: if set to true, a failure to modify +# the service will result in installation failure, rather than just +# a warning. The default is false. +# # an entry may also be a single string, which is interpreted -# as the name field (runlevel "default" is assumed then). +# as the name field (runlevel "default" is assumed then, and not-mandatory). # # # Example services and disable settings: -# # - add foo1 to default +# # - add foo1 to default, but it must succeed # # - add foo2 to nonetwork # # - remove foo3 from default # # - remove foo4 from default # services: # - name: foo1 +# mandatory: true # - name: foo2 # runlevel: nonetwork # disable: From 1957478618257944e1a67244b1448c562c3127ed Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 11:25:11 -0400 Subject: [PATCH 042/112] [services-systemd] Follow the flexible example of openrc - Make *mandatory* optional (and default to false); this allows shorter lists of entries - Allow degenerate entries which are just a name (which have *mandatory* set to false as well). SEE #992 --- src/modules/services-systemd/main.py | 15 +++++++++++---- .../services-systemd/services-systemd.conf | 11 +++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/modules/services-systemd/main.py b/src/modules/services-systemd/main.py index 54a731cf8..09263b9f0 100644 --- a/src/modules/services-systemd/main.py +++ b/src/modules/services-systemd/main.py @@ -35,18 +35,25 @@ def systemctl(targets, command, suffix): silently. """ for svc in targets: + if isinstance(svc, str): + name = svc + mandatory = False + else: + name = svc["name"] + mandatory = svc.get("mandatory", False) + ec = libcalamares.utils.target_env_call( - ['systemctl', command, "{}{}".format(svc['name'], suffix)] + ['systemctl', command, "{}{}".format(name, suffix)] ) if ec != 0: - if svc['mandatory']: - return ("Cannot {} systemd {} {}".format(command, suffix, svc['name']), + if mandatory: + return ("Cannot {} systemd {} {}".format(command, suffix, name), "systemctl {} call in chroot returned error code {}".format(command, ec) ) else: libcalamares.utils.warning( - "Cannot {} systemd {} {}".format(command, suffix, svc['name']) + "Cannot {} systemd {} {}".format(command, suffix, name) ) libcalamares.utils.warning( "systemctl {} call in chroot returned error code {}".format(command, ec) diff --git a/src/modules/services-systemd/services-systemd.conf b/src/modules/services-systemd/services-systemd.conf index 082d63657..6ff1409bf 100644 --- a/src/modules/services-systemd/services-systemd.conf +++ b/src/modules/services-systemd/services-systemd.conf @@ -17,7 +17,12 @@ # - *mandatory* is a boolean option, which states whether the change # must be done successfully. If systemd reports an error while changing # a mandatory entry, the installation will fail. When mandatory is false, -# errors for that entry (service or target) are ignored. +# errors for that entry (service or target) are ignored. If mandatory +# is not specified, the default is false. +# +# An entry may also be given as a single string, which is then +# interpreted as the name of the service. In this case, mandatory +# is also set to the default of false. # # Use [] to express an empty list. @@ -44,7 +49,9 @@ # mandatory: false # # # Disables .target -# disable-targets: [] +# # .. this shows how to use just the name +# disable-targets: +# - graphical # # # Masks (stronger version of disable). This section # # is unusual because you **must** include the suffix From 37552c184b9509e12393532ad6cc1c7823c32255 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 12:50:20 -0400 Subject: [PATCH 043/112] ci: add a release script This is the start of a release script. The idea is to automate a whole bunch of the steps documented in ci/RELEASE.md, so that a release becomes more straightforward. Assumptions abound: basically this is going to work on my workstation, and not on any other. --- ci/RELEASE.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 ci/RELEASE.sh diff --git a/ci/RELEASE.sh b/ci/RELEASE.sh new file mode 100644 index 000000000..51ca42d4f --- /dev/null +++ b/ci/RELEASE.sh @@ -0,0 +1,23 @@ +#! /bin/sh +# +# Release script for Calamares +# +# This attempts to perform the different steps of the RELEASE.md +# document automatically. It's not tested on other machines or +# setups other than [ade]'s development VM. +# +# Assumes that the version in CMakeLists.txt has been bumped, +# and that a release of that version is desired. + +test -d .git || { echo "Not at top-level." ; exit 1 ; } +test -d src/modules || { echo "No src/modules." ; exit 1 ; } + +which cmake > /dev/null 2>&1 || { echo "No cmake(1) available." ; exit 1 ; } + +rm -rf build +mkdir build || { echo "Could not create build directory." ; exit 1 ; } +( cd build && cmake .. && make -j4 ) || { echo "Could not perform test-build." ; exit 1 ; } +( cd build && make test ) || { echo "Tests failed." ; exit 1 ; } + + + From cfe92252d289e13eb18b30c83fdb24f337d04f3a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 12:53:45 -0400 Subject: [PATCH 044/112] ci: if clang is available, do that build too --- ci/RELEASE.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ci/RELEASE.sh b/ci/RELEASE.sh index 51ca42d4f..528735ed9 100644 --- a/ci/RELEASE.sh +++ b/ci/RELEASE.sh @@ -19,5 +19,11 @@ mkdir build || { echo "Could not create build directory." ; exit 1 ; } ( cd build && cmake .. && make -j4 ) || { echo "Could not perform test-build." ; exit 1 ; } ( cd build && make test ) || { echo "Tests failed." ; exit 1 ; } - +if which clang++ > /dev/null 2>&1 ; then + # Do build again with clang + rm -rf build + mkdir build || { echo "Could not create build directory." ; exit 1 ; } + ( cd build && CC=clang CXX=clang++ cmake .. && make -j4 ) || { echo "Could not perform test-build." ; exit 1 ; } + ( cd build && make test ) || { echo "Tests failed." ; exit 1 ; } +fi From 9f1cfba4efbb91ddd52f3246b5614fb318a80495 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Wed, 27 Jun 2018 12:55:48 -0400 Subject: [PATCH 045/112] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_pl.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lang/calamares_pl.ts b/lang/calamares_pl.ts index 48edd7065..706a44cf5 100644 --- a/lang/calamares_pl.ts +++ b/lang/calamares_pl.ts @@ -50,7 +50,7 @@ Blank Page - + Pusta strona @@ -192,17 +192,17 @@ Calamares Initialization Failed - + Błąd inicjacji programu Calamares %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + %1 nie może zostać zainstalowany. Calamares nie mógł wczytać wszystkich skonfigurowanych modułów. Jest to problem ze sposobem, w jaki Calamares jest używany przez dystrybucję. <br/>The following modules could not be loaded: - + <br/>Następujące moduły nie mogły zostać wczytane: @@ -1663,7 +1663,7 @@ Instalator zostanie zamknięty i wszystkie zmiany zostaną utracone. Cre&ate - + Ut_wórz From 2f6e80dc428431247a19c16ae0f219044c10b0e2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jun 2018 13:20:52 -0400 Subject: [PATCH 046/112] CMake: always copy the config files to the build directory. Switching to INSTALL_CONFIG=OFF breaks tests by not having them in the build directory. Some logic was coupling not-installing to not-using-in-build-dir too closely. --- .../CalamaresAddModuleSubdirectory.cmake | 13 +++++---- CMakeModules/CalamaresAddPlugin.cmake | 28 ++++++++++--------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/CMakeModules/CalamaresAddModuleSubdirectory.cmake b/CMakeModules/CalamaresAddModuleSubdirectory.cmake index af26f5a74..0b417bdf3 100644 --- a/CMakeModules/CalamaresAddModuleSubdirectory.cmake +++ b/CMakeModules/CalamaresAddModuleSubdirectory.cmake @@ -85,9 +85,11 @@ function( calamares_add_module_subdirectory ) configure_file( ${SUBDIRECTORY}/${MODULE_FILE} ${SUBDIRECTORY}/${MODULE_FILE} COPYONLY ) get_filename_component( FLEXT ${MODULE_FILE} EXT ) - if( "${FLEXT}" STREQUAL ".conf" AND INSTALL_CONFIG) - install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE} - DESTINATION ${MODULE_DATA_DESTINATION} ) + if( "${FLEXT}" STREQUAL ".conf" ) + if( INSTALL_CONFIG ) + install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE} + DESTINATION ${MODULE_DATA_DESTINATION} ) + endif() list( APPEND MODULE_CONFIG_FILES ${MODULE_FILE} ) else() install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE} @@ -102,10 +104,11 @@ function( calamares_add_module_subdirectory ) message( " ${Green}MODULE_DESTINATION:${ColorReset} ${MODULE_DESTINATION}" ) if( MODULE_CONFIG_FILES ) if ( INSTALL_CONFIG ) - message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${MODULE_CONFIG_FILES} => ${MODULE_DATA_DESTINATION}" ) + set( _destination "${MODULE_DATA_DESTINATION}" ) else() - message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${MODULE_CONFIG_FILES} => [Skipping installation]" ) + set( _destination "[Build directory only]" ) endif() + message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${MODULE_CONFIG_FILES} => ${_destination}" ) endif() message( "" ) endif() diff --git a/CMakeModules/CalamaresAddPlugin.cmake b/CMakeModules/CalamaresAddPlugin.cmake index d2f878381..1bf20e4ca 100644 --- a/CMakeModules/CalamaresAddPlugin.cmake +++ b/CMakeModules/CalamaresAddPlugin.cmake @@ -66,17 +66,18 @@ function( calamares_add_plugin ) 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}" ) -# message( " ${Green}NO_INSTALL:${ColorReset} ${PLUGIN_NO_INSTALL}" ) message( " ${Green}PLUGIN_DESTINATION:${ColorReset} ${PLUGIN_DESTINATION}" ) if( PLUGIN_CONFIG_FILES ) + set( _destination "(unknown)" ) if ( INSTALL_CONFIG AND NOT PLUGIN_NO_INSTALL ) - message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${PLUGIN_CONFIG_FILES} => ${PLUGIN_DATA_DESTINATION}" ) + set( _destination "${PLUGIN_DATA_DESTINATION}" ) + elseif( NOT PLUGIN_NO_INSTALL ) + # Not INSTALL_CONFIG + set( _destination "[Build directory only]" ) else() - message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${PLUGIN_CONFIG_FILES} => [Skipping installation]" ) + set( _destination "[Skipping installation]" ) endif() + message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${PLUGIN_CONFIG_FILES} => ${_destination}" ) endif() if( PLUGIN_RESOURCES ) message( " ${Green}RESOURCES:${ColorReset} ${PLUGIN_RESOURCES}" ) @@ -147,12 +148,13 @@ function( calamares_add_plugin ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_DESC_FILE} DESTINATION ${PLUGIN_DESTINATION} ) - if ( INSTALL_CONFIG ) - foreach( PLUGIN_CONFIG_FILE ${PLUGIN_CONFIG_FILES} ) - configure_file( ${PLUGIN_CONFIG_FILE} ${PLUGIN_CONFIG_FILE} COPYONLY ) - install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE} - DESTINATION ${PLUGIN_DATA_DESTINATION} ) - endforeach() - endif() + foreach( PLUGIN_CONFIG_FILE ${PLUGIN_CONFIG_FILES} ) + configure_file( ${PLUGIN_CONFIG_FILE} ${PLUGIN_CONFIG_FILE} COPYONLY ) + if ( INSTALL_CONFIG ) + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE} + DESTINATION ${PLUGIN_DATA_DESTINATION} ) + endif() + endforeach() endif() endfunction() From dfb42f2b49a347c4c6020a299f5b3cab96628914 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 28 Jun 2018 05:19:32 -0400 Subject: [PATCH 047/112] CMake: add target show-version to get version information --- CMakeLists.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c06beba29..a46b0d37d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,9 @@ # Example usage: # # cmake . -DSKIP_MODULES="partition luksbootkeycfg" +# +# One special target is "show-version", which can be built +# to obtain the version number from here. project( calamares C CXX ) @@ -74,7 +77,6 @@ set( CALAMARES_VERSION_MINOR 2 ) set( CALAMARES_VERSION_PATCH 1 ) set( CALAMARES_VERSION_RC 0 ) - ### Transifex (languages) info # # complete = 100% translated, @@ -394,6 +396,15 @@ if( NOT BUILD_RELEASE AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git/" ) endif() endif() +# Special target for not-RC (e.g. might-be-release) builds. +# This is used by the release script to get the version. +if ( CALAMARES_VERSION_RC EQUAL 0 ) + add_custom_target(show-version + ${CMAKE_COMMAND} -E echo CALAMARES_VERSION=${CALAMARES_VERSION_SHORT} + USES_TERMINAL + ) +endif() + # enforce using constBegin, constEnd for const-iterators add_definitions( "-DQT_STRICT_ITERATORS" ) From 59dd181cfcf248b513e8ecaa01d9b863ab527b53 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 28 Jun 2018 05:48:04 -0400 Subject: [PATCH 048/112] ci: complete release script - Create tag, tarball, and test tarball - Print instructions for completing the release --- ci/RELEASE.sh | 84 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/ci/RELEASE.sh b/ci/RELEASE.sh index 528735ed9..d3c960fd9 100644 --- a/ci/RELEASE.sh +++ b/ci/RELEASE.sh @@ -5,25 +5,89 @@ # This attempts to perform the different steps of the RELEASE.md # document automatically. It's not tested on other machines or # setups other than [ade]'s development VM. -# +# # Assumes that the version in CMakeLists.txt has been bumped, # and that a release of that version is desired. +# +# None of the "update stuff" is done by this script; in preparation +# for the release, you should have already done: +# - updating the version +# - pulling translations +# - updating the language list +# - switching to the right branch test -d .git || { echo "Not at top-level." ; exit 1 ; } test -d src/modules || { echo "No src/modules." ; exit 1 ; } which cmake > /dev/null 2>&1 || { echo "No cmake(1) available." ; exit 1 ; } -rm -rf build -mkdir build || { echo "Could not create build directory." ; exit 1 ; } -( cd build && cmake .. && make -j4 ) || { echo "Could not perform test-build." ; exit 1 ; } -( cd build && make test ) || { echo "Tests failed." ; exit 1 ; } +### Build with default compiler +# +# +BUILDDIR=$(mktemp -d --suffix=-build --tmpdir=.) +rm -rf "$BUILDDIR" +mkdir "$BUILDDIR" || { echo "Could not create build directory." ; exit 1 ; } +( cd "$BUILDDIR" && cmake .. && make -j4 ) || { echo "Could not perform test-build." ; exit 1 ; } +( cd "$BUILDDIR" && make test ) || { echo "Tests failed." ; exit 1 ; } +### Build with clang +# +# if which clang++ > /dev/null 2>&1 ; then - # Do build again with clang - rm -rf build - mkdir build || { echo "Could not create build directory." ; exit 1 ; } - ( cd build && CC=clang CXX=clang++ cmake .. && make -j4 ) || { echo "Could not perform test-build." ; exit 1 ; } - ( cd build && make test ) || { echo "Tests failed." ; exit 1 ; } + # Do build again with clang + rm -rf "$BUILDDIR" + mkdir "$BUILDDIR" || { echo "Could not create build directory." ; exit 1 ; } + ( cd "$BUILDDIR" && CC=clang CXX=clang++ cmake .. && make -j4 ) || { echo "Could not perform test-build." ; exit 1 ; } + ( cd "$BUILDDIR" && make test ) || { echo "Tests failed." ; exit 1 ; } fi +### Get version number for this release +# +# +V=$( cd "$BUILDDIR" && make show-version | grep ^CALAMARES_VERSION | sed s/^[A-Z_]*=// ) +test -n "$V" || { echo "Could not obtain version." ; exit 1 ; } + +### Create signed tag +# +# This is the signing key ID associated with the GitHub account adriaandegroot, +# which is used to create all "verified" tags in the Calamares repo. +KEY_ID="128F00873E05AF1D" +git tag -u "$KEY_ID" "v$V" || { echo "Could not sign tag v$V." ; exit 1 ; } + +### Create the tarball +# +# +TAR_V="calamares-$V" +TAR_FILE="$TAR_V.tar.gz" +git archive -o "$TAR_FILE" --prefix "$TAR_V/" "v$V" || { echo "Could not create tarball." ; exit 1 ; } +test -f "$TAR_FILE" || { echo "Tarball was not created." ; exit 1 ; } +SHA256=$(sha256sum "$TAR_FILE" | cut -d" " -f1) + +### Build the tarball +# +# +D=$(date +%Y%m%d-%H%M%S) +TMPDIR=$(mktemp -d --suffix="-calamares-$D") +test -d "$TMPDIR" || { echo "Could not create tarball-build directory." ; exit 1 ; } +tar xzf "$TAR_FILE" -C "$TMPDIR" || { echo "Could not unpack tarball." ; exit 1 ; } +test -d "$TMPDIR/$TAR_V" || { echo "Tarball did not contain source directory." ; exit 1 ; } +( cd "$TMPDIR/$TAR_V" && cmake . && make -j4 && make test ) || { echo "Tarball build failed." ; exit 1 ; } + +### Cleanup +# +rm -rf "$BUILDDIR" # From test-builds +rm -rf "$TMPDIR" # From tarball + +### Print subsequent instructions +# +# +cat < Date: Thu, 28 Jun 2018 05:51:12 -0400 Subject: [PATCH 049/112] CMake: bump version - Set RC because this isn't near to a release yet --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a46b0d37d..183bc93f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,8 +74,8 @@ set( CALAMARES_DESCRIPTION_SUMMARY set( CALAMARES_VERSION_MAJOR 3 ) set( CALAMARES_VERSION_MINOR 2 ) -set( CALAMARES_VERSION_PATCH 1 ) -set( CALAMARES_VERSION_RC 0 ) +set( CALAMARES_VERSION_PATCH 2 ) +set( CALAMARES_VERSION_RC 1 ) ### Transifex (languages) info # From 6f39db4752c045bb9c929cbad738bde7209a22ab Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 28 Jun 2018 06:02:18 -0400 Subject: [PATCH 050/112] ci: name tags consistently --- ci/RELEASE.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/RELEASE.sh b/ci/RELEASE.sh index d3c960fd9..142d6b0c0 100644 --- a/ci/RELEASE.sh +++ b/ci/RELEASE.sh @@ -52,7 +52,7 @@ test -n "$V" || { echo "Could not obtain version." ; exit 1 ; } # This is the signing key ID associated with the GitHub account adriaandegroot, # which is used to create all "verified" tags in the Calamares repo. KEY_ID="128F00873E05AF1D" -git tag -u "$KEY_ID" "v$V" || { echo "Could not sign tag v$V." ; exit 1 ; } +git tag -u "$KEY_ID" -m "Release v$V" "v$V" || { echo "Could not sign tag v$V." ; exit 1 ; } ### Create the tarball # From f118fd73bce05f6ca38c1185b18b23f4a19458ce Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 28 Jun 2018 06:29:55 -0400 Subject: [PATCH 051/112] [calamares] More info when Cala is already running - If Calamares is already running, print some information about which instances there are so that it is possible to unstick them. --- src/calamares/main.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/calamares/main.cpp b/src/calamares/main.cpp index d4bd2743d..9893e6792 100644 --- a/src/calamares/main.cpp +++ b/src/calamares/main.cpp @@ -108,7 +108,14 @@ main( int argc, char* argv[] ) returnCode = a.exec(); } else + { + auto instancelist = guard.instances(); qDebug() << "Calamares is already running, shutting down."; + if ( instancelist.count() > 0 ) + qDebug() << "Other running Calamares instances:"; + for ( const auto& i : instancelist ) + qDebug() << " " << i.isValid() << i.pid() << i.arguments(); + } return returnCode; } From 3329f2ea5574a08241106eb40e9bc4fbcf933b82 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 29 Jun 2018 09:33:56 -0400 Subject: [PATCH 052/112] [calamares] Refactor searching for QML dir - Split collecting the search paths into separate function - Don't fall back on the current directory --- src/calamares/CalamaresApplication.cpp | 85 ++++++++++++-------------- 1 file changed, 40 insertions(+), 45 deletions(-) diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp index e41516c60..893e76c9b 100644 --- a/src/calamares/CalamaresApplication.cpp +++ b/src/calamares/CalamaresApplication.cpp @@ -133,60 +133,55 @@ CalamaresApplication::mainWindow() } +static QStringList +qmlDirCandidates( bool assumeBuilddir ) +{ + static const char QML[] = "qml"; + + QStringList qmlDirs; + if ( CalamaresUtils::isAppDataDirOverridden() ) + qmlDirs << CalamaresUtils::appDataDir().absoluteFilePath( QML ); + else + { + if ( assumeBuilddir ) + qmlDirs << QDir::current().absoluteFilePath( "src/qml" ); // In build-dir + qmlDirs << CalamaresUtils::appDataDir().absoluteFilePath( QML ); + } + + return qmlDirs; +} + + void CalamaresApplication::initQmlPath() { - QDir importPath; + QDir importPath; // Right now, current-dir + QStringList qmlDirCandidatesByPriority = qmlDirCandidates( isDebug() ); + bool found = false; - QString subpath( "qml" ); - - if ( CalamaresUtils::isAppDataDirOverridden() ) + foreach ( const QString& path, qmlDirCandidatesByPriority ) { - importPath = QDir( CalamaresUtils::appDataDir() - .absoluteFilePath( subpath ) ); - if ( !importPath.exists() || !importPath.isReadable() ) + QDir dir( path ); + if ( dir.exists() && dir.isReadable() ) { - cError() << "FATAL: explicitly configured application data directory" - << CalamaresUtils::appDataDir().absolutePath() - << "does not contain a valid QML modules directory at" - << importPath.absolutePath() - << "\nCowardly refusing to continue startup without the QML directory."; - ::exit( EXIT_FAILURE ); - } - } - else - { - QStringList qmlDirCandidatesByPriority; - if ( isDebug() ) - { - qmlDirCandidatesByPriority.append( - QDir::current().absoluteFilePath( - QString( "src/%1" ) - .arg( subpath ) ) ); - } - qmlDirCandidatesByPriority.append( CalamaresUtils::appDataDir() - .absoluteFilePath( subpath ) ); - - foreach ( const QString& path, qmlDirCandidatesByPriority ) - { - QDir dir( path ); - if ( dir.exists() && dir.isReadable() ) - { - importPath = dir; - break; - } - } - - if ( !importPath.exists() || !importPath.isReadable() ) - { - cError() << "FATAL: none of the expected QML paths (" - << qmlDirCandidatesByPriority.join( ", " ) - << ") exist." - << "\nCowardly refusing to continue startup without the QML directory."; - ::exit( EXIT_FAILURE ); + importPath = dir; + found = true; + break; } } + if ( !found || !importPath.exists() || !importPath.isReadable() ) + { + cError() << "Cowardly refusing to continue startup without a QML directory." + << Logger::DebugList( qmlDirCandidatesByPriority ); + if ( CalamaresUtils::isAppDataDirOverridden() ) + cError() << "FATAL: explicitly configured application data directory is missing qml/"; + else + cError() << "FATAL: none of the expected QML paths exist."; + ::exit( EXIT_FAILURE ); + } + + cDebug() << "Using Calamares QML directory" << importPath.absolutePath(); CalamaresUtils::setQmlModulesDir( importPath ); } From 22ee24a5ad8a39cdefab205ec3053eb42e147cb7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 29 Jun 2018 10:15:43 -0400 Subject: [PATCH 053/112] [calamares] Refactor searching for settings.conf - Split the collection of paths off from the search itself. --- src/calamares/CalamaresApplication.cpp | 78 +++++++++++++------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp index 893e76c9b..29e04cb67 100644 --- a/src/calamares/CalamaresApplication.cpp +++ b/src/calamares/CalamaresApplication.cpp @@ -152,6 +152,26 @@ qmlDirCandidates( bool assumeBuilddir ) } +static QStringList +settingsFileCandidates( bool assumeBuilddir ) +{ + static const char settings[] = "settings.conf"; + + QStringList settingsPaths; + if ( CalamaresUtils::isAppDataDirOverridden() ) + settingsPaths << CalamaresUtils::appDataDir().absoluteFilePath( settings ); + else + { + if ( assumeBuilddir ) + settingsPaths << QDir::current().absoluteFilePath( settings ); + settingsPaths << CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/settings.conf"; // String concat + settingsPaths << CalamaresUtils::appDataDir().absoluteFilePath( settings ); + } + + return settingsPaths; +} + + void CalamaresApplication::initQmlPath() { @@ -189,51 +209,31 @@ CalamaresApplication::initQmlPath() void CalamaresApplication::initSettings() { + QStringList settingsFileCandidatesByPriority = settingsFileCandidates( isDebug() ); + QFileInfo settingsFile; - if ( CalamaresUtils::isAppDataDirOverridden() ) + bool found = false; + + foreach ( const QString& path, settingsFileCandidatesByPriority ) { - settingsFile = QFileInfo( CalamaresUtils::appDataDir().absoluteFilePath( "settings.conf" ) ); - if ( !settingsFile.exists() || !settingsFile.isReadable() ) + QFileInfo pathFi( path ); + if ( pathFi.exists() && pathFi.isReadable() ) { - cError() << "FATAL: explicitly configured application data directory" - << CalamaresUtils::appDataDir().absolutePath() - << "does not contain a valid settings.conf file." - << "\nCowardly refusing to continue startup without settings."; - ::exit( EXIT_FAILURE ); + settingsFile = pathFi; + found = true; + break; } } - else + + if ( !found || !settingsFile.exists() || !settingsFile.isReadable() ) { - QStringList settingsFileCandidatesByPriority; - if ( isDebug() ) - { - settingsFileCandidatesByPriority.append( - QDir::currentPath() + - QDir::separator() + - "settings.conf" ); - } - settingsFileCandidatesByPriority.append( CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/settings.conf" ); - settingsFileCandidatesByPriority.append( CalamaresUtils::appDataDir() - .absoluteFilePath( "settings.conf" ) ); - - foreach ( const QString& path, settingsFileCandidatesByPriority ) - { - QFileInfo pathFi( path ); - if ( pathFi.exists() && pathFi.isReadable() ) - { - settingsFile = pathFi; - break; - } - } - - if ( !settingsFile.exists() || !settingsFile.isReadable() ) - { - cError() << "FATAL: none of the expected configuration file paths (" - << settingsFileCandidatesByPriority.join( ", " ) - << ") contain a valid settings.conf file." - << "\nCowardly refusing to continue startup without settings."; - ::exit( EXIT_FAILURE ); - } + cError() << "Cowardly refusing to continue startup without settings." + << Logger::DebugList( settingsFileCandidatesByPriority ); + if ( CalamaresUtils::isAppDataDirOverridden() ) + cError() << "FATAL: explicitly configured application data directory is missing settings.conf"; + else + cError() << "FATAL: none of the expected configuration file paths exist."; + ::exit( EXIT_FAILURE ); } new Calamares::Settings( settingsFile.absoluteFilePath(), isDebug(), this ); From b0e55c059a3bd1de32dfc83821b2cb9bb0dab820 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 29 Jun 2018 10:52:12 -0400 Subject: [PATCH 054/112] [calamares] Refactor searching for branding descriptor --- src/calamares/CalamaresApplication.cpp | 86 ++++++++++++-------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp index 29e04cb67..ef6c37912 100644 --- a/src/calamares/CalamaresApplication.cpp +++ b/src/calamares/CalamaresApplication.cpp @@ -172,6 +172,27 @@ settingsFileCandidates( bool assumeBuilddir ) } +static QStringList +brandingFileCandidates( bool assumeBuilddir, const QString& brandingFilename ) +{ + QStringList brandingPaths; + if ( CalamaresUtils::isAppDataDirOverridden() ) + brandingPaths << CalamaresUtils::appDataDir().absoluteFilePath( brandingFilename ); + else + { + if ( assumeBuilddir ) + { + brandingPaths << ( QDir::currentPath() + QStringLiteral( "/src/" ) + brandingFilename ); + brandingPaths << QDir( CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/" ) + .absoluteFilePath( brandingFilename ); + brandingPaths << CalamaresUtils::appDataDir().absoluteFilePath( brandingFilename); + } + } + + return brandingPaths; +} + + void CalamaresApplication::initQmlPath() { @@ -250,59 +271,32 @@ CalamaresApplication::initBranding() ::exit( EXIT_FAILURE ); } - QString brandingDescriptorSubpath = QString( "branding/%1/branding.desc" ) - .arg( brandingComponentName ); + QString brandingDescriptorSubpath = QString( "branding/%1/branding.desc" ).arg( brandingComponentName ); + QStringList brandingFileCandidatesByPriority = brandingFileCandidates( isDebug(), brandingDescriptorSubpath); QFileInfo brandingFile; - if ( CalamaresUtils::isAppDataDirOverridden() ) + bool found = false; + + foreach ( const QString& path, brandingFileCandidatesByPriority ) { - brandingFile = QFileInfo( CalamaresUtils::appDataDir() - .absoluteFilePath( brandingDescriptorSubpath ) ); - if ( !brandingFile.exists() || !brandingFile.isReadable() ) + QFileInfo pathFi( path ); + if ( pathFi.exists() && pathFi.isReadable() ) { - cError() << "FATAL: explicitly configured application data directory" - << CalamaresUtils::appDataDir().absolutePath() - << "does not contain a valid branding component descriptor at" - << brandingFile.absoluteFilePath() - << "\nCowardly refusing to continue startup without branding."; - ::exit( EXIT_FAILURE ); + brandingFile = pathFi; + found = true; + break; } } - else + + if ( !found || !brandingFile.exists() || !brandingFile.isReadable() ) { - QStringList brandingFileCandidatesByPriority; - if ( isDebug() ) - { - brandingFileCandidatesByPriority.append( - QDir::currentPath() + - QDir::separator() + - "src" + - QDir::separator() + - brandingDescriptorSubpath ); - } - brandingFileCandidatesByPriority.append( QDir( CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/" ) - .absoluteFilePath( brandingDescriptorSubpath ) ); - brandingFileCandidatesByPriority.append( CalamaresUtils::appDataDir() - .absoluteFilePath( brandingDescriptorSubpath ) ); - - foreach ( const QString& path, brandingFileCandidatesByPriority ) - { - QFileInfo pathFi( path ); - if ( pathFi.exists() && pathFi.isReadable() ) - { - brandingFile = pathFi; - break; - } - } - - if ( !brandingFile.exists() || !brandingFile.isReadable() ) - { - cError() << "FATAL: none of the expected branding descriptor file paths (" - << brandingFileCandidatesByPriority.join( ", " ) - << ") contain a valid branding.desc file." - << "\nCowardly refusing to continue startup without branding."; - ::exit( EXIT_FAILURE ); - } + cError() << "Cowardly refusing to continue startup without branding." + << Logger::DebugList( brandingFileCandidatesByPriority ); + if ( CalamaresUtils::isAppDataDirOverridden() ) + cError() << "FATAL: explicitly configured application data directory is missing" << brandingComponentName; + else + cError() << "FATAL: none of the expected branding descriptor file paths exist."; + ::exit( EXIT_FAILURE ); } new Calamares::Branding( brandingFile.absoluteFilePath(), this ); From f899bda81d151155376ed3b4b257d85500957aff Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 5 Jul 2018 12:01:44 +0200 Subject: [PATCH 055/112] [calamares] Restore missing search paths - Misplaced {} makes the branding search path empty - Reported by @apachelogger --- src/calamares/CalamaresApplication.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp index ef6c37912..018e2b677 100644 --- a/src/calamares/CalamaresApplication.cpp +++ b/src/calamares/CalamaresApplication.cpp @@ -181,12 +181,9 @@ brandingFileCandidates( bool assumeBuilddir, const QString& brandingFilename ) else { if ( assumeBuilddir ) - { brandingPaths << ( QDir::currentPath() + QStringLiteral( "/src/" ) + brandingFilename ); - brandingPaths << QDir( CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/" ) - .absoluteFilePath( brandingFilename ); - brandingPaths << CalamaresUtils::appDataDir().absoluteFilePath( brandingFilename); - } + brandingPaths << QDir( CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/" ).absoluteFilePath( brandingFilename ); + brandingPaths << CalamaresUtils::appDataDir().absoluteFilePath( brandingFilename); } return brandingPaths; From ae7700f2d735c99200bbbb5402e306576f02896c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 10 Jul 2018 04:12:24 -0400 Subject: [PATCH 056/112] [libcalamares] Refactor searching for module configurations - Similar to the refactorings in Calamares proper, just split out collecting the search paths into a static function. This makes it a little easier to find places that will need expansion for more-than-one-config-directory. --- src/libcalamaresui/modulesystem/Module.cpp | 53 ++++++++-------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/src/libcalamaresui/modulesystem/Module.cpp b/src/libcalamaresui/modulesystem/Module.cpp index ed1cb33ea..8d92c37ad 100644 --- a/src/libcalamaresui/modulesystem/Module.cpp +++ b/src/libcalamaresui/modulesystem/Module.cpp @@ -44,14 +44,6 @@ #include -// Example module.desc -/* ---- -type: "view" #job or view -name: "foo" #the module name. must be unique and same as the parent directory -interface: "qtplugin" #can be: qtplugin, python, process, ... -*/ - static const char EMERGENCY[] = "emergency"; namespace Calamares @@ -144,34 +136,29 @@ Module::fromDescriptor( const QVariantMap& moduleDescriptor, } +static QStringList +moduleConfigurationCandidates( bool assumeBuildDir, const QString& moduleName, const QString& configFileName ) +{ + QStringList paths; + + if ( CalamaresUtils::isAppDataDirOverridden() ) + paths << CalamaresUtils::appDataDir().absoluteFilePath( QString( "modules/%1" ).arg( configFileName ) ); + else + { + if ( assumeBuildDir ) + paths << QDir().absoluteFilePath(QString( "src/modules/%1/%2" ).arg( moduleName ).arg( configFileName ) ); + + paths << QString( "/etc/calamares/modules/%1" ).arg( configFileName ); + paths << CalamaresUtils::appDataDir().absoluteFilePath( QString( "modules/%1" ).arg( configFileName ) ); + } + + return paths; +} + void Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::Exception { - QStringList configFilesByPriority; - - if ( CalamaresUtils::isAppDataDirOverridden() ) - { - configFilesByPriority.append( - CalamaresUtils::appDataDir().absoluteFilePath( - QString( "modules/%1" ).arg( configFileName ) ) ); - } - else - { - if ( Settings::instance()->debugMode() ) - { - configFilesByPriority.append( - QDir( QDir::currentPath() ).absoluteFilePath( - QString( "src/modules/%1/%2" ).arg( m_name ).arg( configFileName ) ) ); - } - - configFilesByPriority.append( - QString( "/etc/calamares/modules/%1" ).arg( configFileName ) ); - configFilesByPriority.append( - CalamaresUtils::appDataDir().absoluteFilePath( - QString( "modules/%2" ).arg( configFileName ) ) ); - } - - foreach ( const QString& path, configFilesByPriority ) + foreach ( const QString& path, moduleConfigurationCandidates( Settings::instance()->debugMode(), m_name, configFileName ) ) { QFile configFile( path ); if ( configFile.exists() && configFile.open( QFile::ReadOnly | QFile::Text ) ) From b6f1960fc58352a4f60603b74314e69ea8815b75 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 6 Aug 2018 05:15:48 -0400 Subject: [PATCH 057/112] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_ca.ts | 16 +- lang/calamares_es.ts | 2 +- lang/calamares_es_MX.ts | 10 +- lang/calamares_he.ts | 445 ++++++++++++------------- lang/calamares_hi.ts | 707 ++++++++++++++++++++-------------------- lang/calamares_is.ts | 8 +- lang/calamares_it_IT.ts | 10 +- lang/calamares_ja.ts | 16 +- lang/calamares_ko.ts | 46 +-- lang/calamares_pt_BR.ts | 20 +- lang/calamares_ru.ts | 14 +- lang/calamares_uk.ts | 11 +- 12 files changed, 656 insertions(+), 649 deletions(-) diff --git a/lang/calamares_ca.ts b/lang/calamares_ca.ts index a43d01432..1a6f2b11c 100644 --- a/lang/calamares_ca.ts +++ b/lang/calamares_ca.ts @@ -579,7 +579,7 @@ L'instal·lador es tancarà i tots els canvis es perdran. En&crypt - &Xifra + En&cripta @@ -788,7 +788,7 @@ L'instal·lador es tancarà i tots els canvis es perdran. Skip writing LUKS configuration for Dracut: "/" partition is not encrypted - Omet l'escriptura de la configuració de LUKS per a Dracut: la partició "/" no està xifrada + Omet l'escriptura de la configuració de LUKS per a Dracut: la partició "/" no està encriptada @@ -872,7 +872,7 @@ L'instal·lador es tancarà i tots els canvis es perdran. En&crypt system - &Xifra el sistema + En&cripta el sistema @@ -948,7 +948,7 @@ L'instal·lador es tancarà i tots els canvis es perdran. <h1>All done.</h1><br/>%1 has been installed on your computer.<br/>You may now restart into your new system, or continue using the %2 Live environment. - <h1>Tot fet.</h1><br/>%1 s'ha instal·lat al vostre ordinador.<br/>Ara podeu reiniciar-lo per tal d'accedir al sistema operatiu nou o bé continuar utilitzant l'entorn autònom de %2. + <h1>Tot fet.</h1><br/>%1 s'ha instal·lat a l'ordinador.<br/>Ara podeu reiniciar-lo per tal d'accedir al sistema operatiu nou o bé continuar utilitzant l'entorn autònom de %2. @@ -1786,7 +1786,7 @@ L'instal·lador es tancarà i tots els canvis es perdran. Boot partition not encrypted - Partició d'arrencada sense xifrar + Partició d'arrencada sense encriptar @@ -1839,7 +1839,7 @@ L'instal·lador es tancarà i tots els canvis es perdran. Saving files for later ... - Desament dels fitxers per a més tard... + Desament de fitxers per a més tard... @@ -2528,7 +2528,7 @@ Sortida: Your hostname contains invalid characters. Only letters, numbers and dashes are allowed. - El nom d'amfitrió conté caràcters no vàlids. Només s'admeten lletres, números i guions. + El nom d'amfitrió conté caràcters no vàlids. Només s'hi admeten lletres, números i guions. @@ -2585,7 +2585,7 @@ Sortida: <h1>Welcome to the Calamares installer for %1.</h1> - <h1>Benvingut a l'instal·lador Calamares per a %1.</h1> + <h1>Us donem la benvinguda a l'instal·lador Calamares per a %1.</h1> diff --git a/lang/calamares_es.ts b/lang/calamares_es.ts index 88ce4eae7..c07481a92 100644 --- a/lang/calamares_es.ts +++ b/lang/calamares_es.ts @@ -51,7 +51,7 @@ Para configurar el arranque desde un entorno BIOS, este instalador debe instalar Blank Page - + Página Blanca diff --git a/lang/calamares_es_MX.ts b/lang/calamares_es_MX.ts index 2ecc8f5a7..ca8bd81f6 100644 --- a/lang/calamares_es_MX.ts +++ b/lang/calamares_es_MX.ts @@ -50,7 +50,7 @@ Blank Page - + Página en blanco @@ -192,17 +192,17 @@ Calamares Initialization Failed - + La inicialización de Calamares ha fallado %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + %1 no pudo ser instalado. Calamares no pudo cargar todos los módulos configurados. Este es un problema con la forma en que Calamares esta siendo usada por la distribución. <br/>The following modules could not be loaded: - + <br/>Los siguientes módulos no pudieron ser cargados: @@ -1664,7 +1664,7 @@ El instalador terminará y se perderán todos los cambios. Cre&ate - + Cre&ar diff --git a/lang/calamares_he.ts b/lang/calamares_he.ts index dd9ae1af8..13edcfac2 100644 --- a/lang/calamares_he.ts +++ b/lang/calamares_he.ts @@ -4,17 +4,17 @@ The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. - <strong>תצורת האתחול</strong> של מערכת זו. <br><br> מערכות x86 ישנות יותר תומכות אך ורק ב <strong>BIOS</strong>.<br> מערכות חדשות משתמשות בדרך כלל ב <strong>EFI</strong>, אך יכולות להיות מוצגות כ BIOS במידה והן מופעלות במצב תאימות לאחור. + <strong>תצורת האתחול</strong> של מערכת זו. <br><br> מערכות x86 ישנות יותר תומכות אך ורק ב <strong>BIOS</strong>.<br> מערכות חדשות משתמשות בדרך כלל ב־<strong>EFI</strong>, אך עשוית להופיע כ־BIOS אם הן מופעלות במצב תאימות לאחור. This system was started with an <strong>EFI</strong> boot environment.<br><br>To configure startup from an EFI environment, this installer must deploy a boot loader application, like <strong>GRUB</strong> or <strong>systemd-boot</strong> on an <strong>EFI System Partition</strong>. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own. - מערכת זו הופעלה בתצורת אתחול <strong>EFI</strong>.<br><br> בכדי להגדיר הפעלה מתצורת אתחול EFI, על אשף ההתקנה להתקין מנהל אתחול מערכת, לדוגמה <strong>GRUB</strong> או <strong>systemd-boot</strong> על <strong>מחיצת מערכת EFI</strong>. פעולה זו היא אוטומטית, אלא אם כן תבחר להגדיר מחיצות באופן ידני, במקרה זה עליך לבחור זאת או להגדיר בעצמך. + מערכת זו הופעלה בתצורת אתחול <strong>EFI</strong>.<br><br> כדי להגדיר הפעלה מתצורת אתחול EFI, על אשף ההתקנה להתקין מנהל אתחול מערכת, לדוגמה <strong>GRUB</strong> או <strong>systemd-boot</strong> על <strong>מחיצת מערכת EFI</strong>. פעולה זו היא אוטומטית, אלא אם כן העדפתך היא להגדיר מחיצות באופן ידני, במקרה זה עליך לבחור זאת או להגדיר בעצמך. This system was started with a <strong>BIOS</strong> boot environment.<br><br>To configure startup from a BIOS environment, this installer must install a boot loader, like <strong>GRUB</strong>, either at the beginning of a partition or on the <strong>Master Boot Record</strong> near the beginning of the partition table (preferred). This is automatic, unless you choose manual partitioning, in which case you must set it up on your own. - מערכת זו הופעלה בתצורת אתחול <strong>BIOS</strong>.<br><br> בכדי להגדיר הפעלה מתצורת אתחול BIOS, על אשף ההתקנה להתקין מנהל אתחול מערכת, לדוגמה <strong>GRUB</strong>, בתחלית מחיצה או על ה <strong>Master Boot Record</strong> בצמוד להתחלה של טבלת המחיצות (מועדף). פעולה זו היא אוטומטית, אלא אם כן תבחר להגדיר מחיצות באופן ידני, במקרה זה עליך להגדיר זאת בעצמך. + מערכת זו הופעלה בתצורת אתחול <strong>BIOS</strong>.<br><br> כדי להגדיר הפעלה מתצורת אתחול BIOS, על אשף ההתקנה להתקין מנהל אתחול מערכת, לדוגמה <strong>GRUB</strong>, בתחילת המחיצה או על ה־<strong>Master Boot Record</strong> בצמוד להתחלה של טבלת המחיצות (מועדף). פעולה זו היא אוטומטית, אלא אם כן תבחר להגדיר מחיצות באופן ידני, במקרה זה עליך להגדיר זאת בעצמך. @@ -37,7 +37,7 @@ Do not install a boot loader - אל תתקין מנהל אתחול מערכת, boot loader + לא להתקין מנהל אתחול מערכת @@ -50,7 +50,7 @@ Blank Page - + עמוד ריק @@ -107,7 +107,7 @@ Install - התקן + התקנה @@ -115,7 +115,7 @@ Done - בוצע + הסתיים @@ -123,12 +123,12 @@ Run command %1 %2 - הרץ פקודה %1 %2 + הרצת הפקודה %1 %2 Running command %1 %2 - מריץ פקודה %1 %2 + הפקודה %1 %2 רצה @@ -136,17 +136,17 @@ Running %1 operation. - מריץ פעולה %1. + הפעולה %1 רצה. Bad working directory path - נתיב תיקיית עבודה לא תקין + נתיב תיקיית עבודה שגוי Working directory %1 for python job %2 is not readable. - תיקיית עבודה %1 עבור משימת python %2 לא קריאה. + תיקיית העבודה %1 עבור משימת python‏ %2 אינה קריאה. @@ -161,7 +161,7 @@ Boost.Python error in job "%1". - שגיאת Boost.Python במשימה "%1". + שגיאת Boost.Python במשימה „%1”. @@ -169,56 +169,56 @@ &Back - &קודם + ה&קודם &Next - &הבא + הב&א &Cancel - &בטל + &ביטול Cancel installation without changing the system. - בטל התקנה ללא ביצוע שינוי במערכת. + ביטול התקנה ללא ביצוע שינוי במערכת. Calamares Initialization Failed - + הפעלת Calamares נכשלה %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + אין אפשרות להתקין את %1. ל־Calamares אין אפשרות לטעון את המודולים המוגדרים. מדובר בתקלה באופן בו ההפצה משתמשת ב־Calamares. <br/>The following modules could not be loaded: - + <br/>לא ניתן לטעון את המודולים הבאים: &Install - + הת&קנה Cancel installation? - בטל את ההתקנה? + לבטל את ההתקנה? Do you really want to cancel the current install process? The installer will quit and all changes will be lost. - האם אתה בטוח שברצונך לבטל את תהליך ההתקנה? + לבטל את תהליך ההתקנה? אשף ההתקנה ייסגר וכל השינויים יאבדו. @@ -234,12 +234,12 @@ The installer will quit and all changes will be lost. &Close - &סגור + &סגירה Continue with setup? - המשך עם הליך ההתקנה? + להמשיך בהתקנה? @@ -249,22 +249,22 @@ The installer will quit and all changes will be lost. &Install now - &התקן כעת + להת&קין כעת Go &back - &אחורה + ח&זרה &Done - &בוצע + &סיום The installation is complete. Close the installer. - תהליך ההתקנה הושלם. אנא סגור את אשף ההתקנה. + תהליך ההתקנה הושלם. נא לסגור את אשף ההתקנה. @@ -310,7 +310,7 @@ The installer will quit and all changes will be lost. Show debug information - הצג מידע על ניפוי שגיאות + הצגת מידע ניפוי שגיאות @@ -323,17 +323,17 @@ The installer will quit and all changes will be lost. This computer does not satisfy some of the recommended requirements for installing %1.<br/>Installation can continue, but some features might be disabled. - המחשב לא עומד בחלק מרף דרישות המינימום להתקנת %1.<br/> ההתקנה יכולה להמשיך, אך חלק מהתכונות יכולות להיות מבוטלות. + המחשב לא עומד בחלק מרף דרישות המינימום להתקנת %1.<br/> ההתקנה יכולה להמשיך, אך יתכן כי חלק מהתכונות יושבתו. This program will ask you some questions and set up %2 on your computer. - אשף התקנה זה נכתב בלשון זכר אך מיועד לשני המינים. תוכנה זו תשאל אותך מספר שאלות ותגדיר את %2 על המחשב שלך. + תכנית זו תשאל אותך מספר שאלות ותתקין את %2 על המחשב שלך. For best results, please ensure that this computer: - לקבלת התוצאות הטובות ביותר, אנא וודא כי מחשב זה: + לקבלת התוצאות הטובות ביותר, נא לוודא כי מחשב זה: @@ -356,7 +356,7 @@ The installer will quit and all changes will be lost. <strong>Manual partitioning</strong><br/>You can create or resize partitions yourself. - <strong>הגדרת מחיצות באופן ידני</strong><br/>תוכל ליצור או לשנות את גודל המחיצות בעצמך. + <strong>הגדרת מחיצות באופן ידני</strong><br/>ניתן ליצור או לשנות את גודל המחיצות בעצמך. @@ -366,12 +366,12 @@ The installer will quit and all changes will be lost. %1 will be shrunk to %2MB and a new %3MB partition will be created for %4. - %1 תוקטן ל %2 MB ומחיצה חדשה בגודל %3 MB תיווצר עבור %4. + %1 תוקטן לכדי %2 מ״ב ותיווצר מחיצה חדשה בגודל %3 מ״ב עבור %4. Select storage de&vice: - בחר ה&תקן אחסון: + בחירת התקן א&חסון: @@ -384,27 +384,27 @@ The installer will quit and all changes will be lost. Reuse %1 as home partition for %2. - השתמש ב %1 כמחיצת הבית, home, עבור %2. + להשתמש ב־%1 כמחיצת הבית (home) עבור %2. <strong>Select a partition to shrink, then drag the bottom bar to resize</strong> - <strong>בחר מחיצה לכיווץ, לאחר מכן גרור את הסרגל התחתון בכדי לשנות את גודלה</strong> + <strong>ראשית יש לבחור מחיצה לכיווץ, לאחר מכן לגרור את הסרגל התחתון כדי לשנות את גודלה</strong> <strong>Select a partition to install on</strong> - <strong>בחר מחיצה בכדי לבצע את ההתקנה עליה</strong> + <strong>נא לבחור מחיצה כדי להתקין עליה</strong> An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. - מחיצת מערכת EFI לא נמצאה במערכת. אנא חזור והשתמש ביצירת מחיצות באופן ידני בכדי להגדיר את %1. + במערכת זו לא נמצאה מחיצת מערכת EFI. נא לחזור ולהשתמש ביצירת מחיצות באופן ידני כדי להגדיר את %1. The EFI system partition at %1 will be used for starting %2. - מחיצת מערכת EFI ב %1 תשמש עבור טעינת %2. + מחיצת מערכת ה־EFI שב־%1 תשמש עבור טעינת %2. @@ -414,7 +414,7 @@ The installer will quit and all changes will be lost. This storage device does not seem to have an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - לא נמצאה מערכת הפעלה על התקן אחסון זה. מה ברצונך לעשות?<br/> תוכל לסקור ולאשר את בחירתך לפני ששינויים יתבצעו על התקן האחסון. + לא נמצאה מערכת הפעלה על התקן אחסון זה. מה ברצונך לעשות?<br/> ניתן לסקור ולאשר את בחירתך לפני ששינויים יתבצעו על התקן האחסון. @@ -422,12 +422,12 @@ The installer will quit and all changes will be lost. <strong>Erase disk</strong><br/>This will <font color="red">delete</font> all data currently present on the selected storage device. - <strong>מחק כונן</strong><br/> פעולה זו <font color="red">תמחק</font> את כל המידע השמור על התקן האחסון הנבחר. + <strong>מחיקת כונן</strong><br/> פעולה זו <font color="red">תמחק</font> את כל המידע השמור על התקן האחסון הנבחר. This storage device has %1 on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - נמצא %1 על התקן אחסון זה. מה ברצונך לעשות?<br/> תוכל לסקור ולאשר את בחירתך לפני ששינויים יתבצעו על התקן האחסון. + בהתקן אחסון זה נמצאה %1. מה ברצונך לעשות?<br/> ניתן לסקור ולאשר את בחירתך לפני ששינויים יתבצעו על התקן האחסון. @@ -435,7 +435,7 @@ The installer will quit and all changes will be lost. <strong>Install alongside</strong><br/>The installer will shrink a partition to make room for %1. - <strong>התקן לצד</strong><br/> אשף ההתקנה יכווץ מחיצה בכדי לפנות מקום עבור %1. + <strong>התקנה לצד</strong><br/> אשף ההתקנה יכווץ מחיצה כדי לפנות מקום לטובת %1. @@ -443,17 +443,17 @@ The installer will quit and all changes will be lost. <strong>Replace a partition</strong><br/>Replaces a partition with %1. - <strong>החלף מחיצה</strong><br/> מבצע החלפה של המחיצה עם %1. + <strong>החלפת מחיצה</strong><br/> ביצוע החלפה של המחיצה ב־%1. This storage device already has an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - מערכת הפעלה קיימת על התקן האחסון הזה. מה ברצונך לעשות?<br/> תוכל לסקור ולאשר את בחירתך לפני ששינויים יתבצעו על התקן האחסון. + כבר קיימת מערכת הפעלה על התקן האחסון הזה. כיצד להמשיך?<br/> ניתן לסקור ולאשר את בחירתך לפני ששינויים יתבצעו על התקן האחסון. This storage device has multiple operating systems on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - מערכות הפעלה מרובות קיימות על התקן אחסון זה. מה ברצונך לעשות? <br/>תוכל לסקור ולאשר את בחירתך לפני ששינויים יתבצעו על התקן האחסון. + ישנן מגוון מערכות הפעלה על התקן אחסון זה. איך להמשיך? <br/>ניתן לסקור ולאשר את בחירתך לפני ששינויים יתבצעו על התקן האחסון. @@ -461,17 +461,17 @@ The installer will quit and all changes will be lost. Clear mounts for partitioning operations on %1 - מחק נקודות עיגון עבור ביצוע פעולות של הגדרות מחיצה על %1. + מחיקת נקודות עיגון עבור פעולות חלוקה למחיצות על %1. Clearing mounts for partitioning operations on %1. - מבצע מחיקה של נקודות עיגון עבור ביצוע פעולות של הגדרות מחיצה על %1. + מתבצעת מחיקה של נקודות עיגון לטובת פעולות חלוקה למחיצות על %1. Cleared all mounts for %1 - בוצעה מחיקה עבור כל נקודות העיגון על %1. + כל נקודות העיגון על %1 נמחקו. @@ -479,7 +479,7 @@ The installer will quit and all changes will be lost. Clear all temporary mounts. - מחק את כל נקודות העיגון הזמניות. + מחיקת כל נקודות העיגון הזמניות. @@ -503,17 +503,17 @@ The installer will quit and all changes will be lost. Could not run command. - + לא ניתן להריץ את הפקודה. The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined. - + הפקודה פועלת בסביבת המארח ועליה לדעת מה נתיב השורש, אך לא צוין rootMountPoint. The command needs to know the user's name, but no username is defined. - + הפקודה צריכה לדעת מה שם המשתמש, אך לא הוגדר שם משתמש. @@ -529,7 +529,7 @@ The installer will quit and all changes will be lost. Create a Partition - צור מחיצה + יצירת מחיצה @@ -559,7 +559,7 @@ The installer will quit and all changes will be lost. LVM LV name - + שם כרך לוגי במנהל הכרכים הלוגיים @@ -579,7 +579,7 @@ The installer will quit and all changes will be lost. En&crypt - ה&צפן + ה&צפנה @@ -599,7 +599,7 @@ The installer will quit and all changes will be lost. Mountpoint already in use. Please select another one. - נקודת העיגון בשימוש. אנא בחר נקודת עיגון אחרת. + נקודת העיגון בשימוש. נא לבחור בנקודת עיגון אחרת. @@ -607,7 +607,7 @@ The installer will quit and all changes will be lost. Create new %2MB partition on %4 (%3) with file system %1. - צור מחיצה חדשה בגודל %2 MB על %4 (%3) עם מערכת קבצים %1. + יצירת מחיצה חדשה בגודל של %2 מ״ב על גבי %4 (%3) עם מערכת הקבצים %1. @@ -617,12 +617,12 @@ The installer will quit and all changes will be lost. Creating new %1 partition on %2. - מגדיר מחיצה %1 חדשה על %2. + מוגדרת מחיצת %1 חדשה על %2. The installer failed to create partition on disk '%1'. - אשף ההתקנה נכשל ביצירת מחיצה על כונן '%1'. + אשף ההתקנה נכשל ביצירת מחיצה על הכונן ‚%1’. @@ -630,7 +630,7 @@ The installer will quit and all changes will be lost. Create Partition Table - צור טבלת מחיצות + יצירת טבלת מחיצות @@ -658,17 +658,17 @@ The installer will quit and all changes will be lost. Create new %1 partition table on %2. - צור טבלת מחיצות %1 חדשה על %2. + יצירת טבלת מחיצות חדשה מסוג %1 על %2. Create new <strong>%1</strong> partition table on <strong>%2</strong> (%3). - צור טבלת מחיצות <strong>%1</strong> חדשה על <strong>%2</strong> (%3). + יצירת טבלת מחיצות חדשה מסוג <strong>%1</strong> על <strong>%2</strong> (%3). Creating new %1 partition table on %2. - יוצר טבלת מחיצות %1 חדשה על %2. + נוצרת טבלת מחיצות חדשה מסוג %1 על %2. @@ -681,17 +681,17 @@ The installer will quit and all changes will be lost. Create user %1 - צור משתמש %1 + יצירת משתמש %1 Create user <strong>%1</strong>. - צור משתמש <strong>%1</strong>. + יצירת משתמש <strong>%1</strong>. Creating user %1. - יוצר משתמש %1. + נוצר משתמש %1. @@ -719,7 +719,7 @@ The installer will quit and all changes will be lost. Delete partition %1. - מחק את מחיצה %1. + מחיקת המחיצה %1. @@ -793,7 +793,7 @@ The installer will quit and all changes will be lost. Failed to open %1 - נכשלה פתיחת %1. + הפתיחה של %1 נכשלה. @@ -801,7 +801,7 @@ The installer will quit and all changes will be lost. Dummy C++ Job - משימת דמה של C++ + משימת דמה של C++‎ @@ -809,17 +809,17 @@ The installer will quit and all changes will be lost. Edit Existing Partition - ערוך מחיצה קיימת + עריכת מחיצה קיימת Content: - תכולה: + תוכן: &Keep - &השאר + לה&שאיר @@ -859,7 +859,7 @@ The installer will quit and all changes will be lost. Mountpoint already in use. Please select another one. - נקודת העיגון בשימוש. אנא בחר נקודת עיגון אחרת. + נקודת העיגון בשימוש. נא לבחור בנקודת עיגון אחרת. @@ -872,22 +872,22 @@ The installer will quit and all changes will be lost. En&crypt system - ה&צפן את המערכת + ה&צפנת המערכת Passphrase - ביטוי אבטחה + מילת צופן Confirm passphrase - אשר ביטוי אבטחה + אישור מילת צופן Please enter the same passphrase in both boxes. - אנא הכנס ביטוי אבטחה זהה בשני התאים. + נא להקליד את אותה מילת הצופן בשתי התיבות. @@ -895,37 +895,37 @@ The installer will quit and all changes will be lost. Set partition information - הגדר מידע עבור המחיצה + הגדרת מידע עבור המחיצה Install %1 on <strong>new</strong> %2 system partition. - התקן %1 על מחיצת מערכת %2 <strong>חדשה</strong>. + התקנת %1 על מחיצת מערכת <strong>חדשה</strong> מסוג %2. Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong>. - הגדר מחיצת מערכת %2 <strong>חדשה</strong>בעלת נקודת עיגון <strong>%1</strong>. + הגדרת מחיצת מערכת <strong>חדשה</strong> מסוג %2 עם נקודת העיגון <strong>%1</strong>. Install %2 on %3 system partition <strong>%1</strong>. - התקן %2 על מחיצת מערכת %3 <strong>%1</strong>. + התקנת %2 על מחיצת מערכת <strong>%1</strong> מסוג %3. Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong>. - התקן מחיצה %3 <strong>%1</strong> עם נקודת עיגון <strong>%2</strong>. + התקן מחיצה מסוג %3 <strong>%1</strong> עם נקודת העיגון <strong>%2</strong>. Install boot loader on <strong>%1</strong>. - התקן מנהל אתחול מערכת על <strong>%1</strong>. + התקנת מנהל אתחול מערכת על <strong>%1</strong>. Setting up mount points. - מגדיר נקודות עיגון. + נקודות עיגון מוגדרות. @@ -938,12 +938,12 @@ The installer will quit and all changes will be lost. <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style=" font-style:italic;">Done</span> or close the installer.</p></body></html> - + <html><head/><body><p>כאשר תיבה זו מסומנת, המערכת שלך תופעל מחדש מיידית עם הלחיצה על <span style=" font-style:italic;">סיום</span> או עם סגירת תכנית ההתקנה.</p></body></html> &Restart now - &אתחל כעת + ה&פעלה מחדש כעת @@ -979,7 +979,7 @@ The installer will quit and all changes will be lost. Format partition %1 (file system: %2, size: %3 MB) on %4. - אתחל מחיצה %1 (מערכת קבצים: %2, גודל: %3 MB) על %4. + אתחל מחיצה %1 (מערכת קבצים: %2, גודל: %3 מ״ב) על %4. @@ -1077,17 +1077,17 @@ The installer will quit and all changes will be lost. I accept the terms and conditions above. - אני מאשר את התנאים וההתניות מעלה. + התנאים וההגבלות שלמעלה מקובלים עלי. <h1>License Agreement</h1>This setup procedure will install proprietary software that is subject to licensing terms. - <h1>הסכם רישיון</h1>אשף התקנה זה יבצע התקנה של תוכנות קנייניות אשר כפופות לתנאי רישיון. + <h1>הסכם רישיון</h1>אשף התקנה זה יבצע התקנה של תכניות קנייניות אשר כפופות לתנאי רישיון. Please review the End User License Agreements (EULAs) above.<br/>If you do not agree with the terms, the setup procedure cannot continue. - אנא סקור את הסכם משתמש הקצה (EULA) מעלה.<br/> במידה ואינך מסכים עם התנאים, תהליך ההתקנה יופסק. + נא לעיין בהסכם משתמש הקצה (EULA) מעלה.<br/> אם התנאים אינם מקובלים עליך, תהליך ההתקנה יופסק. @@ -1134,7 +1134,7 @@ The installer will quit and all changes will be lost. <a href="%1">view license agreement</a> - <a href="%1">צפה בהסכם הרשיון</a> + <a href="%1">הצגת הסכם הרישיון</a> @@ -1142,7 +1142,7 @@ The installer will quit and all changes will be lost. License - רשיון + רישיון @@ -1171,7 +1171,7 @@ The installer will quit and all changes will be lost. &Change... - &החלף... + ה&חלפה… @@ -1190,7 +1190,7 @@ The installer will quit and all changes will be lost. Loading location data... - טוען נתונים על המיקום... + הנתונים על המיקום נטענים… @@ -1213,12 +1213,12 @@ The installer will quit and all changes will be lost. Network Installation. (Disabled: Unable to fetch package lists, check your network connection) - התקנת רשת. (מנוטרלת: לא ניתן לאחזר רשימות של חבילות תוכנה, אנא בדוק את חיבורי הרשת) + התקנה מהרשת. (מושבתת: לא ניתן לקבל רשימות של חבילות תכנה, נא לבדוק את החיבור לרשת) Network Installation. (Disabled: Received invalid groups data) - התקנה מהרשת. (מנוטרל: התקבל מידע שגוי בנושא הקבוצות) + התקנה מהרשת. (מושבתת: המידע שהתקבל על קבוצות שגוי) @@ -1234,242 +1234,242 @@ The installer will quit and all changes will be lost. Password is too short - הסיסמה קצרה מדי + הססמה קצרה מדי Password is too long - הסיסמה ארוכה מדי + הססמה ארוכה מדי Password is too weak - + הססמה חלשה מדי Memory allocation error when setting '%1' - + שגיאת הקצאת זיכרון בעת הגדרת ‚%1’ Memory allocation error - + שגיאת הקצאת זיכרון The password is the same as the old one - + הססמה זהה לישנה The password is a palindrome - + הססמה היא פלינדרום The password differs with case changes only - + מורכבות הססמה טמונה בשינויי סוגי אותיות בלבד The password is too similar to the old one - + הססמה דומה מדי לישנה The password contains the user name in some form - + הססמה מכילה את שם המשתמש בצורה כלשהי The password contains words from the real name of the user in some form - + הססמה מכילה מילים מהשם האמתי של המשתמש בצורה זו או אחרת The password contains forbidden words in some form - + הססמה מכילה מילים אסורות בצורה כלשהי The password contains less than %1 digits - + הססמה מכילה פחות מ־%1 ספרות The password contains too few digits - + הססמה לא מכילה מספיק ספרות The password contains less than %1 uppercase letters - + הססמה מכילה פחות מ־%1 אותיות גדולות The password contains too few uppercase letters - + הססמה מכילה מעט מדי אותיות גדולות The password contains less than %1 lowercase letters - + הססמה מכילה פחות מ־%1 אותיות קטנות The password contains too few lowercase letters - + הססמה אינה מכילה מספיק אותיות קטנות The password contains less than %1 non-alphanumeric characters - + הססמה מכילה פחות מ־%1 תווים שאינם אלפאנומריים The password contains too few non-alphanumeric characters - + הססמה מכילה מעט מדי תווים שאינם אלפאנומריים The password is shorter than %1 characters - + אורך הססמה קצר מ־%1 תווים The password is too short - + הססמה קצרה מדי The password is just rotated old one - + הססמה היא פשוט סיכול של ססמה קודמת The password contains less than %1 character classes - + הססמה מכילה פחות מ־%1 סוגי תווים The password does not contain enough character classes - + הססמה לא מכילה מספיק סוגי תווים The password contains more than %1 same characters consecutively - + הססמה מכילה יותר מ־%1 תווים זהים ברצף The password contains too many same characters consecutively - + הססמה מכילה יותר מדי תווים זהים ברצף The password contains more than %1 characters of the same class consecutively - + הססמה מעילה יותר מ־%1 תווים מאותו הסוג ברצף The password contains too many characters of the same class consecutively - + הססמה מכילה יותר מדי תווים מאותו הסוג ברצף The password contains monotonic sequence longer than %1 characters - + הססמה מכילה רצף תווים מונוטוני של יותר מ־%1 תווים The password contains too long of a monotonic character sequence - + הססמה מכילה רצף תווים מונוטוני ארוך מדי No password supplied - + לא צוינה ססמה Cannot obtain random numbers from the RNG device - + לא ניתן לקבל מספרים אקראיים מהתקן ה־RNG Password generation failed - required entropy too low for settings - + יצירת הססמה נכשלה - רמת האקראיות הנדרשת נמוכה ביחס להגדרות The password fails the dictionary check - %1 - + הססמה נכשלה במבחן המילון - %1 The password fails the dictionary check - + הססמה נכשלה במבחן המילון Unknown setting - %1 - + הגדרה לא מוכרת - %1 Unknown setting - + הגדרה לא מוכרת Bad integer value of setting - %1 - + ערך מספרי שגוי להגדרה - %1 Bad integer value - + ערך מספרי שגוי Setting %1 is not of integer type - + ההגדרה %1 אינה מסוג מספר שלם Setting is not of integer type - + ההגדרה אינה מסוג מספר שלם Setting %1 is not of string type - + ההגדרה %1 אינה מסוג מחרוזת Setting is not of string type - + ההגדרה אינה מסוג מחרוזת Opening the configuration file failed - + פתיחת קובץ התצורה נכשלה The configuration file is malformed - + קובץ התצורה פגום Fatal failure - + כשל מכריע Unknown error - + שגיאה לא ידועה @@ -1487,7 +1487,7 @@ The installer will quit and all changes will be lost. Type here to test your keyboard - הקלד כאן בכדי לבדוק את המקלדת שלך + ניתן להקליד כאן כדי לבדוק את המקלדת שלך @@ -1500,19 +1500,19 @@ The installer will quit and all changes will be lost. What is your name? - מהו שמך? + מה שמך? What name do you want to use to log in? - באיזה שם ברצונך להשתמש בעת כניסה למחשב? + איזה שם ברצונך שישמש אותך לכניסה? font-weight: normal - משקל-גופן: נורמלי + font-weight: normal @@ -1522,42 +1522,42 @@ The installer will quit and all changes will be lost. Choose a password to keep your account safe. - בחר סיסמה בכדי להגן על חשבונך. + נא לבחור ססמה להגנה על חשבונך. <small>Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals.</small> - <small>הכנס את אותה הסיסמה פעמיים, בכדי שניתן יהיה לבדוק שגיאות הקלדה. סיסמה טובה אמורה להכיל שילוב של אותיות, מספרים וסימני פיסוק, להיות באורך שמונה תווים לפחות, ועליה להשתנות במרווחי זמן קבועים.</small> + <small>יש להקליד את אותה הססמה פעמיים כדי שניתן יהיה לבדוק שגיאות הקלדה. ססמה טובה אמורה להכיל שילוב של אותיות, מספרים וסימני פיסוק, להיות באורך של שמונה תווים לפחות ויש להחליף אותה במרווחי זמן קבועים.</small> What is the name of this computer? - מהו שם מחשב זה? + מהו השם של המחשב הזה? <small>This name will be used if you make the computer visible to others on a network.</small> - <small>שם זה יהיה בשימוש במידה ומחשב זה יוגדר להיות נראה על ידי עמדות אחרות ברשת.</small> + <small>בשם זה ייעשה שימוש לטובת זיהוי מול מחשבים אחרים ברשת במידת הצורך.</small> Log in automatically without asking for the password. - התחבר באופן אוטומטי מבלי לבקש סיסמה. + כניסה אוטומטית מבלי לבקש ססמה. Use the same password for the administrator account. - השתמש באותה הסיסמה עבור חשבון המנהל. + להשתמש באותה הססמה עבור חשבון המנהל. Choose a password for the administrator account. - בחר סיסמה עבור חשבון המנהל. + בחירת ססמה עבור חשבון המנהל. <small>Enter the same password twice, so that it can be checked for typing errors.</small> - <small>הכנס את אותה הסיסמה פעמיים, בכדי שניתן יהיה לבדוק שגיאות הקלדה.</small> + <small>עליך להקליד את אותה הססמה פעמיים כדי לאפשר זיהוי של שגיאות הקלדה.</small> @@ -1648,12 +1648,12 @@ The installer will quit and all changes will be lost. Storage de&vice: - &התקן זכרון: + ה&תקן זיכרון: &Revert All Changes - &בטל את כל השינויים + &ביטול כל השינויים @@ -1663,37 +1663,37 @@ The installer will quit and all changes will be lost. Cre&ate - + י&צירה &Edit - &ערוך + &עריכה &Delete - &מחק + מ&חיקה Install boot &loader on: - התקן &מנהל אתחול מערכת על: + התקנת מ&נהל אתחול מערכת על: Are you sure you want to create a new partition table on %1? - האם אתה בטוח שברצונך ליצור טבלת מחיצות חדשה על %1? + ליצור טבלת מחיצות חדשה על %1? Can not create new partition - + לא ניתן ליצור מחיצה חדשה The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead. - + לטבלת המחיצות על %1 כבר יש %2 מחיצות עיקריות ואי אפשר להוסיף עוד כאלה. נא להסיר מחיצה עיקרית אחת ולהוסיף מחיצה מורחבת במקום. @@ -1701,7 +1701,7 @@ The installer will quit and all changes will be lost. Gathering system information... - מלקט מידע אודות המערכת... + נאסף מידע על המערכת… @@ -1711,32 +1711,32 @@ The installer will quit and all changes will be lost. Install %1 <strong>alongside</strong> another operating system. - התקן את %1 <strong>לצד</strong> מערכת הפעלה אחרת. + להתקין את %1 <strong>לצד</strong> מערכת הפעלה אחרת. <strong>Erase</strong> disk and install %1. - <strong>מחק</strong> את הכונן והתקן את %1. + <strong>למחוק</strong> את הכונן ולהתקין את %1. <strong>Replace</strong> a partition with %1. - <strong>החלף</strong> מחיצה עם %1. + <strong>החלפת</strong> מחיצה עם %1. <strong>Manual</strong> partitioning. - מגדיר מחיצות באופן <strong>ידני</strong>. + להגדיר מחיצות באופן <strong>ידני</strong>. Install %1 <strong>alongside</strong> another operating system on disk <strong>%2</strong> (%3). - התקן את %1 <strong>לצד</strong> מערכת הפעלה אחרת על כונן <strong>%2</strong> (%3). + להתקין את %1 <strong>לצד</strong> מערכת הפעלה אחרת על כונן <strong>%2</strong> (%3). <strong>Erase</strong> disk <strong>%2</strong> (%3) and install %1. - <strong>מחק</strong> כונן <strong>%2</strong> (%3) והתקן %1. + <strong>למחוק</strong> את הכונן <strong>%2</strong> (%3) ולהתקין את %1. @@ -1799,13 +1799,13 @@ The installer will quit and all changes will be lost. Plasma Look-and-Feel Job - + משימת מראה ותחושה של Plasma Could not select KDE Plasma Look-and-Feel package - + לא ניתן לבחור את חבילת המראה והתחושה של KDE Plasma. @@ -1818,7 +1818,7 @@ The installer will quit and all changes will be lost. Placeholder - שומר מקום + ממלא מקום @@ -1831,7 +1831,7 @@ The installer will quit and all changes will be lost. Look-and-Feel - + מראה ותחושה @@ -1839,17 +1839,17 @@ The installer will quit and all changes will be lost. Saving files for later ... - + הקבצים נשמרים להמשך… No files configured to save for later. - + לא הוגדרו קבצים לשמירה בהמשך. Not all of the configured files could be preserved. - + לא ניתן לשמר את כל הקבצים שהוגדרו. @@ -1858,39 +1858,42 @@ The installer will quit and all changes will be lost. There was no output from the command. - + +לא היה פלט מהפקודה. Output: - + +פלט: + External command crashed. - + הפקודה החיצונית נכשלה. Command <i>%1</i> crashed. - + הפקודה <i>%1</i> קרסה. External command failed to start. - + הפעלת הפעולה החיצונית נכשלה. Command <i>%1</i> failed to start. - + הפעלת הפקודה <i>%1</i> נכשלה. Internal error when starting command. - + שגיאה פנימית בעת הפעלת פקודה. @@ -1900,22 +1903,22 @@ Output: External command failed to finish. - + סיום הפקודה החיצונית נכשל. Command <i>%1</i> failed to finish in %2 seconds. - + הפקודה <i>%1</i> לא הסתיימה תוך %2 שניות. External command finished with errors. - + הפקודה החיצונית הסתיימה עם שגיאות. Command <i>%1</i> finished with exit code %2. - + הפקודה <i>%1</i> הסתיימה עם קוד היציאה %2. @@ -1923,28 +1926,28 @@ Output: Default Keyboard Model - ברירת מחדל של דגם המקלדת + דגם מקלדת כבררת מחדל Default - ברירת מחדל + בררת מחדל unknown - לא מוכר/ת + לא ידוע extended - מורחב/ת + מורחבת unformatted - לא מאותחל/ת + לא מאותחלת @@ -1954,7 +1957,7 @@ Output: Unpartitioned space or unknown partition table - הזכרון לא מחולק למחיצות או טבלת מחיצות לא מוכרת + הזכרון לא מחולק למחיצות או שטבלת המחיצות אינה מוכרת @@ -2037,27 +2040,27 @@ Output: Gathering system information... - מלקט מידע אודות המערכת... + נאסף מידע על המערכת… has at least %1 GB available drive space - קיים לפחות %1 GB של נפח אחסון + עם %1 ג״ב של נפח אחסון לפחות There is not enough drive space. At least %1 GB is required. - נפח האחסון לא מספק. נדרש לפחות %1 GB. + נפח האחסון לא מספיק. נדרשים %1 ג״ב לפחות. has at least %1 GB working memory - קיים לפחות %1 GB של זכרון פעולה + עם %1 ג״ב של זכרון פעולה לפחות The system does not have enough working memory. At least %1 GB is required. - כמות הזכרון הנדרשת לפעולה, לא מספיקה. נדרש לפחות %1 GB. + כמות הזיכרון הנדרשת לפעולה אינה מספיקה. נדרשים %1 ג״ב לפחות. @@ -2087,7 +2090,7 @@ Output: The screen is too small to display the installer. - גודל המסך קטן מדי בכדי להציג את מנהל ההתקנה. + גודל המסך קטן מכדי להציג את תכנית ההתקנה. @@ -2095,7 +2098,7 @@ Output: Resize partition %1. - שנה גודל מחיצה %1. + שינוי גודל המחיצה %1. @@ -2118,12 +2121,12 @@ Output: Scanning storage devices... - סורק התקני זכרון... + התקני אחסון נסרקים… Partitioning - מגדיר מחיצות + חלוקה למחיצות @@ -2131,17 +2134,17 @@ Output: Set hostname %1 - הגדר שם עמדה %1 + הגדרת שם מארח %1 Set hostname <strong>%1</strong>. - הגדר שם עמדה <strong>%1</strong>. + הגדרת שם מארח <strong>%1</strong>. Setting hostname %1. - מגדיר את שם העמדה %1. + שם העמדה %1 מוגדר. @@ -2153,7 +2156,7 @@ Output: Cannot write hostname to target system - נכשלה כתיבת שם העמדה למערכת המטרה + כתיבת שם העמדה למערכת היעד נכשלה @@ -2201,12 +2204,12 @@ Output: Set flags on new partition. - הגדר סימונים על מחיצה חדשה. + הגדרת סימונים על מחיצה חדשה. Clear flags on partition <strong>%1</strong>. - מחק סימונים על מחיצה <strong>%1</strong>. + מחיקת סימונים מהמחיצה <strong>%1</strong>. @@ -2364,7 +2367,7 @@ Output: %L1 / %L2 slide counter, %1 of %2 (numeric) - + %L1 / %L2 @@ -2445,7 +2448,7 @@ Output: Placeholder - שומר מקום + ממלא מקום @@ -2577,17 +2580,17 @@ Output: <h1>Welcome to the %1 installer.</h1> - <h1>ברוכים הבאים להתקנת %1.</h1> + <h1>ברוך בואך להתקנת %1.</h1> <h1>Welcome to the Calamares installer for %1.</h1> - <h1>ברוכים הבאים להתקנת Calamares עבור %1.</h1> + <h1>ברוך בואך להתקנת %1 עם Calamares.</h1> About %1 installer - אודות התקנת %1 + על אודות התקנת %1 @@ -2597,7 +2600,7 @@ Output: %1 support - תמיכה ב - %1 + תמיכה ב־%1 @@ -2605,7 +2608,7 @@ Output: Welcome - ברוכים הבאים + ברוך בואך \ No newline at end of file diff --git a/lang/calamares_hi.ts b/lang/calamares_hi.ts index c1883707e..42750f9a0 100644 --- a/lang/calamares_hi.ts +++ b/lang/calamares_hi.ts @@ -4,17 +4,17 @@ The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. - इस सिस्टम का <strong>boot वातावरण</strong>।<br><br>पुराने x86 सिस्टम केवल <strong>BIOS</strong> का समर्थन करते हैं।<br>आधुनिक सिस्टम आमतौर पर <strong>EFI</strong> का उपयोग करते हैं, लेकिन compatibilty मोड में शुरू होने पर BIOS के रूप में दिखाई दे सकते हैं। + इस सिस्टम का <strong>बूट वातावरण</strong>।<br><br>पुराने x86 सिस्टम केवल <strong>BIOS</strong> का समर्थन करते हैं। आधुनिक सिस्टम आमतौर पर <strong>EFI</strong> का उपयोग करते हैं, लेकिन संगतता मोड में शुरू होने पर BIOS के रूप में दिखाई दे सकते हैं । This system was started with an <strong>EFI</strong> boot environment.<br><br>To configure startup from an EFI environment, this installer must deploy a boot loader application, like <strong>GRUB</strong> or <strong>systemd-boot</strong> on an <strong>EFI System Partition</strong>. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own. - यह सिस्टम <strong>EFI</strong> boot वातावरण के साथ शुरू किया गया।<br><br>EFI वातावरण से स्टार्टअप विन्यस्त करने के लिए इंस्टॉलर को <strong>GRUB</strong> या <strong>systemd-boot</strong> जैसे boot loader अनुप्रयोग <strong>EFI सिस्टम विभाजन</strong> पर स्थापित करने जरूरी हैं। यह स्वत: होता है, परंतु अगर आप मैनुअल विभाजन करना चुनते है; तो आपको या तो इसे चुनना होगा या फिर खुद ही बनाना होगा। + यह सिस्टम <strong>EFI</strong>बूट वातावरण के साथ शुरू किया गया।<br><br>EFI वातावरण से स्टार्टअप विन्यस्त करने के लिए इंस्टॉलर को <strong>GRUB</strong> या <strong>systemd-boot</strong> जैसे बूट लोडर अनुप्रयोग <strong>EFI सिस्टम विभाजन</strong>पर स्थापित करने जरूरी हैं। यह स्वत: होता है, परंतु अगर आप मैनुअल विभाजन करना चुनते है; तो आपको या तो इसे चुनना होगा या फिर खुद ही बनाना होगा। This system was started with a <strong>BIOS</strong> boot environment.<br><br>To configure startup from a BIOS environment, this installer must install a boot loader, like <strong>GRUB</strong>, either at the beginning of a partition or on the <strong>Master Boot Record</strong> near the beginning of the partition table (preferred). This is automatic, unless you choose manual partitioning, in which case you must set it up on your own. - यह सिस्टम <strong>BIOS</strong> boot वातावरण के साथ शुरू किया गया।<br><br>BIOS वातावरण से स्टार्टअप विन्यस्त करने के लिए इंस्टॉलर को <strong>GRUB</strong> जैसे boot loader को, या तो विभाजन की शुरुआत में या फिर <strong>Master Boot Record</strong> पर विभाजन तालिका की शुरुआत में इंस्टॉल (preferred) करना होगा। यह स्वत: होता है, परंतु अगर आप मैनुअल विभाजन करना चुनते है; तो आपको इसे खुद ही बनाना होगा। + यह सिस्टम <strong>BIOS</strong>बूट वातावरण के साथ शुरू किया गया।<br><br>BIOS वातावरण से स्टार्टअप विन्यस्त करने के लिए इंस्टॉलर को <strong>GRUB</strong> जैसे बूट लोडर को, या तो विभाजन की शुरुआत में या फिर <strong>Master Boot Record</strong> पर विभाजन तालिका की शुरुआत में इंस्टॉल (सुझाया जाता है) करना होगा। यह स्वत: होता है, परंतु अगर आप मैनुअल विभाजन करना चुनते है; तो आपको इसे खुद ही बनाना होगा। @@ -27,7 +27,7 @@ Boot Partition - Boot विभाजन + बूट विभाजन @@ -37,7 +37,7 @@ Do not install a boot loader - Boot loader इंस्टॉल न करें + बूट लोडर इंस्टॉल न करें @@ -50,7 +50,7 @@ Blank Page - + खाली पृष्ठ @@ -73,7 +73,7 @@ Modules - Modules + मापांक @@ -115,7 +115,7 @@ Done - हो गया + पूर्ण @@ -146,22 +146,22 @@ Working directory %1 for python job %2 is not readable. - Python job %2 के लिए कार्यरत डायरेक्टरी %1 read करने योग्य नहीं है। + Python job %2 के लिए कार्यरत डायरेक्टरी %1 रीड करने योग्य नहीं है। Bad main script file - मुख्य script फ़ाइल गलत है + मुख्य स्क्रिप्ट फ़ाइल गलत है Main script file %1 for python job %2 is not readable. - Python job %2 के लिए मुख्य script फ़ाइल %1 read करने योग्य नहीं है। + Python job %2 के लिए मुख्य स्क्रिप्ट फ़ाइल %1 रीड करने योग्य नहीं है। Boost.Python error in job "%1". - Job "%1" में Boost.Python error। + Job "%1" में Boost.Python त्रुटि। @@ -169,19 +169,19 @@ &Back - &वापस + वापस (&B) &Next - &आगे + आगे (&N) &Cancel - &रद्द करें + रद्द करें (&C) @@ -192,22 +192,22 @@ Calamares Initialization Failed - + Calamares का आरंभीकरण विफल रहा %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + %1 को इंस्टॉल नहीं किया जा सका। Calamares सारे विन्यस्त मापांकों को लोड करने में विफल रहा। इस समस्या का कारण लिनक्स-वितरण द्वारा Calamares के उपयोग-संबंधी कोई त्रुटि है। <br/>The following modules could not be loaded: - + <br/>निम्नलिखित मापांक लोड नहीं हो सकें : &Install - + इंस्टॉल करें (&I) @@ -224,17 +224,17 @@ The installer will quit and all changes will be lost. &Yes - &हाँ + हाँ (&Y) &No - &नहीं + नहीं (&N) &Close - &बंद करें + बंद करें (&C) @@ -249,27 +249,27 @@ The installer will quit and all changes will be lost. &Install now - अभी &इंस्टॉल करें + अभी इंस्टॉल करें (&I) Go &back - &वापस जाएँ + वापस जाएँ (&b) &Done - हो &गया + पूर्ण हुआ (&D) The installation is complete. Close the installer. - इंस्टॉल पूर्ण हुआ।अब इंस्टॉलर को बंद करें। + इंस्टॉल पूर्ण हुआ। अब इंस्टॉलर को बंद करें। Error - Error + त्रुटि @@ -287,7 +287,7 @@ The installer will quit and all changes will be lost. unparseable Python error - unparseable Python error + unparseable Python त्रुटि @@ -297,7 +297,7 @@ The installer will quit and all changes will be lost. Unfetchable Python error. - Unfetchable Python error. + Unfetchable Python त्रुटि। @@ -328,7 +328,7 @@ The installer will quit and all changes will be lost. This program will ask you some questions and set up %2 on your computer. - यह program आपसे कुछ सवाल पूछेगा व आपके कंप्यूटर पर %2 को सेट करेगा। + यह प्रोग्राम आपसे कुछ सवाल पूछ आपके कंप्यूटर पर %2 को सेट करेगा। @@ -338,7 +338,7 @@ The installer will quit and all changes will be lost. System requirements - सिस्टम की आवश्यकताएँ + सिस्टम इंस्टॉल हेतु आवश्यकताएँ @@ -361,7 +361,7 @@ The installer will quit and all changes will be lost. Boot loader location: - Boot loader की location: + बूट लोडर का स्थान: @@ -371,7 +371,7 @@ The installer will quit and all changes will be lost. Select storage de&vice: - Storage डि&वाइस चुनें : + डिवाइस चुनें (&v): @@ -414,7 +414,7 @@ The installer will quit and all changes will be lost. This storage device does not seem to have an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - इस storage डिवाइस पर लगता है कि कोई ऑपरेटिंग सिस्टम नहीं है। आप क्या करना चाहेंगे?<br/>आप storage डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। + इस डिवाइस पर लगता है कि कोई ऑपरेटिंग सिस्टम नहीं है। आप क्या करना चाहेंगे?<br/>आप डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। @@ -422,12 +422,12 @@ The installer will quit and all changes will be lost. <strong>Erase disk</strong><br/>This will <font color="red">delete</font> all data currently present on the selected storage device. - <strong>डिस्क erase करें</strong><br/>इससे चयनित storage डिवाइस पर मौजूद सारा डाटा <font color="red">delete</font> हो जाएगा। + <strong>डिस्क का सारा डाटा हटाएँ</strong><br/>इससे चयनित डिवाइस पर मौजूद सारा डाटा <font color="red">हटा</font>हो जाएगा। This storage device has %1 on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - इस storage डिवाइस पर %1 है। आप क्या करना चाहेंगे?<br/>आप storage डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। + इस डिवाइस पर %1 है। आप क्या करना चाहेंगे?<br/>आप डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। @@ -443,17 +443,17 @@ The installer will quit and all changes will be lost. <strong>Replace a partition</strong><br/>Replaces a partition with %1. - <strong>विभाजन को बदलें</strong>एक विभाजन को %1 से बदलें। + <strong>विभाजन को बदलें</strong><br/>एक विभाजन को %1 से बदलें। This storage device already has an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - इस storage डिवाइस पर पहले से एक ऑपरेटिंग सिस्टम है। आप क्या करना चाहेंगे?<br/>आप storage डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। + इस डिवाइस पर पहले से एक ऑपरेटिंग सिस्टम है। आप क्या करना चाहेंगे?<br/>आप डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। This storage device has multiple operating systems on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - इस storage डिवाइस पर एक से अधिक ऑपरेटिंग सिस्टम है। आप क्या करना चाहेंगे?<br/>आप storage डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। + इस डिवाइस पर एक से अधिक ऑपरेटिंग सिस्टम है। आप क्या करना चाहेंगे?<br/>आप डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। @@ -461,17 +461,17 @@ The installer will quit and all changes will be lost. Clear mounts for partitioning operations on %1 - %1 पर विभाजन कार्य हेतु mount हटाएँ + %1 पर विभाजन कार्य हेतु माउंट हटाएँ Clearing mounts for partitioning operations on %1. - %1 पर विभाजन कार्य हेतु mount हटाएँ जा रहे हैं। + %1 पर विभाजन कार्य हेतु माउंट हटाएँ जा रहे हैं। Cleared all mounts for %1 - %1 के लिए सभी mount हटा दिए गए + %1 के लिए सभी माउंट हटा दिए गए @@ -479,22 +479,22 @@ The installer will quit and all changes will be lost. Clear all temporary mounts. - सभी अस्थायी mount हटाएँ। + सभी अस्थायी माउंट हटाएँ। Clearing all temporary mounts. - सभी अस्थायी mount हटाएँ जा रहे हैं। + सभी अस्थायी माउंट हटाएँ जा रहे हैं। Cannot get list of temporary mounts. - अस्थाई mount की सूची नहीं मिली। + अस्थाई माउंट की सूची नहीं मिली। Cleared all temporary mounts. - सभी अस्थायी mount हटा दिए गए। + सभी अस्थायी माउंट हटा दिए गए। @@ -503,7 +503,7 @@ The installer will quit and all changes will be lost. Could not run command. - कमांड run नहीं की जा सकी। + कमांड चलाई नहीं जा सकी। @@ -534,32 +534,32 @@ The installer will quit and all changes will be lost. MiB - MiB + MiB Partition &Type: - विभाजन का प्र&कार : + विभाजन का प्रकार (&T): &Primary - &मुख्य + मुख्य (&P) E&xtended - + विस्तृत (&x) Fi&le System: - + फ़ाइल सिस्टम (&l): LVM LV name - + LVM LV का नाम @@ -569,22 +569,22 @@ The installer will quit and all changes will be lost. &Mount Point: - + माउंट पॉइंट (&M): Si&ze: - + आकार (&z): En&crypt - En&crypt + एन्क्रिप्ट (&c) Logical - + तार्किक @@ -599,7 +599,7 @@ The installer will quit and all changes will be lost. Mountpoint already in use. Please select another one. - + माउंट पॉइंट पहले से उपयोग में है । कृपया दूसरा चुनें। @@ -607,22 +607,22 @@ The installer will quit and all changes will be lost. Create new %2MB partition on %4 (%3) with file system %1. - + फ़ाइल सिस्टम %1 के साथ %4 (%3) पर नया %2MB का विभाजन बनाएँ। Create new <strong>%2MB</strong> partition on <strong>%4</strong> (%3) with file system <strong>%1</strong>. - + फ़ाइल सिस्टम <strong>%1</strong> के साथ <strong>%4</strong> (%3) पर नया <strong>%2MB</strong> का विभाजन बनाएँ। Creating new %1 partition on %2. - + %2 पर नया %1 विभाजन बनाया जा रहा है। The installer failed to create partition on disk '%1'. - + इंस्टॉलर डिस्क '%1' पर विभाजन बनाने में विफल रहा। @@ -630,17 +630,17 @@ The installer will quit and all changes will be lost. Create Partition Table - + विभाजन तालिका बनाएँ Creating a new partition table will delete all existing data on the disk. - + नई विभाजन तालिका बनाने से डिस्क पर मौजूद सारा डाटा हट जाएगा। What kind of partition table do you want to create? - + आप किस तरह की विभाजन तालिका बनाना चाहते हैं? @@ -650,7 +650,7 @@ The installer will quit and all changes will be lost. GUID Partition Table (GPT) - GUID Partition Table (GPT) + GUID विभाजन तालिका (GPT) @@ -658,22 +658,22 @@ The installer will quit and all changes will be lost. Create new %1 partition table on %2. - + %2 पर नई %1 विभाजन तालिका बनाएँ। Create new <strong>%1</strong> partition table on <strong>%2</strong> (%3). - + <strong>%2</strong> (%3) पर नई <strong>%1</strong> विभाजन तालिका बनाएँ। Creating new %1 partition table on %2. - + %2 पर नई %1 विभाजन तालिका बनाई जा रही है। The installer failed to create a partition table on %1. - + इंस्टॉलर डिस्क '%1' पर विभाजन तालिका बनाने में विफल रहा। @@ -681,37 +681,37 @@ The installer will quit and all changes will be lost. Create user %1 - + %1 उपयोक्ता बनाएँ Create user <strong>%1</strong>. - + <strong>%1</strong> उपयोक्ता बनाएँ। Creating user %1. - + %1 उपयोक्ता बनाया जा रहा है। Sudoers dir is not writable. - + Sudoers डायरेक्टरी राइट करने योग्य नहीं है। Cannot create sudoers file for writing. - + राइट हेतु sudoers फ़ाइल नहीं बन सकती। Cannot chmod sudoers file. - + sudoers फ़ाइल chmod नहीं की जा सकती। Cannot open groups file for reading. - + रीड हेतु groups फ़ाइल खोली नहीं जा सकती। @@ -719,22 +719,22 @@ The installer will quit and all changes will be lost. Delete partition %1. - + विभाजन %1 हटाएँ। Delete partition <strong>%1</strong>. - + विभाजन <strong>%1</strong> हटाएँ। Deleting partition %1. - + %1 विभाजन हटाया जा रहा है। The installer failed to delete partition %1. - + इंस्टॉलर विभाजन %1 को हटाने में विफल रहा । @@ -742,32 +742,32 @@ The installer will quit and all changes will be lost. The type of <strong>partition table</strong> on the selected storage device.<br><br>The only way to change the partition table type is to erase and recreate the partition table from scratch, which destroys all data on the storage device.<br>This installer will keep the current partition table unless you explicitly choose otherwise.<br>If unsure, on modern systems GPT is preferred. - + चयनित डिवाइस पर <strong>विभाजन तालिका</strong> का प्रकार।<br><br>विभाजन तालिका का प्रकार केवल विभाजन तालिका को हटा दुबारा बनाकर ही किया जा सकता है, इससे डिस्क पर मौजूद सभी डाटा नहीं नष्ट हो जाएगा।<br>अगर आप कुछ अलग नहीं चुनते तो यह इंस्टॉलर वर्तमान विभाजन तालिका उपयोग करेगा।<br>अगर सुनिश्चित नहीं है तो नए व आधुनिक सिस्टम के लिए GPT चुनें। This device has a <strong>%1</strong> partition table. - + इस डिवाइस में <strong>%1</strong> विभाजन तालिका है। This is a <strong>loop</strong> device.<br><br>It is a pseudo-device with no partition table that makes a file accessible as a block device. This kind of setup usually only contains a single filesystem. - + यह एक <strong>लूप</strong> डिवाइस है।<br><br>इस छद्म-डिवाइस में कोई विभाजन तालिका नहीं है जो फ़ाइल को ब्लॉक डिवाइस के रूप में उपयोग कर सकें। इस तरह के सेटअप में केवल एक फ़ाइल सिस्टम होता है। This installer <strong>cannot detect a partition table</strong> on the selected storage device.<br><br>The device either has no partition table, or the partition table is corrupted or of an unknown type.<br>This installer can create a new partition table for you, either automatically, or through the manual partitioning page. - + इंस्टॉलर को चयनित डिवाइस पर <strong>कोई विभाजन तालिका नहीं मिली</strong>।<br><br> डिवाइस पर विभाजन तालिका नहीं है या फिर जो है वो ख़राब है या उसका प्रकार अज्ञात है। <br>इंस्टॉलर एक नई विभाजन तालिका, स्वतः व मैनुअल दोनों तरह से बना सकता है। <br><br>This is the recommended partition table type for modern systems which start from an <strong>EFI</strong> boot environment. - + <br><br><strong>EFI</strong>वातावरण से शुरू होने वाले आधुनिक सिस्टम के लिए यही विभाजन तालिका सुझाई जाती है। <br><br>This partition table type is only advisable on older systems which start from a <strong>BIOS</strong> boot environment. GPT is recommended in most other cases.<br><br><strong>Warning:</strong> the MBR partition table is an obsolete MS-DOS era standard.<br>Only 4 <em>primary</em> partitions may be created, and of those 4, one can be an <em>extended</em> partition, which may in turn contain many <em>logical</em> partitions. - + <br><br>यह विभाजन तालिका केवल <strong>BIOS</strong>वातावरण से शुरू होने वाले पुराने सिस्टम के लिए ही सुझाई जाती है। बाकी सब के लिए GPT ही सबसे उपयुक्त है।<br><br><strong>चेतावनी:</strong> MBR विभाजन तालिका MS-DOS के समय की एक पुरानी तकनीक है।<br> इसमें केवल 4 <em>मुख्य</em> विभाजन बनाये जा सकते हैं, इनमें से एक <em>विस्तृत</em> हो सकता है व इसके अंदर भी कई <em>तार्किक</em> विभाजन हो सकते हैं। @@ -793,7 +793,7 @@ The installer will quit and all changes will be lost. Failed to open %1 - + %1 खोलने में विफल @@ -809,17 +809,17 @@ The installer will quit and all changes will be lost. Edit Existing Partition - + मौजूदा विभाजन को संपादित करें Content: - + सामग्री : &Keep - + रखें (&K) @@ -834,22 +834,22 @@ The installer will quit and all changes will be lost. &Mount Point: - + माउंट पॉइंट (&M): Si&ze: - + आकार (&z): MiB - MiB + MiB Fi&le System: - + फ़ाइल सिस्टम (&l): @@ -859,7 +859,7 @@ The installer will quit and all changes will be lost. Mountpoint already in use. Please select another one. - + माउंट पॉइंट पहले से उपयोग में है । कृपया दूसरा चुनें। @@ -872,22 +872,22 @@ The installer will quit and all changes will be lost. En&crypt system - + सिस्टम एन्क्रिप्ट करें (&E) Passphrase - + कूटशब्द Confirm passphrase - + कूटशब्द की पुष्टि करें Please enter the same passphrase in both boxes. - + कृपया दोनों स्थानों में समान कूटशब्द दर्ज करें। @@ -900,32 +900,32 @@ The installer will quit and all changes will be lost. Install %1 on <strong>new</strong> %2 system partition. - + <strong>नए</strong> %2 सिस्टम विभाजन पर %1 इंस्टॉल करें। Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong>. - + <strong>नया</strong> %2 विभाजन माउंट पॉइंट <strong>%1</strong> के साथ सेट करें। Install %2 on %3 system partition <strong>%1</strong>. - + %3 सिस्टम विभाजन <strong>%1</strong> पर %2 इंस्टॉल करें। Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong>. - + %3 विभाजन <strong>%1</strong> माउंट पॉइंट <strong>%2</strong> के साथ सेट करें। Install boot loader on <strong>%1</strong>. - + बूट लोडर <strong>%1</strong> पर इंस्टॉल करें। Setting up mount points. - + माउंट पॉइंट सेट किए जा रहे हैं। @@ -938,22 +938,22 @@ The installer will quit and all changes will be lost. <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style=" font-style:italic;">Done</span> or close the installer.</p></body></html> - + <html><head/><body><p>इस विकल्प के चेक होने पर आपका सिस्टम तुरंत पुनः आरंभ हो जाएगा जब आप <span style=" font-style:italic;">हो गया</span>पर क्लिक करेंगे या इंस्टॉलर बंद करें ।</p></body></html> &Restart now - + अभी पुनः आरंभ करें (&R) <h1>All done.</h1><br/>%1 has been installed on your computer.<br/>You may now restart into your new system, or continue using the %2 Live environment. - + <h1>सब हो गया।</h1><br/>आपके कंप्यूटर पर %1 इंस्टॉल हो चुका है।<br/>अब आप आपने नए सिस्टम को पुनः आरंभ कर सकते है, या फिर %2 लाइव वातावरण उपयोग करना जारी रखें। <h1>Installation Failed</h1><br/>%1 has not been installed on your computer.<br/>The error message was: %2. - + <h1>इंस्टॉल विफल रहा</h1><br/>%1 आपके कंप्यूटर पर इंस्टॉल नहीं हुआ।<br/>त्रुटि संदेश : %2। @@ -961,17 +961,17 @@ The installer will quit and all changes will be lost. Finish - + समाप्त करें Installation Complete - + इंस्टॉल पूर्ण हुआ The installation of %1 is complete. - + %1 का इंस्टॉल पूर्ण हुआ। @@ -979,22 +979,22 @@ The installer will quit and all changes will be lost. Format partition %1 (file system: %2, size: %3 MB) on %4. - + विभाजन %1 (फ़ाइल सिस्टम: %2, आकार: %3MB) को %4 पर फॉर्मेट करें। Format <strong>%3MB</strong> partition <strong>%1</strong> with file system <strong>%2</strong>. - + फ़ाइल सिस्टम <strong>%2</strong> के साथ <strong>%3MB</strong> के विभाजन <strong>%1</strong> को फॉर्मेट करें। Formatting partition %1 with file system %2. - + फ़ाइल सिस्टम %2 के साथ विभाजन %1 को फॉर्मेट किया जा रहा है। The installer failed to format partition %1 on disk '%2'. - + इंस्टॉलर डिस्क '%2' पर विभाजन %1 को फॉर्मेट करने में विफल रहा। @@ -1002,12 +1002,12 @@ The installer will quit and all changes will be lost. Konsole not installed - + Konsole इंस्टॉल नहीं है Please install KDE Konsole and try again! - + कृपया केडीई Konsole इंस्टॉल कर, पुनः प्रयास करें। @@ -1028,12 +1028,12 @@ The installer will quit and all changes will be lost. Set keyboard model to %1.<br/> - + कुंजीपटल का मॉडल %1 सेट करें।<br/> Set keyboard layout to %1/%2. - + कुंजीपटल का अभिन्यास %1/%2 सेट करें। @@ -1041,7 +1041,7 @@ The installer will quit and all changes will be lost. Keyboard - कुंजीपटल + कुंजीपटल @@ -1049,22 +1049,22 @@ The installer will quit and all changes will be lost. System locale setting - + सिस्टम स्थानिकी सेटिंग्स The system locale setting affects the language and character set for some command line user interface elements.<br/>The current setting is <strong>%1</strong>. - + सिस्टम स्थानिकी सेटिंग कमांड लाइन के कुछ उपयोक्ता अंतरफलक तत्वों की भाषा व अक्षर सेट पर असर डालती है।<br/>मौजूदा सेटिंग है <strong>%1</strong>। &Cancel - &रद्द करें + रद्द करें (&C) &OK - + ठीक है (&O) @@ -1077,17 +1077,17 @@ The installer will quit and all changes will be lost. I accept the terms and conditions above. - + मैं उपर्युक्त नियम व शर्तें स्वीकार करता हूँ। <h1>License Agreement</h1>This setup procedure will install proprietary software that is subject to licensing terms. - + <h1>लाइसेंस अनुबंध</h1>यह लाइसेंस शर्तों के अधीन अमुक्त सॉफ्टवेयर को इंस्टॉल करेगा। Please review the End User License Agreements (EULAs) above.<br/>If you do not agree with the terms, the setup procedure cannot continue. - + कृपया ऊपर दिए गए लक्षित उपयोक्ता लाइसेंस अनुबंध (EULAs) ध्यानपूर्वक पढ़ें।<br/> यदि आप शर्तों से असहमत है, तो सेटअप को ज़ारी नहीं रखा जा सकता। @@ -1097,44 +1097,44 @@ The installer will quit and all changes will be lost. Please review the End User License Agreements (EULAs) above.<br/>If you do not agree with the terms, proprietary software will not be installed, and open source alternatives will be used instead. - + कृपया ऊपर दिए गए लक्षित उपयोक्ता लाइसेंस अनुबंध (EULAs) ध्यानपूर्वक पढ़ें।<br/> यदि आप शर्तों से असहमत है, तो अमुक्त सॉफ्टवेयर इंस्टाल नहीं किया जाएगा व उनके मुक्त विकल्प उपयोग किए जाएँगे। <strong>%1 driver</strong><br/>by %2 %1 is an untranslatable product name, example: Creative Audigy driver - + <strong>%1 ड्राइवर</strong><br/>%2 द्वारा <strong>%1 graphics driver</strong><br/><font color="Grey">by %2</font> %1 is usually a vendor name, example: Nvidia graphics driver - + <strong>%1 ग्राफ़िक्स ड्राइवर</strong><br/><font color="Grey">%2 द्वारा</font> <strong>%1 browser plugin</strong><br/><font color="Grey">by %2</font> - + <strong>%1 ब्राउज़र प्लगिन</strong><br/><font color="Grey">%2 द्वारा</font> <strong>%1 codec</strong><br/><font color="Grey">by %2</font> - + <strong>%1 कोडेक</strong><br/><font color="Grey">%2 द्वारा</font> <strong>%1 package</strong><br/><font color="Grey">by %2</font> - + <strong>%1 पैकेज</strong><br/><font color="Grey">%2 द्वारा</font> <strong>%1</strong><br/><font color="Grey">by %2</font> - + <strong>%1</strong><br/><font color="Grey">%2 द्वारा</font> <a href="%1">view license agreement</a> - + <a href="%1">लाइसेंस अनुबंध देखें</a> @@ -1142,7 +1142,7 @@ The installer will quit and all changes will be lost. License - + लाइसेंस @@ -1150,33 +1150,33 @@ The installer will quit and all changes will be lost. The system language will be set to %1. - + सिस्टम भाषा %1 सेट की जाएगी। The numbers and dates locale will be set to %1. - + संख्या व दिनांक स्थानिकी %1 सेट की जाएगी। Region: - + क्षेत्र : Zone: - + क्षेत्र : &Change... - + बदलें (&C)... Set timezone to %1/%2.<br/> - + समय क्षेत्र %1%2 पर सेट करें।<br/> @@ -1190,12 +1190,12 @@ The installer will quit and all changes will be lost. Loading location data... - + स्थान संबंधी डाटा लोड किया जा रहा है... Location - + स्थान @@ -1203,12 +1203,12 @@ The installer will quit and all changes will be lost. Name - + नाम Description - + विवरण @@ -1226,7 +1226,7 @@ The installer will quit and all changes will be lost. Package selection - + पैकेज चयन @@ -1234,227 +1234,227 @@ The installer will quit and all changes will be lost. Password is too short - + कूटशब्द बहुत छोटा है Password is too long - + कूटशब्द बहुत लंबा है Password is too weak - + कूटशब्द बहुत कमज़ोर है Memory allocation error when setting '%1' - + '%1' सेट करते समय मेमोरी आवंटन त्रुटि Memory allocation error - + मेमोरी आवंटन त्रुटि The password is the same as the old one - + यह कूटशब्द पुराने वाला ही है The password is a palindrome - + कूटशब्द एक विलोमपद है The password differs with case changes only - + इसमें और पिछले कूटशब्द में केवल lower/upper case का फर्क है The password is too similar to the old one - + यह कूटशब्द पुराने वाले जैसा ही है The password contains the user name in some form - + इस कूटशब्द में किसी रूप में उपयोक्ता नाम है The password contains words from the real name of the user in some form - + इस कूटशब्द में किसी रूप में उपयोक्ता के असली नाम के शब्द शामिल है The password contains forbidden words in some form - + इस कूटशब्द में किसी रूप में वर्जित शब्द है The password contains less than %1 digits - + इस कूटशब्द में %1 से कम अंक हैं The password contains too few digits - + इस कूटशब्द में काफ़ी कम अंक हैं The password contains less than %1 uppercase letters - + इस कूटशब्द में %1 से कम uppercase अक्षर हैं The password contains too few uppercase letters - + इस कूटशब्द में काफ़ी कम uppercase अक्षर हैं The password contains less than %1 lowercase letters - + इस कूटशब्द में %1 से कम lowercase अक्षर हैं The password contains too few lowercase letters - + इस कूटशब्द में काफ़ी कम lowercase अक्षर हैं The password contains less than %1 non-alphanumeric characters - + इस कूटशब्द में %1 से कम ऐसे अक्षर हैं जो अक्षरांक नहीं हैं The password contains too few non-alphanumeric characters - + इस कूटशब्द में काफ़ी कम अक्षरांक हैं The password is shorter than %1 characters - + कूटशब्द %1 अक्षरों से छोटा है The password is too short - + कूटशब्द बहुत छोटा है The password is just rotated old one - + यह कूटशब्द पुराने वाला ही है, बस घुमा रखा है The password contains less than %1 character classes - + इस कूटशब्द में %1 से कम अक्षर classes हैं The password does not contain enough character classes - + इस कूटशब्द में नाकाफ़ी अक्षर classes हैं The password contains more than %1 same characters consecutively - + कूटशब्द में %1 से अधिक समान अक्षर लगातार हैं The password contains too many same characters consecutively - + कूटशब्द में काफ़ी ज्यादा समान अक्षर लगातार हैं The password contains more than %1 characters of the same class consecutively - + कूटशब्द में %1 से अधिक समान अक्षर classes लगातार हैं The password contains too many characters of the same class consecutively - + कूटशब्द में काफ़ी ज्यादा एक ही class के अक्षर लगातार हैं The password contains monotonic sequence longer than %1 characters - + कूटशब्द में %1 अक्षरों से लंबा monotonic अनुक्रम है The password contains too long of a monotonic character sequence - + कूटशब्द में काफ़ी बड़ा monotonic अनुक्रम है No password supplied - + कोई कूटशब्द नहीं दिया गया Cannot obtain random numbers from the RNG device - + RNG डिवाइस से यादृच्छिक अंक नहीं मिल सके Password generation failed - required entropy too low for settings - + कूटशब्द बनाना विफल रहा - सेटिंग्स के लिए आवश्यक entropy बहुत कम है The password fails the dictionary check - %1 - + कूटशब्द शब्दकोश की जाँच में विफल रहा - %1 The password fails the dictionary check - + कूटशब्द शब्दकोश की जाँच में विफल रहा Unknown setting - %1 - + अज्ञात सेटिंग- %1 Unknown setting - + अज्ञात सेटिंग Bad integer value of setting - %1 - + सेटिंग का गलत integer मान - %1 Bad integer value - + गलत integer मान Setting %1 is not of integer type - + सेटिंग %1 integer नहीं है Setting is not of integer type - + सेटिंग integer नहीं है Setting %1 is not of string type - + सेटिंग %1 string नहीं है Setting is not of string type - + सेटिंग string नहीं है Opening the configuration file failed - + विन्यास फ़ाइल खोलने में विफल @@ -1464,12 +1464,12 @@ The installer will quit and all changes will be lost. Fatal failure - + गंभीर विफलता Unknown error - + अज्ञात त्रुटि @@ -1482,12 +1482,12 @@ The installer will quit and all changes will be lost. Keyboard Model: - + कुंजीपटल का मॉडल Type here to test your keyboard - + अपना कुंजीपटल जाँचने के लिए यहां टाइप करें @@ -1500,64 +1500,64 @@ The installer will quit and all changes will be lost. What is your name? - + आपका नाम क्या है? What name do you want to use to log in? - + लॉग इन के लिए आप किस नाम का उपयोग करना चाहते हैं? font-weight: normal - font-weight: normal + मुद्रलिपि-weight: सामान्य <small>If more than one person will use this computer, you can set up multiple accounts after installation.</small> - + <small>अगर इस कंप्यूटर को एक से अधिक व्यक्ति उपयोग करते हैं, तो आप इंस्टॉल के उपरांत एकाधिक अकाउंट सेट कर सकते हैं।</small> Choose a password to keep your account safe. - + अपना अकाउंट सुरक्षित रखने के लिए पासवर्ड चुनें । <small>Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals.</small> - + <small>एक ही कूटशब्द दो बार दर्ज़ करें, ताकि उसे टाइप त्रुटि के लिए जांचा जा सके । एक अच्छे कूटशब्द में अक्षर, अंक व विराम चिन्हों का मेल होता है, उसमें कम-से-कम आठ अक्षर होने चाहिए, और उसे नियमित अंतराल पर बदलते रहना चाहिए।</small> What is the name of this computer? - + इस कंप्यूटर का नाम ? <small>This name will be used if you make the computer visible to others on a network.</small> - + <small>यदि आपका कंप्यूटर किसी नेटवर्क पर दृश्यमान होता है, तो यह नाम उपयोग किया जाएगा।</small> Log in automatically without asking for the password. - + कूटशब्द बिना पूछे ही स्वतः लॉग इन करें। Use the same password for the administrator account. - + प्रबंधक अकाउंट के लिए भी यही कूटशब्द उपयोग करें। Choose a password for the administrator account. - + प्रबंधक अकाउंट के लिए कूटशब्द चुनें। <small>Enter the same password twice, so that it can be checked for typing errors.</small> - + <small>समान कूटशब्द दो बार दर्ज करें, ताकि जाँच की जा सके कि कहीं टाइपिंग त्रुटि तो नहीं है।</small> @@ -1565,37 +1565,37 @@ The installer will quit and all changes will be lost. Root - Root + रुट Home - + होम Boot - Boot + बूट EFI system - + EFI सिस्टम Swap - + स्वैप New partition for %1 - + %1 के लिए नया विभाजन New partition - + नया विभाजन @@ -1609,33 +1609,33 @@ The installer will quit and all changes will be lost. Free Space - + खाली स्पेस New partition - + नया विभाजन Name - + नाम File System - + फ़ाइल सिस्टम Mount Point - + माउंट पॉइंट Size - + आकार @@ -1648,47 +1648,47 @@ The installer will quit and all changes will be lost. Storage de&vice: - + डिवाइस (&v): &Revert All Changes - + सभी बदलाव उलट दें (&R) New Partition &Table - + नई विभाजन तालिका (&T) Cre&ate - + बनाएँ (&a) &Edit - + संपादित करें (&E) &Delete - + हटाएँ (D) Install boot &loader on: - + बूट लोडर इंस्टॉल करें (&l) : Are you sure you want to create a new partition table on %1? - + क्या आप वाकई %1 पर एक नई विभाजन तालिका बनाना चाहते हैं? Can not create new partition - + नया विभाजन नहीं बनाया जा सकता @@ -1711,47 +1711,47 @@ The installer will quit and all changes will be lost. Install %1 <strong>alongside</strong> another operating system. - + %1 को दूसरे ऑपरेटिंग सिस्टम <strong>के साथ</strong> इंस्टॉल करें। <strong>Erase</strong> disk and install %1. - + डिस्क का सारा डाटा<strong>हटाकर</strong> कर %1 इंस्टॉल करें। <strong>Replace</strong> a partition with %1. - + विभाजन को %1 से <strong>बदलें</strong>। <strong>Manual</strong> partitioning. - + <strong>मैनुअल</strong> विभाजन। Install %1 <strong>alongside</strong> another operating system on disk <strong>%2</strong> (%3). - + डिस्क <strong>%2</strong> (%3) पर %1 को दूसरे ऑपरेटिंग सिस्टम <strong>के साथ</strong> इंस्टॉल करें। <strong>Erase</strong> disk <strong>%2</strong> (%3) and install %1. - + डिस्क <strong>%2</strong> (%3) <strong>erase</strong> कर %1 इंस्टॉल करें। <strong>Replace</strong> a partition on disk <strong>%2</strong> (%3) with %1. - + डिस्क <strong>%2</strong> (%3) के विभाजन को %1 से <strong>बदलें</strong>। <strong>Manual</strong> partitioning on disk <strong>%1</strong> (%2). - + डिस्क <strong>%1</strong> (%2) पर <strong>मैनुअल</strong> विभाजन। Disk <strong>%1</strong> (%2) - + डिस्क <strong>%1</strong> (%2) @@ -1766,32 +1766,32 @@ The installer will quit and all changes will be lost. No EFI system partition configured - + कोई EFI सिस्टम विभाजन विन्यस्त नहीं है An EFI system partition is necessary to start %1.<br/><br/>To configure an EFI system partition, go back and select or create a FAT32 filesystem with the <strong>esp</strong> flag enabled and mount point <strong>%2</strong>.<br/><br/>You can continue without setting up an EFI system partition but your system may fail to start. - + %1 को शुरू करने हेतु EFI सिस्टम विभाजन ज़रूरी है।<br/><br/>EFI सिस्टम विभाजन को विन्यस्त करने के लिए, वापस जाएँ और चुनें या बनाएँ एक FAT32 फ़ाइल सिस्टम जिस पर <strong>esp</strong> flag चालू हो व माउंट पॉइंट <strong>%2</strong>हो।<br/><br/>आप बिना सेट भी आगे बढ़ सकते है पर सिस्टम चालू नहीं होगा। EFI system partition flag not set - + EFI सिस्टम विभाजन flag सेट नहीं है An EFI system partition is necessary to start %1.<br/><br/>A partition was configured with mount point <strong>%2</strong> but its <strong>esp</strong> flag is not set.<br/>To set the flag, go back and edit the partition.<br/><br/>You can continue without setting the flag but your system may fail to start. - + %1 को शुरू करने हेतु EFI सिस्टम विभाजन ज़रूरी है।<br/><br/>विभाजन को माउंट पॉइंट <strong>%2</strong> के साथ विन्यस्त किया गया परंतु उसका <strong>esp</strong> flag सेट नहीं था।<br/> Flag सेट करने के लिए, वापस जाएँ और विभाजन को edit करें।<br/><br/>आप बिना सेट भी आगे बढ़ सकते है पर सिस्टम चालू नहीं होगा। Boot partition not encrypted - + बूट विभाजन एन्क्रिप्टेड नहीं है 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. - + एन्क्रिप्टेड रुट विभाजन के साथ एक अलग बूट विभाजन भी सेट किया गया था, पर बूट विभाजन एन्क्रिप्टेड नहीं था।<br/><br/> इस तरह का सेटअप सुरक्षित नहीं होता क्योंकि सिस्टम फ़ाइल एन्क्रिप्टेड विभाजन पर होती हैं।<br/>आप चाहे तो जारी रख सकते है, पर फिर फ़ाइल सिस्टम बाद में सिस्टम स्टार्टअप के दौरान अनलॉक होगा।<br/> विभाजन को एन्क्रिप्ट करने के लिए वापस जाकर उसे दोबारा बनाएँ व विभाजन निर्माण विंडो में<strong>एन्क्रिप्ट</strong> चुनें। @@ -1799,13 +1799,13 @@ The installer will quit and all changes will be lost. Plasma Look-and-Feel Job - Plasma Look-and-Feel Job + प्लाज़्मा Look-and-Feel Job Could not select KDE Plasma Look-and-Feel package - + KDE प्लाज़्मा का Look-and-Feel पैकेज चुना नहीं जा सका @@ -1823,7 +1823,7 @@ The installer will quit and all changes will be lost. Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is installed. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. - + कृपया KDE प्लाज़्मा डेस्कटॉप के लिए एक look-and-feel चुनें। आप अभी इस चरण को छोड़ सकते हैं व सिस्टम इंस्टॉल हो जाने के बाद इसे सेट कर सकते हैं। look-and-feel विकल्पों पर क्लिक कर आप चयनित look-and-feel का तुरंत ही पूर्वावलोकन कर सकते हैं। @@ -1831,7 +1831,7 @@ The installer will quit and all changes will be lost. Look-and-Feel - + Look-and-Feel @@ -1858,64 +1858,67 @@ The installer will quit and all changes will be lost. There was no output from the command. - + +कमांड से कोई आउटपुट नहीं मिला। Output: - + +आउटपुट: + External command crashed. - + बाह्य कमांड क्रैश हो गई। Command <i>%1</i> crashed. - + कमांड <i>%1</i> क्रैश हो गई। External command failed to start. - + बाह्य​ कमांड शुरू होने में विफल। Command <i>%1</i> failed to start. - + कमांड <i>%1</i> शुरू होने में विफल। Internal error when starting command. - + कमांड शुरू करते समय आंतरिक त्रुटि। Bad parameters for process job call. - + प्रक्रिया कार्य कॉल के लिए गलत मापदंड। External command failed to finish. - + बाहरी कमांड समाप्त करने में विफल। Command <i>%1</i> failed to finish in %2 seconds. - + कमांड <i>%1</i> %2 सेकंड में समाप्त होने में विफल। External command finished with errors. - + बाहरी कमांड त्रुटि के साथ समाप्त। Command <i>%1</i> finished with exit code %2. - + कमांड <i>%1</i> exit कोड %2 के साथ समाप्त। @@ -1923,18 +1926,18 @@ Output: Default Keyboard Model - + डिफ़ॉल्ट कुंजीपटल मॉडल Default - + डिफ़ॉल्ट unknown - + अज्ञात @@ -1949,12 +1952,12 @@ Output: swap - + स्वैप Unpartitioned space or unknown partition table - + अविभाजित स्पेस या अज्ञात विभाजन तालिका @@ -1967,59 +1970,59 @@ Output: Select where to install %1.<br/><font color="red">Warning: </font>this will delete all files on the selected partition. - + चुनें कि %1 को कहाँ इंस्टॉल करना है।<br/><font color="red">चेतावनी: </font> यह चयनित विभाजन पर मौजूद सभी फ़ाइलों को हटा देगा। The selected item does not appear to be a valid partition. - + चयनित आइटम एक मान्य विभाजन नहीं है। %1 cannot be installed on empty space. Please select an existing partition. - + %1 को खाली स्पेस पर इंस्टॉल नहीं किया जा सकता।कृपया कोई मौजूदा विभाजन चुनें। %1 cannot be installed on an extended partition. Please select an existing primary or logical partition. - + %1 को विस्तृत विभाजन पर इंस्टॉल नहीं किया जा सकता।कृपया कोई मौजूदा मुख्य या तार्किक विभाजन चुनें। %1 cannot be installed on this partition. - + इस विभाजन पर %1 इंस्टॉल नहीं किया जा सकता। Data partition (%1) - + डाटा विभाजन (%1) Unknown system partition (%1) - + अज्ञात सिस्टम विभाजन (%1) %1 system partition (%2) - + %1 सिस्टम विभाजन (%2) <strong>%4</strong><br/><br/>The partition %1 is too small for %2. Please select a partition with capacity at least %3 GiB. - + <strong>%4</strong><br/><br/>%2 के लिए विभाजन %1 बहुत छोटा है।कृपया कम-से-कम %3 GiB की क्षमता वाला कोई विभाजन चुनें । <strong>%2</strong><br/><br/>An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. - + <strong>%2</strong><br/><br/>इस सिस्टम पर कहीं भी कोई EFI सिस्टम विभाजन नहीं मिला। कृपया वापस जाएँ व %1 को सेट करने के लिए मैनुअल रूप से विभाजन करें। <strong>%3</strong><br/><br/>%1 will be installed on %2.<br/><font color="red">Warning: </font>all data on partition %2 will be lost. - + <strong>%3</strong><br/><br/>%2 पर %1 इंस्टॉल किया जाएगा।<br/><font color="red">चेतावनी : </font>विभाजन %2 पर मौजूद सारा डाटा हटा दिया जाएगा। @@ -2042,52 +2045,52 @@ Output: has at least %1 GB available drive space - + %1GB स्पेस ड्राइव पर उपलब्ध है There is not enough drive space. At least %1 GB is required. - + ड्राइव में पर्याप्त स्पेस नहीं है। कम-से-कम %1GB होना ज़रूरी है। has at least %1 GB working memory - + %1GB मेमोरी है The system does not have enough working memory. At least %1 GB is required. - + सिस्टम में पर्याप्त मेमोरी नहीं है। कम-से-कम %1GB होनी ज़रूरी है। is plugged in to a power source - + बिजली से कनेक्ट है। The system is not plugged in to a power source. - + सिस्टम बिजली से कनेक्ट नहीं है। is connected to the Internet - + इंटरनेट से कनेक्ट है। The system is not connected to the Internet. - + सिस्टम इंटरनेट से कनेक्ट नहीं है। The installer is not running with administrator rights. - + इंस्टॉलर के पास प्रबंधक अधिकार नहीं है। The screen is too small to display the installer. - + इंस्टॉलर दिखाने के लिए स्क्रीन बहुत छोटी है। @@ -2095,22 +2098,22 @@ Output: Resize partition %1. - + विभाजन %1 का आकार बदलें। Resize <strong>%2MB</strong> partition <strong>%1</strong> to <strong>%3MB</strong>. - + <strong>%2MB</strong> के <strong>%1</strong> विभाजन का आकार बदलकर <strong>%3MB</strong> किया जा रहा है। Resizing %2MB partition %1 to %3MB. - + %2MB के %1 विभाजन का आकार बदलकर %3MB किया जा रहा है। The installer failed to resize partition %1 on disk '%2'. - + इंस्टॉलर डिस्क '%2' पर विभाजन %1 का आकर बदलने में विफल रहा। @@ -2118,12 +2121,12 @@ Output: Scanning storage devices... - + डिवाइस स्कैन किए जा रहे हैं... Partitioning - + विभाजन @@ -2131,29 +2134,29 @@ Output: Set hostname %1 - + होस्ट नाम %1 सेट करें। Set hostname <strong>%1</strong>. - + होस्ट नाम <strong>%1</strong> सेट करें। Setting hostname %1. - + होस्ट नाम %1 सेट हो रहा है। Internal Error - + आंतरिक त्रुटि Cannot write hostname to target system - + लक्षित सिस्टम पर होस्ट नाम लिखा नहीं जा सकता। @@ -2161,29 +2164,29 @@ Output: Set keyboard model to %1, layout to %2-%3 - + कुंजीपटल का मॉडल %1, अभिन्यास %2-%3 सेट करें। Failed to write keyboard configuration for the virtual console. - + Virtual console हेतु कुंजीपटल की सेटिंग्स राइट करने में विफल रहा। Failed to write to %1 - + %1 पर राइट करने में विफल Failed to write keyboard configuration for X11. - + X11 हेतु कुंजीपटल की सेटिंग्स राइट करने में विफल रहा। Failed to write keyboard configuration to existing /etc/default directory. - + मौजूदा /etc /default डायरेक्टरी में कुंजीपटल की सेटिंग्स write करने में विफल रहा। @@ -2191,82 +2194,82 @@ Output: Set flags on partition %1. - + %1 विभाजन पर flag सेट करें। Set flags on %1MB %2 partition. - + %1MB के %2 विभाजन पर flag सेट करें। Set flags on new partition. - + नए विभाजन पर flag सेट करें। Clear flags on partition <strong>%1</strong>. - + <strong>%1</strong> विभाजन पर से flag हटाएँ। Clear flags on %1MB <strong>%2</strong> partition. - + %1MB के <strong>%2</strong> विभाजन पर से flag हटाएँ। Clear flags on new partition. - + नए विभाजन पर से flag हटाएँ। Flag partition <strong>%1</strong> as <strong>%2</strong>. - + <strong>%1</strong> विभाजन पर <strong>%2</strong> का flag लगाएँ। Flag %1MB <strong>%2</strong> partition as <strong>%3</strong>. - + %1MB के <strong>%2</strong> विभाजन पर <strong>%3</strong> का flag लगाएँ। Flag new partition as <strong>%1</strong>. - + नए विभाजन पर<strong>%1</strong>का flag लगाएँ। Clearing flags on partition <strong>%1</strong>. - + <strong>%1</strong> विभाजन पर से flag हटाएँ जा रहे हैं। Clearing flags on %1MB <strong>%2</strong> partition. - + %1MB के <strong>%2</strong> विभाजन पर से flag हटाएँ जा रहे हैं। Clearing flags on new partition. - + नए विभाजन पर से flag हटाएँ जा रहे हैं। Setting flags <strong>%2</strong> on partition <strong>%1</strong>. - + <strong>%1</strong> विभाजन पर flag <strong>%2</strong> सेट किए जा रहे हैं। Setting flags <strong>%3</strong> on %1MB <strong>%2</strong> partition. - + %1MB के <strong>%2</strong> विभाजन पर flag <strong>%3</strong> सेट किए जा रहे हैं। Setting flags <strong>%1</strong> on new partition. - + नए विभाजन पर flag <strong>%1</strong> सेट किए जा रहे हैं। The installer failed to set flags on partition %1. - + इंस्टॉलर विभाजन %1 पर flag सेट करने में विफल रहा। @@ -2274,42 +2277,42 @@ Output: Set password for user %1 - + उपयोक्ता %1 के लिए पासवर्ड सेट करें। Setting password for user %1. - + उपयोक्ता %1 के लिए पासवर्ड सेट किया जा रहा है। Bad destination system path. - + लक्ष्य का सिस्टम पथ गलत है। rootMountPoint is %1 - + rootMountPoint %1 है Cannot disable root account. - + रुट अकाउंट निष्क्रिय नहीं किया जा सकता । passwd terminated with error code %1. - + passwd त्रुटि कोड %1 के साथ समाप्त। Cannot set password for user %1. - + उपयोक्ता %1 के लिए पासवर्ड सेट नहीं किया जा सकता। usermod terminated with error code %1. - + usermod त्रुटि कोड %1 के साथ समाप्त। @@ -2317,37 +2320,37 @@ Output: Set timezone to %1/%2 - + समय क्षेत्र %1%2 पर सेट करें Cannot access selected timezone path. - + चयनित समय क्षेत्र पथ तक पहुँचा नहीं जा सका। Bad path: %1 - + गलत पथ: %1 Cannot set timezone. - + समय क्षेत्र सेट नहीं हो सका। Link creation failed, target: %1; link name: %2 - + लिंक बनाना विफल, लक्ष्य: %1; लिंक का नाम: %2 Cannot set timezone, - + समय क्षेत्र सेट नहीं हो सका। Cannot open /etc/timezone for writing - + राइट करने हेतु /etc /timezone खोला नहीं जा सका। @@ -2364,7 +2367,7 @@ Output: %L1 / %L2 slide counter, %1 of %2 (numeric) - + %L1 / %L2 @@ -2372,7 +2375,7 @@ Output: This is an overview of what will happen once you start the install procedure. - + यह अवलोकन है कि इंस्टॉल शुरू होने के बाद क्या होगा। @@ -2380,7 +2383,7 @@ Output: Summary - सारांश + सार @@ -2505,33 +2508,33 @@ Output: Your username is too long. - + आपका उपयोक्ता नाम बहुत लंबा है। Your username contains invalid characters. Only lowercase letters and numbers are allowed. - + आपके होस्ट नाम में अमान्य अक्षर हैं । केवल lowercase अक्षरों व संख्याओं की ही अनुमति है । Your hostname is too short. - + आपका होस्ट नाम बहुत छोटा है। Your hostname is too long. - + आपका होस्ट नाम बहुत लंबा है। Your hostname contains invalid characters. Only letters, numbers and dashes are allowed. - + आपके होस्ट नाम में अमान्य अक्षर हैं । केवल अक्षरों, संख्याओं व dash की ही अनुमति है । Your passwords do not match! - + आपके कूटशब्द मेल नहीं खाते! @@ -2539,7 +2542,7 @@ Output: Users - + उपयोक्ता @@ -2552,27 +2555,27 @@ Output: &Language: - + भाषा (&L): &Release notes - + रिलीज़ नोट्स (&R) &Known issues - + ज्ञात समस्याएँ (&K) &Support - + सहायता (&S) &About - + बारे में (&A) @@ -2605,7 +2608,7 @@ Output: Welcome - स्वागतं + स्वागतं \ No newline at end of file diff --git a/lang/calamares_is.ts b/lang/calamares_is.ts index e4ae4228e..bda81784f 100644 --- a/lang/calamares_is.ts +++ b/lang/calamares_is.ts @@ -50,7 +50,7 @@ Blank Page - + Auð síða @@ -356,7 +356,7 @@ Uppsetningarforritið mun hætta og allar breytingar tapast. <strong>Manual partitioning</strong><br/>You can create or resize partitions yourself. - <strong>Handvirk disksneiðing</strong><br/>Þú getur búið til eða breytt stærð disksneiða sjálf(ur). + <strong>Handvirk disksneiðing</strong><br/>Þú getur búið til eða breytt stærð disksneiða sjálft. @@ -1469,7 +1469,7 @@ Uppsetningarforritið mun hætta og allar breytingar tapast. Unknown error - + Óþekkt villa @@ -2582,7 +2582,7 @@ Output: <h1>Welcome to the Calamares installer for %1.</h1> - <h1>Velkomin(n) til Calamares uppsetningar fyrir %1</h1> + <h1>Velkomin til Calamares uppsetningar fyrir %1</h1> diff --git a/lang/calamares_it_IT.ts b/lang/calamares_it_IT.ts index 107597116..2d60d6920 100644 --- a/lang/calamares_it_IT.ts +++ b/lang/calamares_it_IT.ts @@ -50,7 +50,7 @@ Blank Page - + Pagina Vuota @@ -192,17 +192,17 @@ Calamares Initialization Failed - + Inizializzazione di Calamares Fallita %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + %1 non può essere installato. Calamares non è stato in grado di caricare tutti i moduli configurati. Questo è un problema del modo in cui Calamares viene utilizzato dalla distribuzione. <br/>The following modules could not be loaded: - + <br/>Non è stato possibile caricare il seguente modulo: @@ -1663,7 +1663,7 @@ Il programma d'installazione sarà terminato e tutte le modifiche andranno Cre&ate - + Crea diff --git a/lang/calamares_ja.ts b/lang/calamares_ja.ts index 4e14afbfd..bafc53eee 100644 --- a/lang/calamares_ja.ts +++ b/lang/calamares_ja.ts @@ -50,7 +50,7 @@ Blank Page - + 空白のページ @@ -192,7 +192,7 @@ Calamares Initialization Failed - + Calamares によるインストールに失敗しました。 @@ -202,7 +202,7 @@ <br/>The following modules could not be loaded: - + <br/>以下のモジュールがロードできませんでした。: @@ -508,12 +508,12 @@ The installer will quit and all changes will be lost. The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined. - + コマンドがホスト環境で実行される際、rootのパスの情報が必要になりますが、root のマウントポイントが定義されていません。 The command needs to know the user's name, but no username is defined. - + ユーザー名が必要ですが、定義されていません。 @@ -1664,7 +1664,7 @@ The installer will quit and all changes will be lost. Cre&ate - + 作成(&a) @@ -1689,7 +1689,7 @@ The installer will quit and all changes will be lost. Can not create new partition - + 新しいパーティションを作成できません @@ -1840,7 +1840,7 @@ The installer will quit and all changes will be lost. Saving files for later ... - + 後でファイルを保存する... diff --git a/lang/calamares_ko.ts b/lang/calamares_ko.ts index 00bc40c82..1b0d2707d 100644 --- a/lang/calamares_ko.ts +++ b/lang/calamares_ko.ts @@ -4,17 +4,17 @@ The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. - + 이 시스템의 <strong>부트 환경</strong>입니다. <br> <br> 오래된 x86 시스템은 <strong>BIOS</strong>만을 지원합니다. <br> 최근 시스템은 주로 <strong>EFI</strong>을(를) 사용하지만, 호환 모드로 시작한 경우 BIOS로 나타날 수도 있습니다. This system was started with an <strong>EFI</strong> boot environment.<br><br>To configure startup from an EFI environment, this installer must deploy a boot loader application, like <strong>GRUB</strong> or <strong>systemd-boot</strong> on an <strong>EFI System Partition</strong>. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own. - + 이 시스템은 <strong>EFI</strong> 부트 환경에서 시동되었습니다. <br> <br> EFI 환경에서의 시동에 대해 설정하려면, <strong>EFI 시스템 파티션</strong>에 <strong>GRUB</strong>나 <strong>systemd-boot</strong>와 같은 부트 로더 애플리케이션을 배치해야 합니다. 이 과정은 자동으로 진행됩니다. 단, 수동 파티셔닝을 선택할 경우, EFI 시스템 파티션을 직접 선택 또는 작성해야 합니다. This system was started with a <strong>BIOS</strong> boot environment.<br><br>To configure startup from a BIOS environment, this installer must install a boot loader, like <strong>GRUB</strong>, either at the beginning of a partition or on the <strong>Master Boot Record</strong> near the beginning of the partition table (preferred). This is automatic, unless you choose manual partitioning, in which case you must set it up on your own. - + 이 시스템은 <strong>BIOS 부트 환경</strong>에서 시동되었습니다. <br> <br> BIOS 환경에서의 시동에 대해 설정하려면, 파티션의 시작 위치 또는 파티션 테이블의 시작 위치 근처(권장)에 있는 <strong>마스터 부트 레코드</strong>에 <strong>GRUB</strong>과 같은 부트 로더를 설치해야 합니다. 이 과정은 자동으로 진행됩니다. 단, 수동 파티셔닝을 선택할 경우, 사용자가 직접 설정을 해야 합니다. @@ -50,7 +50,7 @@ Blank Page - + 빈 페이지 @@ -58,7 +58,7 @@ Form - + 형식 @@ -84,7 +84,7 @@ none - + 없음 @@ -123,12 +123,12 @@ Run command %1 %2 - + 커맨드 %1 %2 실행 Running command %1 %2 - + 커맨드 %1 %2 실행 중 @@ -192,17 +192,17 @@ Calamares Initialization Failed - + Calamares 초기화 실패 %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + %1 이(가) 설치될 수 없습니다. Calamares가 모든 구성된 모듈을 불러올 수 없었습니다. 이것은 Calamares가 분포에 의해 사용되는 방식에서 비롯된 문제입니다. <br/>The following modules could not be loaded: - + 다음 모듈 불러오기 실패: @@ -244,7 +244,7 @@ The installer will quit and all changes will be lost. The %1 installer is about to make changes to your disk in order to install %2.<br/><strong>You will not be able to undo these changes.</strong> - + %1 인스톨러가 %2를 설치하기 위해 사용자의 디스크의 내용을 변경하려고 합니다. <br/> <strong>이 변경 작업은 되돌릴 수 없습니다.</strong> @@ -346,7 +346,7 @@ The installer will quit and all changes will be lost. Form - + 형식 @@ -867,7 +867,7 @@ The installer will quit and all changes will be lost. Form - + 형식 @@ -933,7 +933,7 @@ The installer will quit and all changes will be lost. Form - + 형식 @@ -1072,7 +1072,7 @@ The installer will quit and all changes will be lost. Form - + 형식 @@ -1477,7 +1477,7 @@ The installer will quit and all changes will be lost. Form - + 형식 @@ -1495,7 +1495,7 @@ The installer will quit and all changes will be lost. Form - + 형식 @@ -1643,7 +1643,7 @@ The installer will quit and all changes will be lost. Form - + 형식 @@ -1813,7 +1813,7 @@ The installer will quit and all changes will be lost. Form - + 형식 @@ -1965,7 +1965,7 @@ Output: Form - + 형식 @@ -2443,7 +2443,7 @@ Output: Form - + 형식 @@ -2550,7 +2550,7 @@ Output: Form - + 형식 diff --git a/lang/calamares_pt_BR.ts b/lang/calamares_pt_BR.ts index c83013ce3..84302178a 100644 --- a/lang/calamares_pt_BR.ts +++ b/lang/calamares_pt_BR.ts @@ -50,7 +50,7 @@ Blank Page - + Página em Branco @@ -192,17 +192,17 @@ Calamares Initialization Failed - + Falha na inicialização do Calamares %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + %1 não pôde ser instalado. O Calamares não conseguiu carregar todos os módulos configurados. Este é um problema com o modo em que o Calamares está sendo utilizado pela distribuição. <br/>The following modules could not be loaded: - + <br/>Os seguintes módulos não puderam ser carregados: @@ -319,7 +319,7 @@ O instalador será fechado e todas as alterações serão perdidas. This computer does not satisfy the minimum requirements for installing %1.<br/>Installation cannot continue. <a href="#details">Details...</a> Este computador não satisfaz os requisitos mínimos para instalar %1. -A instalação não pode continuar.<a href="#details">Detalhes...</a> +A instalação não pode continuar. Detalhes: @@ -515,7 +515,7 @@ A instalação pode continuar, mas alguns recursos podem ser desativados. The command needs to know the user's name, but no username is defined. - + O comando precisa saber do nome do usuário, mas nenhum nome de usuário foi definido. @@ -1665,7 +1665,7 @@ A instalação pode continuar, mas alguns recursos podem ser desativados. Cre&ate - + Cri&ar @@ -1841,17 +1841,17 @@ A instalação pode continuar, mas alguns recursos podem ser desativados. Saving files for later ... - + Salvando arquivos para mais tarde... No files configured to save for later. - + Nenhum arquivo configurado para ser salvo mais tarde. Not all of the configured files could be preserved. - + Nem todos os arquivos configurados puderam ser preservados. diff --git a/lang/calamares_ru.ts b/lang/calamares_ru.ts index 626b4cc44..2c05acdc9 100644 --- a/lang/calamares_ru.ts +++ b/lang/calamares_ru.ts @@ -50,7 +50,7 @@ Blank Page - + Пустая страница @@ -192,7 +192,7 @@ Calamares Initialization Failed - + Ошибка инициализации Calamares @@ -202,7 +202,7 @@ <br/>The following modules could not be loaded: - + <br/>Не удалось загрузить следующие модули: @@ -512,7 +512,7 @@ The installer will quit and all changes will be lost. The command needs to know the user's name, but no username is defined. - + Команде необходимо знать имя пользователя, но оно не задано. @@ -937,7 +937,7 @@ The installer will quit and all changes will be lost. <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style=" font-style:italic;">Done</span> or close the installer.</p></body></html> - + <html><head/><body><p>Если этот флажок установлен, ваша система будет перезагружена сразу после нажатия кнопки <span style=" font-style:italic;">Готово</span> или закрытия инсталлятора.</p></body></html> @@ -952,7 +952,7 @@ The installer will quit and all changes will be lost. <h1>Installation Failed</h1><br/>%1 has not been installed on your computer.<br/>The error message was: %2. - + <h1>Сбой установки</h1><br/>Не удалось установить %1 на ваш компьютер.<br/>Сообщение об ошибке: %2. @@ -1343,7 +1343,7 @@ The installer will quit and all changes will be lost. The password is just rotated old one - + Новый пароль — это просто перевёрнутый старый diff --git a/lang/calamares_uk.ts b/lang/calamares_uk.ts index 22a486857..2c4225f56 100644 --- a/lang/calamares_uk.ts +++ b/lang/calamares_uk.ts @@ -1244,7 +1244,7 @@ The installer will quit and all changes will be lost. Password is too weak - + Пароль надто ненадійний @@ -1274,12 +1274,13 @@ The installer will quit and all changes will be lost. The password is too similar to the old one - + Цей пароль надто схожий на попередній The password contains the user name in some form - + Цей пароль якимось чином містить ім'я користувача + @@ -1339,7 +1340,7 @@ The installer will quit and all changes will be lost. The password is too short - + Цей пароль занадто короткий @@ -1469,7 +1470,7 @@ The installer will quit and all changes will be lost. Unknown error - + Невідома помилка From 28f0ba4eeac2763031abe5e7b350bc1f9a11d8a9 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 6 Aug 2018 05:15:48 -0400 Subject: [PATCH 058/112] i18n: [desktop] Automatic merge of Transifex translations --- calamares.desktop | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/calamares.desktop b/calamares.desktop index 42373404d..9c865b60b 100644 --- a/calamares.desktop +++ b/calamares.desktop @@ -57,9 +57,10 @@ GenericName[fr]=Installateur système Comment[fr]=Calamares - Installateur système Name[fr]=Installer le système Name[gl]=Instalación do Sistema -Icon[he]=קלמארס +Icon[he]=calamares GenericName[he]=אשף התקנה -Comment[he]=קלמארס - אשף התקנה +Comment[he]=Calamares - אשף התקנה +Name[he]=התקנת מערכת Icon[hi]=calamares GenericName[hi]=सिस्टम इंस्टॉलर Comment[hi]=Calamares — सिस्टम इंस्टॉलर From 8c32fc75a1fdf71422fd1a594b07ae27746342f9 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 6 Aug 2018 05:15:49 -0400 Subject: [PATCH 059/112] i18n: [dummypythonqt] Automatic merge of Transifex translations --- .../lang/pt_BR/LC_MESSAGES/dummypythonqt.mo | Bin 993 -> 1007 bytes .../lang/pt_BR/LC_MESSAGES/dummypythonqt.po | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.mo b/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.mo index e0ede8c3629bb0469631ab500bac106fba377f53..96931f5ac7940f97334c3071edcafadb3943f177 100644 GIT binary patch delta 98 zcmaFJ{+@k8i0Ls#28IM67GPjtP-kXfFa^>UK$;Io=K*PHAYBWkX98(UAb;z|PHjdm mGhIUq1p{*{6SK+t7(ID?6N?TnPs~vW&de!G+|0&wn-KsPz7wSY delta 84 zcmaFQ{*Zk_i0KYS28IM67GPjtkYr|HFa^?DK$;IoCje<_Ae|4TyMeSNkiUFmr#2&( Ysji`!f}x?6iNWN3jGmiCnQk!x01*`pzyJUM diff --git a/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.po b/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.po index 4ed4e7c28..211949087 100644 --- a/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.po +++ b/src/modules/dummypythonqt/lang/pt_BR/LC_MESSAGES/dummypythonqt.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-05-16 11:40-0400\n" +"POT-Creation-Date: 2018-06-18 07:46-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Guilherme , 2017\n" +"Last-Translator: Guilherme Marçal Silva , 2017\n" "Language-Team: Portuguese (Brazil) (https://www.transifex.com/calamares/teams/20061/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" From 12b668f4ee02c2cae67fbbd4abacb98558b76c88 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 6 Aug 2018 05:15:49 -0400 Subject: [PATCH 060/112] i18n: [python] Automatic merge of Transifex translations --- lang/python/he/LC_MESSAGES/python.mo | Bin 1366 -> 1561 bytes lang/python/he/LC_MESSAGES/python.po | 26 +++++++++++++------------- lang/python/is/LC_MESSAGES/python.mo | Bin 1066 -> 959 bytes lang/python/is/LC_MESSAGES/python.po | 8 ++++---- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lang/python/he/LC_MESSAGES/python.mo b/lang/python/he/LC_MESSAGES/python.mo index c374160129dd364fc87203d66d9cc3beeb22ebbc..17ce90b750edae9a7c269d111a59dfce2a7729fd 100644 GIT binary patch delta 636 zcmaKoyGjE=6ozM$tR`Lx?=h%M6WB%AC|X+h0#;%nh_Jc|2_zdx)*@A2KqPTD$YRuJ zk;KK$7tq32@KlO|m5qhiS@=)lEnqy$&$n~VnK}Q=ZJ#?(ydMr!7$O8sK?XDkT|gop zpdsiH8iigz8I;=jX>bv_7&r?W;2c;2$G~e)_Ay4_4Ayu4_MCTcfw4_C8DK1o!V0(t zCO{O}8+Zk(GGiL}4B`wHgm7Lfgy~)grSHJDR^WWrQ@(i`Su-=)9n<28R65S{g}fEd z*mbEES=Vz}ldmTAWKQ4G%@kkCC$)k|UT*kyrBIbze06HtFaG)E8hM-!sEkyVD&%R5 zjs>Yf9VLfT34NV)^x2Xe>Hq5gdmS!1zb9}EIKzlC*5ij}qWv}&lr zg@=|pT4B(kQ)&`CoKyA3ZilCC-BHD~WqEv}OI`T?rxw;~co`2y8yr?#+Q;un`wC4u OY+V3PC5*asq_Gb>p!skB delta 408 zcmZXOze>Yk6i07rJ}W8(rLI7N zI3laKjF<5yuH!a#aw7M*M*lD|%74WT`Y&7(*^mWSHjP)JU!, 2017\n" +"Last-Translator: Yaron Shahrabani , 2017\n" "Language-Team: Hebrew (https://www.transifex.com/calamares/teams/20061/he/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,7 +20,7 @@ msgstr "" #: src/modules/umount/main.py:40 msgid "Unmount file systems." -msgstr "" +msgstr "ניתוק עיגון מערכות קבצים." #: src/modules/dummypython/main.py:44 msgid "Dummy python job." @@ -32,31 +32,31 @@ msgstr "צעד דמה של Python {}" #: src/modules/machineid/main.py:35 msgid "Generate machine-id." -msgstr "חולל מספר סידורי של המכונה." +msgstr "לייצר מספר סידורי של המכונה." #: src/modules/packages/main.py:62 #, python-format msgid "Processing packages (%(count)d / %(total)d)" -msgstr "מעבד חבילות (%(count)d/%(total)d)" +msgstr "החבילות מעובדות (%(count)d/%(total)d)" #: src/modules/packages/main.py:64 src/modules/packages/main.py:74 msgid "Install packages." -msgstr "התקן חבילות." +msgstr "התקנת חבילות." #: src/modules/packages/main.py:67 #, python-format msgid "Installing one package." msgid_plural "Installing %(num)d packages." -msgstr[0] "מתקין חבילה אחת." -msgstr[1] "מתקין %(num)d חבילות." -msgstr[2] "מתקין %(num)d חבילות." -msgstr[3] "מתקין %(num)d חבילות." +msgstr[0] "מותקנת חבילה אחת." +msgstr[1] "מותקנות %(num)d חבילות." +msgstr[2] "מותקנות %(num)d חבילות." +msgstr[3] "מותקנות %(num)d חבילות." #: src/modules/packages/main.py:70 #, python-format msgid "Removing one package." msgid_plural "Removing %(num)d packages." -msgstr[0] "מסיר חבילה אחת." -msgstr[1] "מסיר %(num)d חבילות." -msgstr[2] "מסיר %(num)d חבילות." -msgstr[3] "מסיר %(num)d חבילות." +msgstr[0] "מתבצעת הסרה של חבילה אחת." +msgstr[1] "מתבצעת הסרה של %(num)d חבילות." +msgstr[2] "מתבצעת הסרה של %(num)d חבילות." +msgstr[3] "מתבצעת הסרה של %(num)d חבילות." diff --git a/lang/python/is/LC_MESSAGES/python.mo b/lang/python/is/LC_MESSAGES/python.mo index 12b4043e36654c46edaa7cee8c4a61c7b09f9428..ae0776f9481aef5044b245f9bd4fd5adf2db2fb3 100644 GIT binary patch delta 231 zcmZ3*v7f#Eo)F7a1|VPqVi_Rz0b*_-t^r~YSOLU>K)e!&O@Mee5NiYR2Ou^8Vi`sT z22mjG3#8WraWW7K0Qthq3=DceS_Md}0_k8VzY<7`0r@L{G*GD~0}GJD1jHZ!6k}io zvk(NxVIVM>g>k8HXkKo9XLQsT`m>>Q1CSPAV5n!93S{U36)XeNszCZGl>Zw@ z1NAbn12HQQ1Gx-rK+FQfAjg6L6NG}0E~UA-l?nxwB^mj73R(F{dJHHc#U-f)3e~j? u?x}gHMTsS;3b~2N8JTQ(sk)gddJ|VH-JHz0fzcX83$cbk%$O|1JPiQutU%KM diff --git a/lang/python/is/LC_MESSAGES/python.po b/lang/python/is/LC_MESSAGES/python.po index eeb2989b9..bf607b024 100644 --- a/lang/python/is/LC_MESSAGES/python.po +++ b/lang/python/is/LC_MESSAGES/python.po @@ -20,19 +20,19 @@ msgstr "" #: src/modules/umount/main.py:40 msgid "Unmount file systems." -msgstr "" +msgstr "Aftengja skráarkerfi." #: src/modules/dummypython/main.py:44 msgid "Dummy python job." -msgstr "Dummy python job." +msgstr "" #: src/modules/dummypython/main.py:97 msgid "Dummy python step {}" -msgstr "Dummy python step {}" +msgstr "" #: src/modules/machineid/main.py:35 msgid "Generate machine-id." -msgstr "Generate machine-id." +msgstr "" #: src/modules/packages/main.py:62 #, python-format From 1cbfa9d693a0f00fd3e007604cc65e9ad69abe54 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Aug 2018 04:49:13 -0400 Subject: [PATCH 061/112] [partition] Simplify code for sizing --- .../partition/core/PartitionActions.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index d654edf12..999847e37 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -114,19 +114,11 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass defaultFsType = "ext4"; // Partition sizes are expressed in MiB, should be multiples of - // the logical sector size (usually 512B). - int uefisys_part_size = 0; - int empty_space_size = 0; - if ( isEfi ) - { - uefisys_part_size = 300; - empty_space_size = 2; - } - else - { - // we start with a 1MiB offset before the first partition - empty_space_size = 1; - } + // the logical sector size (usually 512B). EFI starts with 2MiB + // empty and a 300MiB EFI boot partition, while BIOS starts at + // the 1MiB boundary (usually sector 2048). + int uefisys_part_size = isEfi ? 300 : 0; + int empty_space_size = isEfi ? 2 : 1; qint64 firstFreeSector = MiBtoBytes(empty_space_size) / dev->logicalSize() + 1; From 59fea041b601af942833880506822a50ec755407 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Aug 2018 05:16:46 -0400 Subject: [PATCH 062/112] [partition] Fix up calculations of sectors in auto-partition - Calculating first free sector had an off-by-one so that partitioning would start at 2049. - EFI boot partition grew 1 sector larger than desired. - While here, align everything to 1MiB boundaries as well. FIXES #1008 --- .../partition/core/PartitionActions.cpp | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 999847e37..87c9d6e72 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -101,6 +101,24 @@ swapSuggestion( const qint64 availableSpaceB ) return suggestedSwapSizeB; } +constexpr qint64 +alignBytesToBlockSize( qint64 bytes, qint64 blocksize ) +{ + Q_ASSERT( bytes >= 0 ); + Q_ASSERT( blocksize > 0 ); + qint64 blocks = bytes / blocksize; + Q_ASSERT( blocks >= 0 ); + + if ( blocks * blocksize != bytes ) + ++blocks; + return blocks * blocksize; +} + +constexpr qint64 +bytesToSectors( qint64 bytes, qint64 blocksize ) +{ + return alignBytesToBlockSize( alignBytesToBlockSize( bytes, blocksize), MiBtoBytes(1) ) / blocksize; +} void doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPassphrase ) @@ -120,11 +138,20 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass int uefisys_part_size = isEfi ? 300 : 0; int empty_space_size = isEfi ? 2 : 1; - qint64 firstFreeSector = MiBtoBytes(empty_space_size) / dev->logicalSize() + 1; + // Since sectors count from 0, if the space is 2048 sectors in size, + // the first free sector has number 2048 (and there are 2048 sectors + // before that one, numbered 0..2047). + qint64 firstFreeSector = bytesToSectors( MiBtoBytes(empty_space_size), dev->logicalSize() ); if ( isEfi ) { - qint64 lastSector = firstFreeSector + ( MiBtoBytes(uefisys_part_size) / dev->logicalSize() ); + qint64 efiSectorCount = bytesToSectors( MiBtoBytes(uefisys_part_size), dev->logicalSize() ); + Q_ASSERT( efiSectorCount > 0 ); + + // Since sectors count from 0, and this partition is created starting + // at firstFreeSector, we need efiSectorCount sectors, numbered + // firstFreeSector..firstFreeSector+efiSectorCount-1. + qint64 lastSector = firstFreeSector + efiSectorCount - 1; core->createPartitionTable( dev, PartitionTable::gpt ); Partition* efiPartition = KPMHelpers::createNewPartition( dev->partitionTable(), From 8ed26e537f73959e295e82b4cc51540478393204 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Aug 2018 05:26:55 -0400 Subject: [PATCH 063/112] [partition] Fix swap maximum size - The existing calculation comment says "maximum 10% of disk" but the calculation itself uses 110%. --- src/modules/partition/core/PartitionActions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 87c9d6e72..130f5ab01 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -90,7 +90,7 @@ swapSuggestion( const qint64 availableSpaceB ) suggestedSwapSizeB *= overestimationFactor; // don't use more than 10% of available space - qreal maxSwapDiskRatio = 1.10; + qreal maxSwapDiskRatio = 0.10; qint64 maxSwapSizeB = availableSpaceB * maxSwapDiskRatio; if ( suggestedSwapSizeB > maxSwapSizeB ) suggestedSwapSizeB = maxSwapSizeB; From f10bab8a3af9c3504cf566468e5e4f9ec219a0fe Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Aug 2018 05:29:19 -0400 Subject: [PATCH 064/112] [partition] Minor code-styling --- src/modules/partition/core/PartitionActions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 130f5ab01..6db23c00a 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -96,7 +96,7 @@ swapSuggestion( const qint64 availableSpaceB ) suggestedSwapSizeB = maxSwapSizeB; } - cDebug() << "Suggested swap size:" << suggestedSwapSizeB / 1024. / 1024. /1024. << "GiB"; + cDebug() << "Suggested swap size:" << suggestedSwapSizeB / 1024. / 1024. / 1024. << "GiB"; return suggestedSwapSizeB; } From 238a1e812f999fad6f98fff750cf4a086cec8495 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Aug 2018 05:58:41 -0400 Subject: [PATCH 065/112] [partition] Reduce the fudge-factor for swap size - Reported by Bill Auger (I think), a 15GiB disk wouldn't hold a 8.9GiB root plus 4GiB swap -- due to 10% overprovisioning of swap, plus the 2.1GiB fudge factor. --- src/modules/partition/core/PartitionActions.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 6db23c00a..68ad85cf2 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -181,8 +181,11 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass { qint64 availableSpaceB = ( dev->totalLogical() - firstFreeSector ) * dev->logicalSize(); suggestedSwapSizeB = swapSuggestion( availableSpaceB ); + // Space required by this installation is what the distro claims is needed + // (via global configuration) plus the swap size plus a fudge factor of + // 0.6GiB (this was 2.1GiB up to Calamares 3.2.2). qint64 requiredSpaceB = - GiBtoBytes( gs->value( "requiredStorageGB" ).toDouble() + 0.1 + 2.0 ) + + GiBtoBytes( gs->value( "requiredStorageGB" ).toDouble() + 0.6 ) + suggestedSwapSizeB; // If there is enough room for ESP + root + swap, create swap, otherwise don't. From bc4407360d8be0fe6460093fdc5666be17ba9002 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 6 Aug 2018 11:06:28 -0400 Subject: [PATCH 066/112] Add a changelog --- CHANGES | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 CHANGES diff --git a/CHANGES b/CHANGES new file mode 100644 index 000000000..7fd9a3cff --- /dev/null +++ b/CHANGES @@ -0,0 +1,49 @@ +This is the changelog for Calamares. For each release, the major changes and +contributors are listed. Note that Calamares does not have a historical +changelog -- this log starts with version 3.2.0. The release notes on the +website will have to do for older versions. + += 3.2.2 (unreleased) = + +== Core == + + * Contributions from the following people (alphabetically by first name): + - artoo@cromnix.org + - Caio Carvalho + * Example configurations are **no longer installed** by default. + The default setting for *INSTALL_CONFIG* has changed. Distributions + are strongly encouraged to write their own configuration files and + not rely on the example configuration files. Example configurations + may change unpredictably. + * It is now possible to express module dependencies through the + *requiredModules* key in `module.desc`. All of the required modules + for a given module must occur in the sequence **before** the module + requiring them. None of the core modules use this facility. + * The search paths for QML files, branding descriptors and module + descriptors have been revamped and now self-document in the log. + * A new `ci/RELEASE.sh` script has been added to streamline releases; + it is not guaranteed to work anywhere in particular though. + +== Modules == + + * When multiple modules are mutually exclusive, or don't make sense + to enable concurrectly, a new `USE_` framework has been added + to CMake to simplify the selection of modules. This is in addition + to the existing `SKIP_MODULES` mechanism. + * A new module has been added to the core which can configure openrc + services. To make services configuration consistent: + - The *services* module has been **renamed** *services-systemd*, + - The openrc module is named *services-openrc*, + - At CMake time, it is possible to select all of the services modules, + or one specific one, by setting the *USE_services* CMake variable. + By default, all of the modules are built and installed. + * The systemd-services module can now disable targets and mask both + targets and services (which will allow you to break the system with + a bad configuration). The configuration is a little more flexible + because a service (or target) name can be used on its own with + sensible defaults. + +**3.2.1** (2018-06-25) + + +**3.2.0** (2018-05-17) From b6077ce9bcd425cfc2f58268833abf9aeb68703d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Aug 2018 06:01:51 -0400 Subject: [PATCH 067/112] Changelog: document partitioning fixes --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 7fd9a3cff..6bcb46e72 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,9 @@ website will have to do for older versions. to enable concurrectly, a new `USE_` framework has been added to CMake to simplify the selection of modules. This is in addition to the existing `SKIP_MODULES` mechanism. + * Various off-by-one-sector errors in the automatic partitioning + mode have been corrected. In addition, swap space is calculated + a little more conservatively. * A new module has been added to the core which can configure openrc services. To make services configuration consistent: - The *services* module has been **renamed** *services-systemd*, From f73f4bdea23c5a31a5ad5a77f1a559fa293f49ca Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 10 Aug 2018 07:09:28 -0400 Subject: [PATCH 068/112] CI: for now, switch off PythonQt --- ci/travis-config.sh | 12 ++++++++++++ ci/travis-continuous.sh | 2 +- ci/travis-coverity.sh | 2 +- ci/travis.sh | 2 ++ 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 ci/travis-config.sh diff --git a/ci/travis-config.sh b/ci/travis-config.sh new file mode 100644 index 000000000..85e6a9790 --- /dev/null +++ b/ci/travis-config.sh @@ -0,0 +1,12 @@ +# Build configuration on Travis. +# +# Defines a CMAKE_ARGS variable for use with cmake +# +# This file is sourced by travis.sh, and exports the variables +# to the environment. +CMAKE_ARGS="\ + -DWEBVIEW_FORCE_WEBKIT=1 \ + -DKDE_INSTALL_USE_QT_SYS_PATHS=ON \ + -DWITH_PYTHONQT=OFF" + +export CMAKE_ARGS diff --git a/ci/travis-continuous.sh b/ci/travis-continuous.sh index 02994be74..42cfb4bd3 100755 --- a/ci/travis-continuous.sh +++ b/ci/travis-continuous.sh @@ -12,4 +12,4 @@ test -f $SRCDIR/CMakeLists.txt || exit 1 cd $BUILDDIR || exit 1 -cmake -DWEBVIEW_FORCE_WEBKIT=1 -DKDE_INSTALL_USE_QT_SYS_PATHS=ON $SRCDIR && make -j2 && make install DESTDIR=/build/INSTALL_ROOT +cmake $CMAKE_ARGS $SRCDIR && make -j2 && make install DESTDIR=/build/INSTALL_ROOT diff --git a/ci/travis-coverity.sh b/ci/travis-coverity.sh index 07da4ce1a..c9495cf56 100755 --- a/ci/travis-coverity.sh +++ b/ci/travis-coverity.sh @@ -21,7 +21,7 @@ tar xvf coverity_tool.tar.gz -C "$BUILDDIR/coveritytool" --strip-components 2 export PATH="$BUILDDIR/coveritytool/bin:$PATH" -cmake -DCMAKE_BUILD_TYPE=Debug -DWEBVIEW_FORCE_WEBKIT=1 -DKDE_INSTALL_USE_QT_SYS_PATHS=ON $SRCDIR || exit 1 +cmake -DCMAKE_BUILD_TYPE=Debug $CMAKE_ARGS $SRCDIR || exit 1 cov-build --dir cov-int make -j2 tar caf calamares-ci.tar.xz cov-int diff --git a/ci/travis.sh b/ci/travis.sh index c8ac49f5d..364923b9e 100755 --- a/ci/travis.sh +++ b/ci/travis.sh @@ -12,6 +12,8 @@ test -d "$D" || exit 1 test -x "$D/travis-continuous.sh" || exit 1 test -x "$D/travis-coverity.sh" || exit 1 +test -f "$D/travis-common.sh" && . "$D/travis-config.sh" + if test "$TRAVIS_EVENT_TYPE" = "cron" ; then exec "$D/travis-coverity.sh" else From f94625443396b4cbadb2170ae572951dd61d18b9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 10 Aug 2018 07:47:09 -0400 Subject: [PATCH 069/112] [branding] Document compiling .ts files FIXES #1003 --- src/branding/README.md | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/branding/README.md b/src/branding/README.md index f85ad8f67..1d816911e 100644 --- a/src/branding/README.md +++ b/src/branding/README.md @@ -44,6 +44,15 @@ file) should be enclosed in this form for translations text: qsTr("This is an example text.") ``` +If you use CMake for preparing branding for packaging, the macro +`calamares_add_branding_subdirectory()`` (see also *Project Layout*, +below) will convert the source `.ts` files to their compiled form). +If you are packaging the branding by hand, use +``` + lrelease file_en.ts [file_en_GB.ts ..] +``` +with all the language suffixes to *file*. + ## Presentation The default QML classes provided by Calamares can be used for a simple @@ -105,13 +114,6 @@ will have a top-level `CMakeLists.txt` that includes some boilerplate to find Calamares, and then adds a subdirectory which contains the actual branding component. -Adding the subdirectory can be done as follows: - - - If the directory contains files only, and optionally has a single - subdirectory lang/ which contains the translation files for the - component, then `calamares_add_branding_subdirectory()` can be - used, which takes only the name of the subdirectory. - The file layout in a typical branding component repository is: ``` @@ -127,9 +129,19 @@ The file layout in a typical branding component repository is: ... ``` +Adding the subdirectory can be done as follows: + + - If the directory contains files only, and optionally has a single + subdirectory lang/ which contains the translation files for the + component, then `calamares_add_branding_subdirectory()` can be + used, which takes only the name of the subdirectory. - If the branding component has many files which are organized into subdirectories, use the SUBDIRECTORIES argument to the CMake function to additionally install files from those subdirectories. For example, if the component places all of its images in an `img/` subdirectory, then call `calamares_add_branding_subdirectory( ... SUBDIRECTORIES img)`. It is a bad idea to include `lang/` in the SUBDIRECTORIES list. + - The `.ts` files from the `lang/` subdirectory need be be compiled + to `.qm` files before being installed. The CMake macro's do this + automatically. For manual packaging, use `lrelease` to compile + the files. From 5c50587f891fbdb738a3145f1ee030e31dba5542 Mon Sep 17 00:00:00 2001 From: Simon Quigley Date: Fri, 10 Aug 2018 13:23:31 -0500 Subject: [PATCH 070/112] Fix LUKS deployment link. --- src/modules/partition/partition.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/partition.conf b/src/modules/partition/partition.conf index a5c428e23..78ad82f10 100644 --- a/src/modules/partition/partition.conf +++ b/src/modules/partition/partition.conf @@ -56,7 +56,7 @@ defaultFileSystemType: "ext4" # 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 +# https://github.com/calamares/calamares/wiki/Deploy-LUKS # # If nothing is specified, LUKS is enabled in automated modes. #enableLuksAutomatedPartitioning: true From 22aa6dc1320bc41e7cfff4d19c8e8229b3d1fd05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sun, 12 Aug 2018 14:26:43 +0100 Subject: [PATCH 071/112] [partition] fix build with latest kpmcore. --- src/modules/partition/core/PartitionCoreModule.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index f838ab2aa..f6eba9288 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -665,7 +665,11 @@ PartitionCoreModule::scanForLVMPVs() // Update LVM::pvList LvmDevice::scanSystemLVM( physicalDevices ); +#ifdef WITH_KPMCOREGT33 + for ( auto p : LVM::pvList::list() ) +#else for ( auto p : LVM::pvList ) +#endif { m_lvmPVs << p.partition().data(); From 08d41f745bb7d55a786617c2453ad67c8e47e995 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 06:03:40 -0400 Subject: [PATCH 072/112] [partition] Remove superfluous null check delete is specified to handle nullptr gracefully. FIXES #1012 --- src/modules/partition/core/DeviceList.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/partition/core/DeviceList.cpp b/src/modules/partition/core/DeviceList.cpp index ebc40a03d..4a353efb4 100644 --- a/src/modules/partition/core/DeviceList.cpp +++ b/src/modules/partition/core/DeviceList.cpp @@ -98,8 +98,7 @@ erase(DeviceList& l, DeviceList::iterator& it) { Device* p = *it; auto r = l.erase( it ); - if (p) - delete p; + delete p; return r; } From c3cef4d9193fdca5c49376ec6d31026f650a17f1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 06:17:05 -0400 Subject: [PATCH 073/112] [displaymanager] Avoid unassigned variable If displaymanagers is not set in the job config or globally, it wasn't set at all, leading to a runtime error. Set to None, so that the regular error message will be triggered. FIXES #1002 --- src/modules/displaymanager/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 37c107334..47eb147ed 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -382,6 +382,7 @@ def run(): If a displaymanager is in the list but not installed, a debugging message is printed and the entry ignored. """ + displaymanagers = None if "displaymanagers" in libcalamares.job.configuration: displaymanagers = libcalamares.job.configuration["displaymanagers"] From 76a7c439c1a4d94a650cd7e169d4800176c179e2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 07:37:46 -0400 Subject: [PATCH 074/112] [displaymanager] Begin refactoring DM - Introduce a base-class to "do the stuff" for one specific display manager / desktop environment. --- src/modules/displaymanager/main.py | 42 +++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 47eb147ed..d45913d5c 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -23,16 +23,41 @@ # You should have received a copy of the GNU General Public License # along with Calamares. If not, see . +import abc import os -import collections import re import libcalamares import configparser -DesktopEnvironment = collections.namedtuple( - 'DesktopEnvironment', ['executable', 'desktop_file'] - ) +class DesktopEnvironment(metaclass=abc.ABCMeta): + """ + Desktop Environment base class. A subclass + implements DE maintainence for a specific DE. + """ + executable = None + desktop_file = None + + def find_desktop_environment(self, root_mount_point): + """ + Check if this environment is installed in the + target system at @p root_mount_point. + """ + return ( + os.path.exists("{!s}{!s}".format(root_mount_point, self.executable)) and + os.path.exists("{!s}/usr/share/xsessions/{!s}.desktop".format(root_mount_point, self.desktop_file)) + ) + + def __init__(self, exec, desktop): + self.executable = exec + self.desktop_file = desktop + +# Collect all the subclasses of DesktopEnvironment defined above, +desktop_environments = [ + c for c in globals().values() + if type(c) is abc.ABCMeta and issubclass(c, DesktopEnvironment) and c.desktop_file +] + desktop_environments = [ DesktopEnvironment('/usr/bin/startkde', 'plasma'), # KDE Plasma 5 @@ -63,14 +88,7 @@ def find_desktop_environment(root_mount_point): :return: """ for desktop_environment in desktop_environments: - if (os.path.exists("{!s}{!s}".format( - root_mount_point, desktop_environment.executable - ) - ) and os.path.exists( - "{!s}/usr/share/xsessions/{!s}.desktop".format( - root_mount_point, desktop_environment.desktop_file - ) - )): + if desktop_environment.find_desktop_environment(root_mount_point): return desktop_environment return None From f188c6f71b5fc4024485b005dde2b115199d7368 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 08:14:52 -0400 Subject: [PATCH 075/112] [displaymanager] Simplify DE class - The DE isn't being configured, and isn't where the complexity lies. Drop the ABC from it. --- src/modules/displaymanager/main.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index d45913d5c..e8ff86c4c 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -30,13 +30,16 @@ import libcalamares import configparser -class DesktopEnvironment(metaclass=abc.ABCMeta): +class DesktopEnvironment: """ - Desktop Environment base class. A subclass - implements DE maintainence for a specific DE. + Desktop Environment -- some utility functions for a desktop + environment (e.g. finding out if it is installed). This + is independent of the *Display Manager*, which is what + we're configuring in this module. """ - executable = None - desktop_file = None + def __init__(self, exec, desktop): + self.executable = exec + self.desktop_file = desktop def find_desktop_environment(self, root_mount_point): """ @@ -48,16 +51,6 @@ class DesktopEnvironment(metaclass=abc.ABCMeta): os.path.exists("{!s}/usr/share/xsessions/{!s}.desktop".format(root_mount_point, self.desktop_file)) ) - def __init__(self, exec, desktop): - self.executable = exec - self.desktop_file = desktop - -# Collect all the subclasses of DesktopEnvironment defined above, -desktop_environments = [ - c for c in globals().values() - if type(c) is abc.ABCMeta and issubclass(c, DesktopEnvironment) and c.desktop_file -] - desktop_environments = [ DesktopEnvironment('/usr/bin/startkde', 'plasma'), # KDE Plasma 5 From 7f47b2f9ca5970c5e9b90e735d66ff4ff896cdfc Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 08:26:30 -0400 Subject: [PATCH 076/112] [displaymanager] Introduce class for DM configuration - Much like PackageManager, this is where the actual implementation of configuration methods will end up, for each supported DM. --- src/modules/displaymanager/main.py | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index e8ff86c4c..80ad2cd72 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -86,6 +86,40 @@ def find_desktop_environment(root_mount_point): return None +class DisplayManager(metaclass=abc.ABCMeta): + """ + Display Manager -- a base class for DM configuration. + """ + name = None + executable = None + + def have_dm(self, root_mount_point): + bin_path = "{!s}/usr/bin/{!s}".format(root_mount_point, self.executable) + sbin_path = "{!s}/usr/sbin/{!s}".format(root_mount_point, self.executable) + return ( + os.path.exists(bin_path) + or os.path.exists(sbin_path) + ) + + @abc.abstractmethod + def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + """ + Configure the DM inside the given @p root_mount_point with + autologin (if @p do_autologin is True) for the given @p username. + If the DM supports it, set the default DE to @p default_desktop_environment + as well. + """ + + +# Collect all the subclasses of DisplayManager defined above, +# and index them based on the name property of each class. +display_managers = [ + (c.name, c) + for c in globals().values() + if type(c) is abc.ABCMeta and issubclass(c, DisplayManager) and c.name +] + + def have_dm(dm_name, root_mount_point): """ Checks if display manager is properly installed. From e1f7dbdbb96b59cf108747e4e94f65cdfa50e900 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 08:27:49 -0400 Subject: [PATCH 077/112] [displaymanager] Simplify do_autologin initialization --- src/modules/displaymanager/main.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 80ad2cd72..4ec7407f5 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -148,10 +148,7 @@ def set_autologin(username, :param default_desktop_environment: :param root_mount_point: """ - do_autologin = True - - if username is None: - do_autologin = False + do_autologin = (username is not None) if "mdm" == displaymanager: # Systems with MDM as Desktop Manager From 47b58083f79e7b519d38fd90491710777d561534 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 09:11:18 -0400 Subject: [PATCH 078/112] [displaymanager] Move setup_autologin to individual classes - Split the entire body of setup_autologin() to a method per implementation class. - Make the check for presence of a DM a class-method, since if it fails, instantiation is going to be useless. --- src/modules/displaymanager/main.py | 156 +++++++++++++++++++---------- 1 file changed, 101 insertions(+), 55 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 4ec7407f5..a9e8993ab 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -93,9 +93,13 @@ class DisplayManager(metaclass=abc.ABCMeta): name = None executable = None - def have_dm(self, root_mount_point): - bin_path = "{!s}/usr/bin/{!s}".format(root_mount_point, self.executable) - sbin_path = "{!s}/usr/sbin/{!s}".format(root_mount_point, self.executable) + @classmethod + def have_dm(cls, root_mount_point): + if cls.executable is None: + return True + + bin_path = "{!s}/usr/bin/{!s}".format(root_mount_point, cls.executable) + sbin_path = "{!s}/usr/sbin/{!s}".format(root_mount_point, cls.executable) return ( os.path.exists(bin_path) or os.path.exists(sbin_path) @@ -111,46 +115,11 @@ class DisplayManager(metaclass=abc.ABCMeta): """ -# Collect all the subclasses of DisplayManager defined above, -# and index them based on the name property of each class. -display_managers = [ - (c.name, c) - for c in globals().values() - if type(c) is abc.ABCMeta and issubclass(c, DisplayManager) and c.name -] +class DMmdm(DisplayManager): + name = "mdm" + executable = "mdm" - -def have_dm(dm_name, root_mount_point): - """ - Checks if display manager is properly installed. - - :param dm_name: - :param root_mount_point: - :return: - """ - bin_path = "{!s}/usr/bin/{!s}".format(root_mount_point, dm_name) - sbin_path = "{!s}/usr/sbin/{!s}".format(root_mount_point, dm_name) - return (os.path.exists(bin_path) - or os.path.exists(sbin_path) - ) - - -def set_autologin(username, - displaymanager, - default_desktop_environment, - root_mount_point): - """ - Enables automatic login for the installed desktop managers. - - :param username: - :param displaymanager: str - The displaymanager for which to configure autologin. - :param default_desktop_environment: - :param root_mount_point: - """ - do_autologin = (username is not None) - - if "mdm" == displaymanager: + def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): # Systems with MDM as Desktop Manager mdm_conf_path = os.path.join(root_mount_point, "etc/mdm/custom.conf") @@ -187,7 +156,12 @@ def set_autologin(username, else: mdm_conf.write('AutomaticLoginEnable=False\n') - if "gdm" == displaymanager: + +class DMgdm(DisplayManager): + name = "gdm" + executable = "gdm" + + def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): # Systems with GDM as Desktop Manager gdm_conf_path = os.path.join(root_mount_point, "etc/gdm/custom.conf") @@ -236,7 +210,12 @@ def set_autologin(username, userfile.write("Icon=\n") - if "kdm" == displaymanager: + +class DMkdm(DisplayManager): + name = "kdm" + executable = "kdm" + + def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): # Systems with KDM as Desktop Manager kdm_conf_path = os.path.join( root_mount_point, "usr/share/config/kdm/kdmrc" @@ -276,7 +255,12 @@ def set_autologin(username, "KDM config file {!s} does not exist".format(kdm_conf_path) ) - if "lxdm" == displaymanager: + +class DMlxdm(DisplayManager): + name = "lxdm" + executable = "lxdm" + + def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): # Systems with LXDM as Desktop Manager lxdm_conf_path = os.path.join(root_mount_point, "etc/lxdm/lxdm.conf") text = [] @@ -300,7 +284,12 @@ def set_autologin(username, "LXDM config file {!s} does not exist".format(lxdm_conf_path) ) - if "lightdm" == displaymanager: + +class DMlightdm(DisplayManager): + name = "lightdm" + executable = "lightdm" + + def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): # Systems with LightDM as Desktop Manager # Ideally, we should use configparser for the ini conf file, # but we just do a simple text replacement for now, as it @@ -342,7 +331,12 @@ def set_autologin(username, ) ) - if "slim" == displaymanager: + +class DMslim(DisplayManager): + name = "slim" + executable = "slim" + + def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): # Systems with Slim as Desktop Manager slim_conf_path = os.path.join(root_mount_point, "etc/slim.conf") text = [] @@ -369,7 +363,12 @@ def set_autologin(username, "SLIM config file {!s} does not exist".format(slim_conf_path) ) - if "sddm" == displaymanager: + +class DMsddm(DisplayManager): + name = "sddm" + executable = "sddm" + + def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): # Systems with Sddm as Desktop Manager sddm_conf_path = os.path.join(root_mount_point, "etc/sddm.conf") @@ -398,7 +397,12 @@ def set_autologin(username, with open(sddm_conf_path, 'w') as sddm_config_file: sddm_config.write(sddm_config_file, space_around_delimiters=False) - if "sysconfig" == displaymanager: + +class DMsysconfig(DisplayManager): + name = "sysconfig" + executable = None + + def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): dmauto = "DISPLAYMANAGER_AUTOLOGIN" os.system( @@ -410,8 +414,49 @@ def set_autologin(username, ) ) - return None +# Collect all the subclasses of DisplayManager defined above, +# and index them based on the name property of each class. +display_managers = [ + (c.name, c) + for c in globals().values() + if type(c) is abc.ABCMeta and issubclass(c, DisplayManager) and c.name +] + + +def have_dm(dm_name, root_mount_point): + """ + Checks if display manager is properly installed. + + :param dm_name: + :param root_mount_point: + :return: + """ + bin_path = "{!s}/usr/bin/{!s}".format(root_mount_point, dm_name) + sbin_path = "{!s}/usr/sbin/{!s}".format(root_mount_point, dm_name) + return (os.path.exists(bin_path) + or os.path.exists(sbin_path) + ) + + + +_ = """ + if "mdm" == displaymanager: + + if "gdm" == displaymanager: + + if "kdm" == displaymanager: + + if "lxdm" == displaymanager: + + if "lightdm" == displaymanager: + + if "slim" == displaymanager: + + if "sddm" == displaymanager: + + if "sysconfig" == displaymanager: +""" def run(): """ @@ -707,11 +752,12 @@ def run(): dm_setup_message = [] for dm in displaymanagers: - dm_message = set_autologin( - username, dm, - default_desktop_environment, - root_mount_point - ) + impl = [ cls for name, cls in display_managers if name == dm ] + if len(impl) == 1: + dm_message = impl[0]().set_autologin(username, default_desktop_environment, root_mount_point) + else: + dm_message = ("Can not configure {!s}".format(dm), "{!s} has {!d} implementation classes.".format(dm).format(len(impl))) + if dm_message is not None: dm_setup_message.append("{!s}: {!s}".format(*dm_message)) From cd0cdfc9af263da81abebfb4d67a00ba0c884f5d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 09:48:03 -0400 Subject: [PATCH 079/112] [displaymanager] Move basic setup to DM classes - For all the DMs that have some kind of basic setup, introduce a method in the DM class for doing just that. - The Python code now doesn't call basic setup anywhere, so this specific revision isn't going to work properly. --- src/modules/displaymanager/main.py | 300 ++++++++++++++++------------- 1 file changed, 162 insertions(+), 138 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index a9e8993ab..34f7a112b 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -114,6 +114,12 @@ class DisplayManager(metaclass=abc.ABCMeta): as well. """ + @abc.abstractmethod + def basic_setup(self): + """ + Do basic setup (e.g. users, groups, directory creation) for this DM. + """ + class DMmdm(DisplayManager): name = "mdm" @@ -156,6 +162,38 @@ class DMmdm(DisplayManager): else: mdm_conf.write('AutomaticLoginEnable=False\n') + def basic_setup(self): + if libcalamares.utils.target_env_call( + ['getent', 'group', 'mdm'] + ) != 0: + libcalamares.utils.target_env_call( + ['groupadd', '-g', '128', 'mdm'] + ) + + if libcalamares.utils.target_env_call( + ['getent', 'passwd', 'mdm'] + ) != 0: + libcalamares.utils.target_env_call( + ['useradd', + '-c', '"Linux Mint Display Manager"', + '-u', '128', + '-g', 'mdm', + '-d', '/var/lib/mdm', + '-s', '/usr/bin/nologin', + 'mdm' + ] + ) + + libcalamares.utils.target_env_call( + ['passwd', '-l', 'mdm'] + ) + libcalamares.utils.target_env_call( + ['chown', 'root:mdm', '/var/lib/mdm'] + ) + libcalamares.utils.target_env_call( + ['chmod', '1770', '/var/lib/mdm'] + ) + class DMgdm(DisplayManager): name = "gdm" @@ -211,6 +249,36 @@ class DMgdm(DisplayManager): userfile.write("Icon=\n") + def basic_setup(self): + if libcalamares.utils.target_env_call( + ['getent', 'group', 'gdm'] + ) != 0: + libcalamares.utils.target_env_call( + ['groupadd', '-g', '120', 'gdm'] + ) + + if libcalamares.utils.target_env_call( + ['getent', 'passwd', 'gdm'] + ) != 0: + libcalamares.utils.target_env_call( + ['useradd', + '-c', '"Gnome Display Manager"', + '-u', '120', + '-g', 'gdm', + '-d', '/var/lib/gdm', + '-s', '/usr/bin/nologin', + 'gdm' + ] + ) + + libcalamares.utils.target_env_call( + ['passwd', '-l', 'gdm'] + ) + libcalamares.utils.target_env_call( + ['chown', '-R', 'gdm:gdm', '/var/lib/gdm'] + ) + + class DMkdm(DisplayManager): name = "kdm" executable = "kdm" @@ -255,6 +323,33 @@ class DMkdm(DisplayManager): "KDM config file {!s} does not exist".format(kdm_conf_path) ) + def basic_setup(self): + if libcalamares.utils.target_env_call( + ['getent', 'group', 'kdm'] + ) != 0: + libcalamares.utils.target_env_call( + ['groupadd', '-g', '135', 'kdm'] + ) + + if libcalamares.utils.target_env_call( + ['getent', 'passwd', 'kdm'] + ) != 0: + libcalamares.utils.target_env_call( + ['useradd', + '-u', '135', + '-g', 'kdm', + '-d', '/var/lib/kdm', + '-s', '/bin/false', + '-r', + '-M', + 'kdm' + ] + ) + + libcalamares.utils.target_env_call( + ['chown', '-R', '135:135', 'var/lib/kdm'] + ) + class DMlxdm(DisplayManager): name = "lxdm" @@ -284,6 +379,24 @@ class DMlxdm(DisplayManager): "LXDM config file {!s} does not exist".format(lxdm_conf_path) ) + def basic_setup(self): + if libcalamares.utils.target_env_call( + ['getent', 'group', 'lxdm'] + ) != 0: + libcalamares.utils.target_env_call( + ['groupadd', '--system', 'lxdm'] + ) + + libcalamares.utils.target_env_call( + ['chgrp', '-R', 'lxdm', '/var/lib/lxdm'] + ) + libcalamares.utils.target_env_call( + ['chgrp', 'lxdm', '/etc/lxdm/lxdm.conf'] + ) + libcalamares.utils.target_env_call( + ['chmod', '+r', '/etc/lxdm/lxdm.conf'] + ) + class DMlightdm(DisplayManager): name = "lightdm" @@ -332,6 +445,41 @@ class DMlightdm(DisplayManager): ) + def basic_setup(self): + libcalamares.utils.target_env_call( + ['mkdir', '-p', '/run/lightdm'] + ) + + if libcalamares.utils.target_env_call( + ['getent', 'group', 'lightdm'] + ) != 0: + libcalamares.utils.target_env_call( + ['groupadd', '-g', '620', 'lightdm'] + ) + + if libcalamares.utils.target_env_call( + ['getent', 'passwd', 'lightdm'] + ) != 0: + libcalamares.utils.target_env_call( + ['useradd', '-c', + '"LightDM Display Manager"', + '-u', '620', + '-g', 'lightdm', + '-d', '/var/run/lightdm', + '-s', '/usr/bin/nologin', + 'lightdm' + ] + ) + + libcalamares.utils.target_env_call('passwd', '-l', 'lightdm') + libcalamares.utils.target_env_call( + ['chown', '-R', 'lightdm:lightdm', '/run/lightdm'] + ) + libcalamares.utils.target_env_call( + ['chmod', '+r' '/etc/lightdm/lightdm.conf'] + ) + + class DMslim(DisplayManager): name = "slim" executable = "slim" @@ -364,6 +512,10 @@ class DMslim(DisplayManager): ) + def basic_setup(self): + pass + + class DMsddm(DisplayManager): name = "sddm" executable = "sddm" @@ -398,6 +550,10 @@ class DMsddm(DisplayManager): sddm_config.write(sddm_config_file, space_around_delimiters=False) + def basic_setup(self): + pass + + class DMsysconfig(DisplayManager): name = "sysconfig" executable = None @@ -415,6 +571,10 @@ class DMsysconfig(DisplayManager): ) + def basic_setup(self): + pass + + # Collect all the subclasses of DisplayManager defined above, # and index them based on the name property of each class. display_managers = [ @@ -520,40 +680,6 @@ def run(): root_mount_point, "etc/lightdm/lightdm.conf" ) - if enable_basic_setup: - libcalamares.utils.target_env_call( - ['mkdir', '-p', '/run/lightdm'] - ) - - if libcalamares.utils.target_env_call( - ['getent', 'group', 'lightdm'] - ) != 0: - libcalamares.utils.target_env_call( - ['groupadd', '-g', '620', 'lightdm'] - ) - - if libcalamares.utils.target_env_call( - ['getent', 'passwd', 'lightdm'] - ) != 0: - libcalamares.utils.target_env_call( - ['useradd', '-c', - '"LightDM Display Manager"', - '-u', '620', - '-g', 'lightdm', - '-d', '/var/run/lightdm', - '-s', '/usr/bin/nologin', - 'lightdm' - ] - ) - - libcalamares.utils.target_env_call('passwd', '-l', 'lightdm') - libcalamares.utils.target_env_call( - ['chown', '-R', 'lightdm:lightdm', '/run/lightdm'] - ) - libcalamares.utils.target_env_call( - ['chmod', '+r' '/etc/lightdm/lightdm.conf'] - ) - if default_desktop_environment is not None: os.system( "sed -i -e \"s/^.*user-session=.*/user-session={!s}/\" " @@ -596,34 +722,7 @@ def run(): # Setup gdm if "gdm" in displaymanagers: if have_dm("gdm", root_mount_point): - if enable_basic_setup: - if libcalamares.utils.target_env_call( - ['getent', 'group', 'gdm'] - ) != 0: - libcalamares.utils.target_env_call( - ['groupadd', '-g', '120', 'gdm'] - ) - - if libcalamares.utils.target_env_call( - ['getent', 'passwd', 'gdm'] - ) != 0: - libcalamares.utils.target_env_call( - ['useradd', - '-c', '"Gnome Display Manager"', - '-u', '120', - '-g', 'gdm', - '-d', '/var/lib/gdm', - '-s', '/usr/bin/nologin', - 'gdm' - ] - ) - - libcalamares.utils.target_env_call( - ['passwd', '-l', 'gdm'] - ) - libcalamares.utils.target_env_call( - ['chown', '-R', 'gdm:gdm', '/var/lib/gdm'] - ) + pass else: libcalamares.utils.debug("gdm selected but not installed") displaymanagers.remove("gdm") @@ -631,38 +730,6 @@ def run(): # Setup mdm if "mdm" in displaymanagers: if have_dm("mdm", root_mount_point): - if enable_basic_setup: - if libcalamares.utils.target_env_call( - ['getent', 'group', 'mdm'] - ) != 0: - libcalamares.utils.target_env_call( - ['groupadd', '-g', '128', 'mdm'] - ) - - if libcalamares.utils.target_env_call( - ['getent', 'passwd', 'mdm'] - ) != 0: - libcalamares.utils.target_env_call( - ['useradd', - '-c', '"Linux Mint Display Manager"', - '-u', '128', - '-g', 'mdm', - '-d', '/var/lib/mdm', - '-s', '/usr/bin/nologin', - 'mdm' - ] - ) - - libcalamares.utils.target_env_call( - ['passwd', '-l', 'mdm'] - ) - libcalamares.utils.target_env_call( - ['chown', 'root:mdm', '/var/lib/mdm'] - ) - libcalamares.utils.target_env_call( - ['chmod', '1770', '/var/lib/mdm'] - ) - if default_desktop_environment is not None: os.system( "sed -i \"s|default.desktop|{!s}.desktop|g\" " @@ -678,24 +745,6 @@ def run(): # Setup lxdm if "lxdm" in displaymanagers: if have_dm("lxdm", root_mount_point): - if enable_basic_setup: - if libcalamares.utils.target_env_call( - ['getent', 'group', 'lxdm'] - ) != 0: - libcalamares.utils.target_env_call( - ['groupadd', '--system', 'lxdm'] - ) - - libcalamares.utils.target_env_call( - ['chgrp', '-R', 'lxdm', '/var/lib/lxdm'] - ) - libcalamares.utils.target_env_call( - ['chgrp', 'lxdm', '/etc/lxdm/lxdm.conf'] - ) - libcalamares.utils.target_env_call( - ['chmod', '+r', '/etc/lxdm/lxdm.conf'] - ) - if default_desktop_environment is not None: os.system( "sed -i -e \"s|^.*session=.*|session={!s}|\" " @@ -711,32 +760,7 @@ def run(): # Setup kdm if "kdm" in displaymanagers: if have_dm("kdm", root_mount_point): - if enable_basic_setup: - if libcalamares.utils.target_env_call( - ['getent', 'group', 'kdm'] - ) != 0: - libcalamares.utils.target_env_call( - ['groupadd', '-g', '135', 'kdm'] - ) - - if libcalamares.utils.target_env_call( - ['getent', 'passwd', 'kdm'] - ) != 0: - libcalamares.utils.target_env_call( - ['useradd', - '-u', '135', - '-g', 'kdm', - '-d', '/var/lib/kdm', - '-s', '/bin/false', - '-r', - '-M', - 'kdm' - ] - ) - - libcalamares.utils.target_env_call( - ['chown', '-R', '135:135', 'var/lib/kdm'] - ) + pass else: libcalamares.utils.debug("kdm selected but not installed") displaymanagers.remove("kdm") From 1c0b9e6a2a878027879e6a2c8d962f4215ec6a05 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 09:56:15 -0400 Subject: [PATCH 080/112] [displaymanager] Call basic_setup through instance - Now that basic_setup is factored out into the classes, call it via an instance before doing set_autologin. --- src/modules/displaymanager/main.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 34f7a112b..1c1585f22 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -778,7 +778,12 @@ def run(): for dm in displaymanagers: impl = [ cls for name, cls in display_managers if name == dm ] if len(impl) == 1: - dm_message = impl[0]().set_autologin(username, default_desktop_environment, root_mount_point) + dm_impl = impl[0]() # Instantiate the class that was named + dm_message = None + if enable_basic_setup: + dm_message = dm_impl.basic_setup() + if dm_message is None: + dm_message = dm_impl.set_autologin(username, default_desktop_environment, root_mount_point) else: dm_message = ("Can not configure {!s}".format(dm), "{!s} has {!d} implementation classes.".format(dm).format(len(impl))) From 383e0e4f252a7bc0f821496c55949f85d8937b31 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 10:14:29 -0400 Subject: [PATCH 081/112] [displaymanager] Refactor setting up default DE - Some DMs allow setting up the default DE. Factor that out into a method like basic_setup() and setup_autologin() and add it to the configuration chain. --- src/modules/displaymanager/main.py | 64 ++++++++++++++++++------------ 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 1c1585f22..3ff9dd350 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -119,7 +119,15 @@ class DisplayManager(metaclass=abc.ABCMeta): """ Do basic setup (e.g. users, groups, directory creation) for this DM. """ + # Some implementations do nothing + @abc.abstractmethod + def desktop_environment_setup(self, desktop_environment): + """ + Configure the given @p desktop_environment as the default one, in + the configuration files for this DM. + """ + # Many implementations do nothing class DMmdm(DisplayManager): name = "mdm" @@ -194,6 +202,15 @@ class DMmdm(DisplayManager): ['chmod', '1770', '/var/lib/mdm'] ) + def desktop_environment_setup(self, default_desktop_environment): + os.system( + "sed -i \"s|default.desktop|{!s}.desktop|g\" " + "{!s}/etc/mdm/custom.conf".format( + default_desktop_environment.desktop_file, + root_mount_point + ) + ) + class DMgdm(DisplayManager): name = "gdm" @@ -397,6 +414,15 @@ class DMlxdm(DisplayManager): ['chmod', '+r', '/etc/lxdm/lxdm.conf'] ) + def desktop_environment_setup(self, default_desktop_environment): + os.system( + "sed -i -e \"s|^.*session=.*|session={!s}|\" " + "{!s}/etc/lxdm/lxdm.conf".format( + default_desktop_environment.executable, + root_mount_point + ) + ) + class DMlightdm(DisplayManager): name = "lightdm" @@ -479,6 +505,15 @@ class DMlightdm(DisplayManager): ['chmod', '+r' '/etc/lightdm/lightdm.conf'] ) + def desktop_environment_setup(self, default_desktop_environment): + os.system( + "sed -i -e \"s/^.*user-session=.*/user-session={!s}/\" " + "{!s}".format( + default_desktop_environment.desktop_file, + lightdm_conf_path + ) + ) + class DMslim(DisplayManager): name = "slim" @@ -680,15 +715,6 @@ def run(): root_mount_point, "etc/lightdm/lightdm.conf" ) - if default_desktop_environment is not None: - os.system( - "sed -i -e \"s/^.*user-session=.*/user-session={!s}/\" " - "{!s}".format( - default_desktop_environment.desktop_file, - lightdm_conf_path - ) - ) - # configure lightdm-greeter greeter_path = os.path.join( root_mount_point, "usr/share/xgreeters" @@ -730,14 +756,7 @@ def run(): # Setup mdm if "mdm" in displaymanagers: if have_dm("mdm", root_mount_point): - if default_desktop_environment is not None: - os.system( - "sed -i \"s|default.desktop|{!s}.desktop|g\" " - "{!s}/etc/mdm/custom.conf".format( - default_desktop_environment.desktop_file, - root_mount_point - ) - ) + pass else: libcalamares.utils.debug("mdm selected but not installed") displaymanagers.remove("mdm") @@ -745,14 +764,7 @@ def run(): # Setup lxdm if "lxdm" in displaymanagers: if have_dm("lxdm", root_mount_point): - if default_desktop_environment is not None: - os.system( - "sed -i -e \"s|^.*session=.*|session={!s}|\" " - "{!s}/etc/lxdm/lxdm.conf".format( - default_desktop_environment.executable, - root_mount_point - ) - ) + pass else: libcalamares.utils.debug("lxdm selected but not installed") displaymanagers.remove("lxdm") @@ -782,6 +794,8 @@ def run(): dm_message = None if enable_basic_setup: dm_message = dm_impl.basic_setup() + if default_desktop_environment is not None and dm_message is None: + dm_message = dm_impl.desktop_environment_setup(default_desktop_environment) if dm_message is None: dm_message = dm_impl.set_autologin(username, default_desktop_environment, root_mount_point) else: From 18392cb216623ade3a3c4a23d1fdc3e58cc0144f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 10:26:59 -0400 Subject: [PATCH 082/112] [displaymanager] Refactor greeter setup - Only lightdm has support for dynamically configuring the greeter based on what is installed. Still, refactory that to something general. --- src/modules/displaymanager/main.py | 71 +++++++++++++++++------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 3ff9dd350..942a7d470 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -129,6 +129,14 @@ class DisplayManager(metaclass=abc.ABCMeta): """ # Many implementations do nothing + @abc.abstractmethod + def greeter_setup(self): + """ + Additional setup for the greeter. + """ + # Most implementations do nothing + + class DMmdm(DisplayManager): name = "mdm" executable = "mdm" @@ -514,6 +522,38 @@ class DMlightdm(DisplayManager): ) ) + def greeter_setup(self): + lightdm_conf_path = os.path.join( + root_mount_point, "etc/lightdm/lightdm.conf" + ) + + # configure lightdm-greeter + greeter_path = os.path.join( + root_mount_point, "usr/share/xgreeters" + ) + + if (os.path.exists(greeter_path)): + # configure first found lightdm-greeter + for entry in os.listdir(greeter_path): + if entry.endswith('.desktop'): + greeter = entry.split('.')[0] + libcalamares.utils.debug( + "found greeter {!s}".format(greeter) + ) + os.system( + "sed -i -e \"s/^.*greeter-session=.*" + "/greeter-session={!s}/\" {!s}".format( + greeter, + lightdm_conf_path + ) + ) + libcalamares.utils.debug( + "{!s} configured as greeter.".format(greeter) + ) + break + else: + return ("No lightdm greeter installed.") + class DMslim(DisplayManager): name = "slim" @@ -711,36 +751,7 @@ def run(): # setup lightdm if "lightdm" in displaymanagers: if have_dm("lightdm", root_mount_point): - lightdm_conf_path = os.path.join( - root_mount_point, "etc/lightdm/lightdm.conf" - ) - - # configure lightdm-greeter - greeter_path = os.path.join( - root_mount_point, "usr/share/xgreeters" - ) - - if (os.path.exists(greeter_path)): - # configure first found lightdm-greeter - for entry in os.listdir(greeter_path): - if entry.endswith('.desktop'): - greeter = entry.split('.')[0] - libcalamares.utils.debug( - "found greeter {!s}".format(greeter) - ) - os.system( - "sed -i -e \"s/^.*greeter-session=.*" - "/greeter-session={!s}/\" {!s}".format( - greeter, - lightdm_conf_path - ) - ) - libcalamares.utils.debug( - "{!s} configured as greeter.".format(greeter) - ) - break - else: - return ("No lightdm greeter installed.") + pass else: libcalamares.utils.debug("lightdm selected but not installed") displaymanagers.remove("lightdm") From 155e212616b0c0a6f0af0e4e3e63f92f1925fcfd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 10:49:17 -0400 Subject: [PATCH 083/112] [displaymanager] Call all configuration methods through instance - Make root_mount_point a parameter of the DM classes - Create instances as needed, then check if they're available - Keep instances that actually need to be configured - Clean up remaining cruft from removing old setup_autologin() with all the string-comparison magic. --- src/modules/displaymanager/main.py | 177 +++++++++-------------------- 1 file changed, 54 insertions(+), 123 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 942a7d470..559a5bcf0 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -93,20 +93,22 @@ class DisplayManager(metaclass=abc.ABCMeta): name = None executable = None - @classmethod - def have_dm(cls, root_mount_point): + def __init__(self, root_mount_point): + self.root_mount_point = root_mount_point + + def have_dm(cls): if cls.executable is None: return True - bin_path = "{!s}/usr/bin/{!s}".format(root_mount_point, cls.executable) - sbin_path = "{!s}/usr/sbin/{!s}".format(root_mount_point, cls.executable) + bin_path = "{!s}/usr/bin/{!s}".format(self.root_mount_point, cls.executable) + sbin_path = "{!s}/usr/sbin/{!s}".format(self.root_mount_point, cls.executable) return ( os.path.exists(bin_path) or os.path.exists(sbin_path) ) @abc.abstractmethod - def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + def set_autologin(self, username, do_autologin, default_desktop_environment): """ Configure the DM inside the given @p root_mount_point with autologin (if @p do_autologin is True) for the given @p username. @@ -141,9 +143,9 @@ class DMmdm(DisplayManager): name = "mdm" executable = "mdm" - def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with MDM as Desktop Manager - mdm_conf_path = os.path.join(root_mount_point, "etc/mdm/custom.conf") + mdm_conf_path = os.path.join(self.root_mount_point, "etc/mdm/custom.conf") if os.path.exists(mdm_conf_path): with open(mdm_conf_path, 'r') as mdm_conf: @@ -215,7 +217,7 @@ class DMmdm(DisplayManager): "sed -i \"s|default.desktop|{!s}.desktop|g\" " "{!s}/etc/mdm/custom.conf".format( default_desktop_environment.desktop_file, - root_mount_point + self.root_mount_point ) ) @@ -224,9 +226,9 @@ class DMgdm(DisplayManager): name = "gdm" executable = "gdm" - def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with GDM as Desktop Manager - gdm_conf_path = os.path.join(root_mount_point, "etc/gdm/custom.conf") + gdm_conf_path = os.path.join(self.root_mount_point, "etc/gdm/custom.conf") if os.path.exists(gdm_conf_path): with open(gdm_conf_path, 'r') as gdm_conf: @@ -260,7 +262,7 @@ class DMgdm(DisplayManager): if (do_autologin): accountservice_dir = "{!s}/var/lib/AccountsService/users".format( - root_mount_point + self.root_mount_point ) userfile_path = "{!s}/{!s}".format(accountservice_dir, username) if os.path.exists(accountservice_dir): @@ -308,10 +310,10 @@ class DMkdm(DisplayManager): name = "kdm" executable = "kdm" - def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with KDM as Desktop Manager kdm_conf_path = os.path.join( - root_mount_point, "usr/share/config/kdm/kdmrc" + self.root_mount_point, "usr/share/config/kdm/kdmrc" ) # Check which path is in use: SUSE does something else. # Also double-check the default setting. Pick the first @@ -320,7 +322,7 @@ class DMkdm(DisplayManager): "usr/share/config/kdm/kdmrc", "usr/share/kde4/config/kdm/kdmrc", ): - p = os.path.join(root_mount_point, candidate_kdmrc) + p = os.path.join(self.root_mount_point, candidate_kdmrc) if os.path.exists(p): kdm_conf_path = p break @@ -380,9 +382,9 @@ class DMlxdm(DisplayManager): name = "lxdm" executable = "lxdm" - def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with LXDM as Desktop Manager - lxdm_conf_path = os.path.join(root_mount_point, "etc/lxdm/lxdm.conf") + lxdm_conf_path = os.path.join(self.root_mount_point, "etc/lxdm/lxdm.conf") text = [] if os.path.exists(lxdm_conf_path): @@ -427,7 +429,7 @@ class DMlxdm(DisplayManager): "sed -i -e \"s|^.*session=.*|session={!s}|\" " "{!s}/etc/lxdm/lxdm.conf".format( default_desktop_environment.executable, - root_mount_point + self.root_mount_point ) ) @@ -436,13 +438,13 @@ class DMlightdm(DisplayManager): name = "lightdm" executable = "lightdm" - def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with LightDM as Desktop Manager # Ideally, we should use configparser for the ini conf file, # but we just do a simple text replacement for now, as it # worksforme(tm) lightdm_conf_path = os.path.join( - root_mount_point, "etc/lightdm/lightdm.conf" + self.root_mount_point, "etc/lightdm/lightdm.conf" ) text = [] @@ -524,12 +526,12 @@ class DMlightdm(DisplayManager): def greeter_setup(self): lightdm_conf_path = os.path.join( - root_mount_point, "etc/lightdm/lightdm.conf" + self.root_mount_point, "etc/lightdm/lightdm.conf" ) # configure lightdm-greeter greeter_path = os.path.join( - root_mount_point, "usr/share/xgreeters" + self.root_mount_point, "usr/share/xgreeters" ) if (os.path.exists(greeter_path)): @@ -559,9 +561,9 @@ class DMslim(DisplayManager): name = "slim" executable = "slim" - def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with Slim as Desktop Manager - slim_conf_path = os.path.join(root_mount_point, "etc/slim.conf") + slim_conf_path = os.path.join(self.root_mount_point, "etc/slim.conf") text = [] if os.path.exists(slim_conf_path): @@ -595,9 +597,9 @@ class DMsddm(DisplayManager): name = "sddm" executable = "sddm" - def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with Sddm as Desktop Manager - sddm_conf_path = os.path.join(root_mount_point, "etc/sddm.conf") + sddm_conf_path = os.path.join(self.root_mount_point, "etc/sddm.conf") sddm_config = configparser.ConfigParser(strict=False) # Make everything case sensitive @@ -633,7 +635,7 @@ class DMsysconfig(DisplayManager): name = "sysconfig" executable = None - def set_autologin(self, username, do_autologin, root_mount_point, default_desktop_environment): + def set_autologin(self, username, do_autologin, default_desktop_environment): dmauto = "DISPLAYMANAGER_AUTOLOGIN" os.system( @@ -641,7 +643,7 @@ class DMsysconfig(DisplayManager): "{!s}/etc/sysconfig/displaymanager".format( dmauto, dmauto, username if do_autologin else "", - root_mount_point + self.root_mount_point ) ) @@ -659,40 +661,6 @@ display_managers = [ ] -def have_dm(dm_name, root_mount_point): - """ - Checks if display manager is properly installed. - - :param dm_name: - :param root_mount_point: - :return: - """ - bin_path = "{!s}/usr/bin/{!s}".format(root_mount_point, dm_name) - sbin_path = "{!s}/usr/sbin/{!s}".format(root_mount_point, dm_name) - return (os.path.exists(bin_path) - or os.path.exists(sbin_path) - ) - - - -_ = """ - if "mdm" == displaymanager: - - if "gdm" == displaymanager: - - if "kdm" == displaymanager: - - if "lxdm" == displaymanager: - - if "lightdm" == displaymanager: - - if "slim" == displaymanager: - - if "sddm" == displaymanager: - - if "sysconfig" == displaymanager: -""" - def run(): """ Configure display managers. @@ -736,57 +704,23 @@ def run(): else: enable_basic_setup = False - # Setup slim - if "slim" in displaymanagers: - if not have_dm("slim", root_mount_point): - libcalamares.utils.debug("slim selected but not installed") - displaymanagers.remove("slim") - - # Setup sddm - if "sddm" in displaymanagers: - if not have_dm("sddm", root_mount_point): - libcalamares.utils.debug("sddm selected but not installed") - displaymanagers.remove("sddm") - - # setup lightdm - if "lightdm" in displaymanagers: - if have_dm("lightdm", root_mount_point): - pass + dm_impl = [] + for dm in displaymanagers: + # Find the implementation class + dm_impl = None + impl = [ cls for name, cls in display_managers if name == dm ] + if len(impl) == 1: + dm_instance = impl[0](root_mount_point) + if dm_instance.have_dm(): + dm_impl.append(dm_instance) + else: + dm_impl = None else: - libcalamares.utils.debug("lightdm selected but not installed") - displaymanagers.remove("lightdm") + libcalamares.utils.debug("{!s} has {!d} implementation classes.".format(dm).format(len(impl))) - # Setup gdm - if "gdm" in displaymanagers: - if have_dm("gdm", root_mount_point): - pass - else: - libcalamares.utils.debug("gdm selected but not installed") - displaymanagers.remove("gdm") - - # Setup mdm - if "mdm" in displaymanagers: - if have_dm("mdm", root_mount_point): - pass - else: - libcalamares.utils.debug("mdm selected but not installed") - displaymanagers.remove("mdm") - - # Setup lxdm - if "lxdm" in displaymanagers: - if have_dm("lxdm", root_mount_point): - pass - else: - libcalamares.utils.debug("lxdm selected but not installed") - displaymanagers.remove("lxdm") - - # Setup kdm - if "kdm" in displaymanagers: - if have_dm("kdm", root_mount_point): - pass - else: - libcalamares.utils.debug("kdm selected but not installed") - displaymanagers.remove("kdm") + if dm_impl is None: + libcalamares.utils.debug("{!s} selected but not installed".format(dm)) + displaymanagers.remove(dm) if username is not None: libcalamares.utils.debug( @@ -798,19 +732,16 @@ def run(): libcalamares.globalstorage.insert("displayManagers", displaymanagers) dm_setup_message = [] - for dm in displaymanagers: - impl = [ cls for name, cls in display_managers if name == dm ] - if len(impl) == 1: - dm_impl = impl[0]() # Instantiate the class that was named - dm_message = None - if enable_basic_setup: - dm_message = dm_impl.basic_setup() - if default_desktop_environment is not None and dm_message is None: - dm_message = dm_impl.desktop_environment_setup(default_desktop_environment) - if dm_message is None: - dm_message = dm_impl.set_autologin(username, default_desktop_environment, root_mount_point) - else: - dm_message = ("Can not configure {!s}".format(dm), "{!s} has {!d} implementation classes.".format(dm).format(len(impl))) + for dm in dm_impl: + dm_message = None + if enable_basic_setup: + dm_message = dm.basic_setup() + if default_desktop_environment is not None and dm_message is None: + dm_message = dm.desktop_environment_setup(default_desktop_environment) + if dm_message is None: + dm_message = dm.greeter_setup() + if dm_message is None: + dm_message = dm.set_autologin(username, do_autologin, default_desktop_environment) if dm_message is not None: dm_setup_message.append("{!s}: {!s}".format(*dm_message)) From 2d0660a54af8fde800038cc4c88b5bc0fe15c82c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 11:00:20 -0400 Subject: [PATCH 084/112] [displaymanager] Fix up missing methods - Add (empty) implementations of all the abstract methods that are not needed (or supported) by various DMs. - Order the abstract methods by calling order - Fix up have_dm --- src/modules/displaymanager/main.py | 69 ++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 559a5bcf0..b5b5bb0c1 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -96,25 +96,25 @@ class DisplayManager(metaclass=abc.ABCMeta): def __init__(self, root_mount_point): self.root_mount_point = root_mount_point - def have_dm(cls): - if cls.executable is None: + def have_dm(self): + """ + Is this DM installed in the target system? + The default implementation checks for `executable` + in the target system. + """ + if self.executable is None: return True - bin_path = "{!s}/usr/bin/{!s}".format(self.root_mount_point, cls.executable) - sbin_path = "{!s}/usr/sbin/{!s}".format(self.root_mount_point, cls.executable) + bin_path = "{!s}/usr/bin/{!s}".format(self.root_mount_point, self.executable) + sbin_path = "{!s}/usr/sbin/{!s}".format(self.root_mount_point, self.executable) return ( os.path.exists(bin_path) or os.path.exists(sbin_path) ) - @abc.abstractmethod - def set_autologin(self, username, do_autologin, default_desktop_environment): - """ - Configure the DM inside the given @p root_mount_point with - autologin (if @p do_autologin is True) for the given @p username. - If the DM supports it, set the default DE to @p default_desktop_environment - as well. - """ + # The four abstract methods below are called in the order listed here. + # They must all be implemented by subclasses, but not all of them + # actually do something for all DMs. @abc.abstractmethod def basic_setup(self): @@ -138,6 +138,15 @@ class DisplayManager(metaclass=abc.ABCMeta): """ # Most implementations do nothing + @abc.abstractmethod + def set_autologin(self, username, do_autologin, default_desktop_environment): + """ + Configure the DM inside the given @p root_mount_point with + autologin (if @p do_autologin is True) for the given @p username. + If the DM supports it, set the default DE to @p default_desktop_environment + as well. + """ + class DMmdm(DisplayManager): name = "mdm" @@ -221,6 +230,9 @@ class DMmdm(DisplayManager): ) ) + def greeter_setup(self): + pass + class DMgdm(DisplayManager): name = "gdm" @@ -305,6 +317,12 @@ class DMgdm(DisplayManager): ['chown', '-R', 'gdm:gdm', '/var/lib/gdm'] ) + def desktop_environment_setup(self, desktop_environment): + pass + + def greeter_setup(self): + pass + class DMkdm(DisplayManager): name = "kdm" @@ -377,6 +395,12 @@ class DMkdm(DisplayManager): ['chown', '-R', '135:135', 'var/lib/kdm'] ) + def desktop_environment_setup(self, desktop_environment): + pass + + def greeter_setup(self): + pass + class DMlxdm(DisplayManager): name = "lxdm" @@ -433,6 +457,9 @@ class DMlxdm(DisplayManager): ) ) + def greeter_setup(self): + pass + class DMlightdm(DisplayManager): name = "lightdm" @@ -592,6 +619,12 @@ class DMslim(DisplayManager): def basic_setup(self): pass + def desktop_environment_setup(self, desktop_environment): + pass + + def greeter_setup(self): + pass + class DMsddm(DisplayManager): name = "sddm" @@ -630,6 +663,12 @@ class DMsddm(DisplayManager): def basic_setup(self): pass + def desktop_environment_setup(self, desktop_environment): + pass + + def greeter_setup(self): + pass + class DMsysconfig(DisplayManager): name = "sysconfig" @@ -651,6 +690,12 @@ class DMsysconfig(DisplayManager): def basic_setup(self): pass + def desktop_environment_setup(self, desktop_environment): + pass + + def greeter_setup(self): + pass + # Collect all the subclasses of DisplayManager defined above, # and index them based on the name property of each class. From 59a003a41fad55b0baad04a34ac540b7975ba9a7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 11:06:49 -0400 Subject: [PATCH 085/112] [displaymanager] Expand check for no-DMs - The message refers to an empty list or unset variable, but the if only checked for unset. Also bail out if the list is empty. --- src/modules/displaymanager/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index b5b5bb0c1..183188722 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -724,7 +724,7 @@ def run(): if libcalamares.globalstorage.contains("displayManagers"): displaymanagers = libcalamares.globalstorage.value("displayManagers") - if displaymanagers is None: + if not displaymanagers: return ( "No display managers selected for the displaymanager module.", "The displaymanagers list is empty or undefined in both" From 229cc241faf874f9e4fe1cd1624f5bd3ed808fbf Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 11:10:40 -0400 Subject: [PATCH 086/112] [displaymanager] Massage do_autologin - Move getting the global setting closer to where it is used - Initialize variable --- src/modules/displaymanager/main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 183188722..21c9115f1 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -731,7 +731,6 @@ def run(): "globalstorage and displaymanager.conf." ) - username = libcalamares.globalstorage.value("autologinUser") root_mount_point = libcalamares.globalstorage.value("rootMountPoint") if "default_desktop_environment" in libcalamares.job.configuration: @@ -767,11 +766,12 @@ def run(): libcalamares.utils.debug("{!s} selected but not installed".format(dm)) displaymanagers.remove(dm) + username = libcalamares.globalstorage.value("autologinUser") if username is not None: - libcalamares.utils.debug( - "Setting up autologin for user {!s}.".format(username) - ) + do_autologin = True + libcalamares.utils.debug("Setting up autologin for user {!s}.".format(username)) else: + do_autologin = False libcalamares.utils.debug("Unsetting autologin.") libcalamares.globalstorage.insert("displayManagers", displaymanagers) From ebae7e1f476a28bd57b7d83d175ad7e156b875e1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 12:02:01 -0400 Subject: [PATCH 087/112] [displaymanager] Re-arrange initializations - Move variable initializations closer to where they are first used - Also warn if no implementations are available - Handle sysconfig as any other DM; there's no real reason to treat it specially. --- src/modules/displaymanager/main.py | 55 ++++++++++++++++++------------ 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 21c9115f1..8a9de1426 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -717,6 +717,7 @@ def run(): If a displaymanager is in the list but not installed, a debugging message is printed and the entry ignored. """ + # Get configuration settings for display managers displaymanagers = None if "displaymanagers" in libcalamares.job.configuration: displaymanagers = libcalamares.job.configuration["displaymanagers"] @@ -731,8 +732,39 @@ def run(): "globalstorage and displaymanager.conf." ) + # Get instances that are actually installed root_mount_point = libcalamares.globalstorage.value("rootMountPoint") + dm_impl = [] + dm_names = displaymanagers[:] + if ("sysconfigSetup" in libcalamares.job.configuration + and libcalamares.job.configuration["sysconfigSetup"]): + dm_names.append("sysconfig") + for dm in dm_names: + # Find the implementation class + dm_instance = None + impl = [ cls for name, cls in display_managers if name == dm ] + if len(impl) == 1: + dm_instance = impl[0](root_mount_point) + if dm_instance.have_dm(): + dm_impl.append(dm_instance) + else: + dm_instance = None + else: + libcalamares.utils.debug("{!s} has {!d} implementation classes.".format(dm).format(len(impl))) + if dm_instance is None: + libcalamares.utils.debug("{!s} selected but not installed".format(dm)) + if dm in displaymanagers: + displaymanagers.remove(dm) + + if not dm_impl: + return ( + "No display managers selected for the displaymanager module.", + "The list is empty after checking for installed display managers." + ) + + + # Pick up remaining settings if "default_desktop_environment" in libcalamares.job.configuration: entry = libcalamares.job.configuration["defaultDesktopEnvironment"] default_desktop_environment = DesktopEnvironment( @@ -748,24 +780,6 @@ def run(): else: enable_basic_setup = False - dm_impl = [] - for dm in displaymanagers: - # Find the implementation class - dm_impl = None - impl = [ cls for name, cls in display_managers if name == dm ] - if len(impl) == 1: - dm_instance = impl[0](root_mount_point) - if dm_instance.have_dm(): - dm_impl.append(dm_instance) - else: - dm_impl = None - else: - libcalamares.utils.debug("{!s} has {!d} implementation classes.".format(dm).format(len(impl))) - - if dm_impl is None: - libcalamares.utils.debug("{!s} selected but not installed".format(dm)) - displaymanagers.remove(dm) - username = libcalamares.globalstorage.value("autologinUser") if username is not None: do_autologin = True @@ -776,6 +790,7 @@ def run(): libcalamares.globalstorage.insert("displayManagers", displaymanagers) + # Do the actual configuration and collect messages dm_setup_message = [] for dm in dm_impl: dm_message = None @@ -791,10 +806,6 @@ def run(): if dm_message is not None: dm_setup_message.append("{!s}: {!s}".format(*dm_message)) - if ("sysconfigSetup" in libcalamares.job.configuration - and libcalamares.job.configuration["sysconfigSetup"]): - set_autologin(username, "sysconfig", None, root_mount_point) - if dm_setup_message: return ("Display manager configuration was incomplete", "\n".join(dm_setup_message)) From 5191400d89973f48a6a27cf536fd5c5537014a71 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 12:14:43 -0400 Subject: [PATCH 088/112] [displaymanager] Fix LightDM error message - Error tuple was not being constructed properly - Fix capitalization consistency --- src/modules/displaymanager/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 8a9de1426..464b560a6 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -581,7 +581,10 @@ class DMlightdm(DisplayManager): ) break else: - return ("No lightdm greeter installed.") + return ( + "Cannot configure LightDM", + "No LightDM greeter installed." + ) class DMslim(DisplayManager): From a83ee4984dc6f4865f0a33cb623bf6daf80b4de0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 12:28:47 -0400 Subject: [PATCH 089/112] [displaymanager] Enable translation for user-visible messages See also #991 --- src/modules/displaymanager/main.py | 47 ++++++++++++++++++------------ 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 464b560a6..4d79ccad5 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -29,6 +29,15 @@ import re import libcalamares import configparser +from libcalamares.utils import gettext_path, gettext_languages + +import gettext +_translation = gettext.translation("calamares-python", + localedir=gettext_path(), + languages=gettext_languages(), + fallback=True) +_ = _translation.gettext +_n = _translation.ngettext class DesktopEnvironment: """ @@ -364,8 +373,8 @@ class DMkdm(DisplayManager): kdm_conf.write(line) else: return ( - "Cannot write KDM configuration file", - "KDM config file {!s} does not exist".format(kdm_conf_path) + _("Cannot write KDM configuration file"), + _("KDM config file {!s} does not exist").format(kdm_conf_path) ) def basic_setup(self): @@ -426,8 +435,8 @@ class DMlxdm(DisplayManager): lxdm_conf.write(line) else: return ( - "Cannot write LXDM configuration file", - "LXDM config file {!s} does not exist".format(lxdm_conf_path) + _("Cannot write LXDM configuration file"), + _("LXDM config file {!s} does not exist").format(lxdm_conf_path) ) def basic_setup(self): @@ -501,10 +510,8 @@ class DMlightdm(DisplayManager): "#autologin-user=\n") except FileNotFoundError: return ( - "Cannot write LightDM configuration file", - "LightDM config file {!s} does not exist".format( - lightdm_conf_path - ) + _("Cannot write LightDM configuration file"), + _("LightDM config file {!s} does not exist").format(lightdm_conf_path) ) @@ -582,8 +589,8 @@ class DMlightdm(DisplayManager): break else: return ( - "Cannot configure LightDM", - "No LightDM greeter installed." + _("Cannot configure LightDM"), + _("No LightDM greeter installed.") ) @@ -614,8 +621,8 @@ class DMslim(DisplayManager): slim_conf.write(line) else: return ( - "Cannot write SLIM configuration file", - "SLIM config file {!s} does not exist".format(slim_conf_path) + _("Cannot write SLIM configuration file"), + _("SLIM config file {!s} does not exist").format(slim_conf_path) ) @@ -730,9 +737,9 @@ def run(): if not displaymanagers: return ( - "No display managers selected for the displaymanager module.", - "The displaymanagers list is empty or undefined in both" - "globalstorage and displaymanager.conf." + _("No display managers selected for the displaymanager module."), + _("The displaymanagers list is empty or undefined in both" + "globalstorage and displaymanager.conf.") ) # Get instances that are actually installed @@ -762,8 +769,8 @@ def run(): if not dm_impl: return ( - "No display managers selected for the displaymanager module.", - "The list is empty after checking for installed display managers." + _("No display managers selected for the displaymanager module."), + _("The list is empty after checking for installed display managers.") ) @@ -810,5 +817,7 @@ def run(): dm_setup_message.append("{!s}: {!s}".format(*dm_message)) if dm_setup_message: - return ("Display manager configuration was incomplete", - "\n".join(dm_setup_message)) + return ( + _("Display manager configuration was incomplete"), + "\n".join(dm_setup_message) + ) From 2ced06a0e99cc8c853944420b862370fe31b2a87 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 20 Aug 2018 12:32:45 -0400 Subject: [PATCH 090/112] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_he.ts | 64 ++++++++++++++++++++--------------------- lang/calamares_pt_BR.ts | 2 +- lang/calamares_uk.ts | 16 +++++------ 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/lang/calamares_he.ts b/lang/calamares_he.ts index 13edcfac2..b5389d5dd 100644 --- a/lang/calamares_he.ts +++ b/lang/calamares_he.ts @@ -4,7 +4,7 @@ The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. - <strong>תצורת האתחול</strong> של מערכת זו. <br><br> מערכות x86 ישנות יותר תומכות אך ורק ב <strong>BIOS</strong>.<br> מערכות חדשות משתמשות בדרך כלל ב־<strong>EFI</strong>, אך עשוית להופיע כ־BIOS אם הן מופעלות במצב תאימות לאחור. + <strong>תצורת האתחול</strong> של מערכת זו. <br><br> מערכות x86 ישנות יותר תומכות אך ורק ב־<strong>BIOS</strong>.<br> מערכות חדשות משתמשות בדרך כלל ב־<strong>EFI</strong>, אך עשוית להופיע כ־BIOS אם הן מופעלות במצב תאימות לאחור. @@ -979,12 +979,12 @@ The installer will quit and all changes will be lost. Format partition %1 (file system: %2, size: %3 MB) on %4. - אתחל מחיצה %1 (מערכת קבצים: %2, גודל: %3 מ״ב) על %4. + אתחול מחיצה %1 (מערכת קבצים: %2, גודל: %3 מ״ב) על %4. Format <strong>%3MB</strong> partition <strong>%1</strong> with file system <strong>%2</strong>. - אתחול מחיצה <strong>%1</strong> בגודל <strong>%3 MB</strong> עם מערכת קבצים <strong>%2</strong>. + אתחול מחיצה <strong>%1</strong> בגודל <strong>%3 מ״ב</strong> עם מערכת קבצים <strong>%2</strong>. @@ -994,7 +994,7 @@ The installer will quit and all changes will be lost. The installer failed to format partition %1 on disk '%2'. - אשף ההתקנה נכשל בעת אתחול המחיצה %1 על כונן '%2'. + אשף ההתקנה נכשל בעת אתחול המחיצה %1 על הכונן ‚%2’. @@ -1007,12 +1007,12 @@ The installer will quit and all changes will be lost. Please install KDE Konsole and try again! - אנא התקן את KDE Konsole ונסה שוב! + נא להתקין את KDE Konsole ולנסות שוב! Executing script: &nbsp;<code>%1</code> - מריץ תסריט הרצה: &nbsp; <code>%1</code> + הסקריפט מופעל: &nbsp; <code>%1</code> @@ -1020,7 +1020,7 @@ The installer will quit and all changes will be lost. Script - תסריט הרצה + סקריפט @@ -1028,12 +1028,12 @@ The installer will quit and all changes will be lost. Set keyboard model to %1.<br/> - הגדר את דגם המקלדת ל %1.<br/> + הגדרת דגם המקלדת בתור %1.<br/> Set keyboard layout to %1/%2. - הגדר את פריסת לוח המקשים ל %1/%2. + הגדרת פריסת לוח המקשים בתור %1/%2. @@ -1097,7 +1097,7 @@ The installer will quit and all changes will be lost. Please review the End User License Agreements (EULAs) above.<br/>If you do not agree with the terms, proprietary software will not be installed, and open source alternatives will be used instead. - אנא סקור את הסכם משתמש הקצה (EULA) מעלה.<br/> במידה ואינך מסכים עם התנאים, תוכנות קנייניות לא יותקנו, ותוכנות חליפיות מבוססות קוד פתוח יותקנו במקומן. + נא לעיין בהסכם משתמש הקצה (EULA) מעלה.<br/> אם התנאים אינם מקובלים עליך, לא תותקנה תכניות קנייניות, במקומן תותקנה תכניות חלופיות מבוססות קוד פתוח. @@ -1176,7 +1176,7 @@ The installer will quit and all changes will be lost. Set timezone to %1/%2.<br/> - הגדרת אזור זמן ל %1/%2.<br/> + הגדרת אזור זמן בתור %1/%2.<br/> @@ -1369,7 +1369,7 @@ The installer will quit and all changes will be lost. The password contains more than %1 characters of the same class consecutively - הססמה מעילה יותר מ־%1 תווים מאותו הסוג ברצף + הססמה מכילה יותר מ־%1 תווים מאותו הסוג ברצף @@ -1517,7 +1517,7 @@ The installer will quit and all changes will be lost. <small>If more than one person will use this computer, you can set up multiple accounts after installation.</small> - <small>במידה ויותר מאדם אחד ישתמש במחשב זה, תוכל להגדיר משתמשים נוספים לאחר ההתקנה.</small> + <small>אם יותר מאדם אחד אמור להשתמש במחשב זה, ניתן להגדיר משתמשים נוספים לאחר ההתקנה.</small> @@ -1585,7 +1585,7 @@ The installer will quit and all changes will be lost. Swap - דפדוף, Swap + דפדוף Swap @@ -1741,12 +1741,12 @@ The installer will quit and all changes will be lost. <strong>Replace</strong> a partition on disk <strong>%2</strong> (%3) with %1. - <strong>החלף</strong> מחיצה על כונן <strong>%2</strong> (%3) עם %1. + <strong>החלפת</strong> מחיצה על כונן <strong>%2</strong> (%3) ב־%1. <strong>Manual</strong> partitioning on disk <strong>%1</strong> (%2). - מגדיר מחיצות באופן <strong>ידני</strong> על כונן <strong>%1</strong>(%2). + חלוקה למחיצות באופן <strong>ידני</strong> על כונן <strong>%1</strong> (%2). @@ -1771,22 +1771,22 @@ The installer will quit and all changes will be lost. An EFI system partition is necessary to start %1.<br/><br/>To configure an EFI system partition, go back and select or create a FAT32 filesystem with the <strong>esp</strong> flag enabled and mount point <strong>%2</strong>.<br/><br/>You can continue without setting up an EFI system partition but your system may fail to start. - מחיצת מערכת EFI נדרשת בשביל להפעיל את %1.<br/><br/> בכדי להגדיר מחיצת מערכת EFI, חזור ובחר או צור מערכת קבצים מסוג FAT32 עם סימון <strong>esp</strong> מופעל ונקודת עיגון <strong>%2</strong>.<br/><br/> ניתן להמשיך ללא הגדרת מחיצת מערכת EFI אך המערכת יכולה להיכשל בטעינה. + מחיצת מערכת EFI נדרשת כדי להפעיל את %1.<br/><br/> כדי להגדיר מחיצת מערכת EFI, עליך לחזור ולבחור או ליצור מערכת קבצים מסוג FAT32 עם סימון <strong>esp</strong> פעיל ועם נקודת עיגון <strong>%2</strong>.<br/><br/> ניתן להמשיך ללא הגדרת מחיצת מערכת EFI אך טעינת המערכת עשויה להיכשל. EFI system partition flag not set - סימון מחיצת מערכת EFI לא מוגדר + לא מוגדר סימון מחיצת מערכת EFI An EFI system partition is necessary to start %1.<br/><br/>A partition was configured with mount point <strong>%2</strong> but its <strong>esp</strong> flag is not set.<br/>To set the flag, go back and edit the partition.<br/><br/>You can continue without setting the flag but your system may fail to start. - מחיצת מערכת EFI נדרשת להפעלת %1.<br/><br/> מחיצה הוגדרה עם נקודת עיגון <strong>%2</strong> אך סימון <strong>esp</strong> לא הוגדר.<br/> בכדי לסמן את המחיצה, חזור וערוך את המחיצה.<br/><br/> תוכל להמשיך ללא ביצוע הסימון אך המערכת יכולה להיכשל בטעינה. + לצורך הפעלת %1 נדרשת מחיצת מערכת EFI.<br/><br/> הוגדרה מחיצה עם נקודת עיגון <strong>%2</strong> אך לא הוגדר סימון <strong>esp</strong>.<br/> כדי לסמן את המחיצה, עליך לחזור ולערוך את המחיצה.<br/><br/> ניתן להמשיך ללא הוספת הסימון אך טעינת המערכת עשויה להיכשל. Boot partition not encrypted - מחיצת טעינת המערכת Boot לא מוצפנת. + מחיצת טעינת המערכת (Boot) אינה מוצפנת. @@ -2453,14 +2453,14 @@ Output: <html><head/><body><p>By selecting this, you will send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html> - <html><head/><body><p>על ידי בחירת אפשרות זו, <span style=" font-weight:600;">לא תשלח מידע כלל </span>בנושא ההתקנה שלך.</p></body></html> + <html><head/><body><p>בחירה באפשרות זו, תוביל לכך <span style=" font-weight:600;">שלא יישלח מידע כלל</span> בנוגע ההתקנה שלך.</p></body></html> TextLabel - תָּוִית טקסט + תווית טקסט @@ -2477,22 +2477,22 @@ Output: Install tracking helps %1 to see how many users they have, what hardware they install %1 to and (with the last two options below), get continuous information about preferred applications. To see what will be sent, please click the help icon next to each area. - התקנת תכונת המעקב מסייעת ל %1 לראות את כמות המשתמשים, החומרה שעליה הם מתקינים את %1 ו(באמצעות שתי האפשרויות מטה), לקבל מידע מתמשך אודות תוכנות נבחרות. בכדי לראות את המידע שיישלח, אנא לחץ על צַלְמִית העזרה לצד כל תחום. + מעקב אחר ההתקנה מסייע ל־%1 לראות כמה משתמשים במוצר שלהם, על איזו חומרה מתבצעת ההתקנה של %1, בנוסף (לשתי האפשרויות הקודמות), קבלת מידע מתחדש על יישומים מועדפים. כדי לצפות בנתונים שיישלחו, נא לשלוח על סמל העזרה שליד כל אחד מהסעיפים. By selecting this you will send information about your installation and hardware. This information will <b>only be sent once</b> after the installation finishes. - על ידי בחירת אפשרות זו יישלח מידע אודות ההתקנה והחומרה שלך. מידע זה <b>יישלח פעם אחת בלבד</b> לאחר תום הליך ההתקנה. + בחירה באפשרות זו תוביל לשליחת מידע על ההתקנה והחומרה שלך. מידע זה <b>יישלח פעם אחת בלבד</b> לאחר סיום ההתקנה. By selecting this you will <b>periodically</b> send information about your installation, hardware and applications, to %1. - על ידי בחירת אפשרות זו יישלח <b>באופן קבוע</b> מידע אודות ההתקנה, החומרה והתוכנות שלך, ל %1. + בחירה באפשרות הזאת תוביל לשליחת מידע <b>מדי פעם בפעם</b> על ההתקנה, החומרה והיישומים שלך אל %1. By selecting this you will <b>regularly</b> send information about your installation, hardware, applications and usage patterns, to %1. - על ידי בחירת אפשרות זו יישלח <b>באופן קבוע</b> מידע אודות ההתקנה, החומרה, התוכנות ודפוסי השימוש שלך, ל %1. + בחירה באפשרות זו תוביל לשליחת מידע <b>באופן קבוע</b> על ההתקנה, החומרה, היישומים ודפוסי שימוש אל %1. @@ -2513,28 +2513,28 @@ Output: Your username contains invalid characters. Only lowercase letters and numbers are allowed. - שם העמדה מכיל ערכים לא תקינים. ניתן להשתמש אך ורק באותיות קטנות ומספרים. + שם המחשב מכיל תווים בלתי תקינים. מותר להשתמש אך ורק באותיות ובמספרים. Your hostname is too short. - שם העמדה קצר מדי. + שם המחשב קצר מדי. Your hostname is too long. - שם העמדה ארוך מדי. + שם המחשב ארוך מדי. Your hostname contains invalid characters. Only letters, numbers and dashes are allowed. - שם העמדה מכיל ערכים לא תקינים. אך ורק אותיות, מספרים ומקפים מורשים. + שם המחשב מכיל תווים בלתי תקינים. מותר להשתמש אך ורק באותיות, במספרים ובמקפים. Your passwords do not match! - הסיסמאות לא תואמות! + הססמאות לא תואמות! @@ -2575,7 +2575,7 @@ Output: &About - &אודות + על &אודות diff --git a/lang/calamares_pt_BR.ts b/lang/calamares_pt_BR.ts index 84302178a..ae40a024f 100644 --- a/lang/calamares_pt_BR.ts +++ b/lang/calamares_pt_BR.ts @@ -1519,7 +1519,7 @@ A instalação pode continuar, mas alguns recursos podem ser desativados. <small>If more than one person will use this computer, you can set up multiple accounts after installation.</small> - <small>Se mais de uma pessoa utilizará este computador, você pode definir múltiplas contas após a instalação.</small> + <small>Se mais de uma pessoa utilizará este computador, você poderá definir múltiplas contas após a instalação.</small> diff --git a/lang/calamares_uk.ts b/lang/calamares_uk.ts index 2c4225f56..d8470bcea 100644 --- a/lang/calamares_uk.ts +++ b/lang/calamares_uk.ts @@ -1007,7 +1007,7 @@ The installer will quit and all changes will be lost. Please install KDE Konsole and try again! - + Будь ласка встановіть KDE Konsole і спробуйте знову! @@ -1254,12 +1254,12 @@ The installer will quit and all changes will be lost. Memory allocation error - + Помилка виділення пам'яті The password is the same as the old one - + Цей пароль такий же як і старий @@ -1285,7 +1285,7 @@ The installer will quit and all changes will be lost. The password contains words from the real name of the user in some form - + Цей пароль містить слова зі справжнього імені користувача в якійсь із форм @@ -1295,12 +1295,12 @@ The installer will quit and all changes will be lost. The password contains less than %1 digits - + Цей пароль містить менше ніж %1 символ The password contains too few digits - + Цей пароль містить замало символів @@ -1465,7 +1465,7 @@ The installer will quit and all changes will be lost. Fatal failure - + Фатальна помилка @@ -1840,7 +1840,7 @@ The installer will quit and all changes will be lost. Saving files for later ... - + Збереження файлів на потім ... From 5d9e5b6d3e12ce6074b051e6bcd1a01023323199 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 20 Aug 2018 12:32:45 -0400 Subject: [PATCH 091/112] i18n: [desktop] Automatic merge of Transifex translations --- calamares.desktop | 2 ++ 1 file changed, 2 insertions(+) diff --git a/calamares.desktop b/calamares.desktop index 9c865b60b..5b73cecf3 100644 --- a/calamares.desktop +++ b/calamares.desktop @@ -145,6 +145,8 @@ GenericName[sv]=Systeminstallerare Comment[sv]=Calamares — Systeminstallerare Name[sv]=Installera system Name[th]=ติดตั้งระบบ +GenericName[uk]=Встановлювач системи +Comment[uk]=Calamares - Встановлювач системи Name[uk]=Встановити Систему Icon[zh_CN]=calamares GenericName[zh_CN]=系统安装程序 From 3fd1aefb0346b1385ec98ea16f2c23775a384dfa Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 20 Aug 2018 12:32:47 -0400 Subject: [PATCH 092/112] i18n: [python] Automatic merge of Transifex translations --- lang/python/uk/LC_MESSAGES/python.mo | Bin 645 -> 801 bytes lang/python/uk/LC_MESSAGES/python.po | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lang/python/uk/LC_MESSAGES/python.mo b/lang/python/uk/LC_MESSAGES/python.mo index 46f027dacc5ea91d47a53d71aecd6f8a82576756..abc489f66ad97b1f3922d885428e6ca9b0fe069b 100644 GIT binary patch delta 223 zcmZo=UC5SnPl#nI0}wC)u?!IF05K~N+W;{L1OTxh5C;PBETE!fAgu(%|A1^pAdL(_ zW-xf>6_+IDB7DXyMcJig&i06 zT-b53LE*y0iwzexTx`0q>%u+-o5;l6#Ee8^b7P16(vqC~{A|7C{9HR71tSAPi;YJP lGAdt~bg>brc*BLgKvOmWO=!BXL*c@HpunyRTR|K>1^@u4P1XPa delta 69 zcmZ3;*2-#ePl#nI0}wC*u?!Ha05LNV>i{tbSOBp%69a=KkOrxNfr&}|n;jVUF#-Vj CYX?^V diff --git a/lang/python/uk/LC_MESSAGES/python.po b/lang/python/uk/LC_MESSAGES/python.po index 9de9a1166..9c5ca55bd 100644 --- a/lang/python/uk/LC_MESSAGES/python.po +++ b/lang/python/uk/LC_MESSAGES/python.po @@ -10,6 +10,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-06-18 07:46-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Володимир Братко , 2018\n" "Language-Team: Ukrainian (https://www.transifex.com/calamares/teams/20061/uk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -40,7 +41,7 @@ msgstr "" #: src/modules/packages/main.py:64 src/modules/packages/main.py:74 msgid "Install packages." -msgstr "" +msgstr "Встановити пакети." #: src/modules/packages/main.py:67 #, python-format From fa45e21e15140398721eb8c547c5b834d430cad6 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 20 Aug 2018 22:21:39 -0700 Subject: [PATCH 093/112] Fix default desktop environment variable in displaymanager. Closes #1016. --- src/modules/displaymanager/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 47eb147ed..807dc79c9 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -399,7 +399,7 @@ def run(): username = libcalamares.globalstorage.value("autologinUser") root_mount_point = libcalamares.globalstorage.value("rootMountPoint") - if "default_desktop_environment" in libcalamares.job.configuration: + if "defaultDesktopEnvironment" in libcalamares.job.configuration: entry = libcalamares.job.configuration["defaultDesktopEnvironment"] default_desktop_environment = DesktopEnvironment( entry["executable"], entry["desktopFile"] From 00e1bb9c8deb639d64f1170ecbfbe654ee8b45ed Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Aug 2018 17:39:56 -0400 Subject: [PATCH 094/112] CI: fix the build on Travis - Make the Travis scripts a bit more verbose on failure - Fix wrong filename tested for picking up the configuration (this is why the builds were failing: missing the force-webkit flag, while webengine isn't in the dockerfile for Travis) FIXES #1018 --- ci/travis-continuous.sh | 10 +++++----- ci/travis-coverity.sh | 13 ++++++------- ci/travis.sh | 8 ++++---- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/ci/travis-continuous.sh b/ci/travis-continuous.sh index 42cfb4bd3..30fe82996 100755 --- a/ci/travis-continuous.sh +++ b/ci/travis-continuous.sh @@ -3,12 +3,12 @@ # Travis CI script for use on every-commit: # - build and install Calamares # -test -n "$BUILDDIR" || exit 1 -test -n "$SRCDIR" || exit 1 +test -n "$BUILDDIR" || { echo "! \$BUILDDIR not set" ; exit 1 ; } +test -n "$SRCDIR" || { echo "! \$SRCDIR not set" ; exit 1 ; } -test -d $BUILDDIR || exit 1 -test -d $SRCDIR || exit 1 -test -f $SRCDIR/CMakeLists.txt || exit 1 +test -d $BUILDDIR || { echo "! $BUILDDIR not a directory" ; exit 1 ; } +test -d $SRCDIR || { echo "! $SRCDIR not a directory" ; exit 1 ; } +test -f $SRCDIR/CMakeLists.txt || { echo "! Missing $SRCDIR/CMakeLists.txt" ; exit 1 ; } cd $BUILDDIR || exit 1 diff --git a/ci/travis-coverity.sh b/ci/travis-coverity.sh index c9495cf56..79b7fbdab 100755 --- a/ci/travis-coverity.sh +++ b/ci/travis-coverity.sh @@ -3,13 +3,13 @@ # Travis CI script for weekly (cron) use: # - use the coverity tool to build and and upload results # -test -n "$COVERITY_SCAN_TOKEN" || exit 1 -test -n "$BUILDDIR" || exit 1 -test -n "$SRCDIR" || exit 1 +test -n "$COVERITY_SCAN_TOKEN" || { echo "! Missing Coverity token" ; exit 1 ; } +test -n "$BUILDDIR" || { echo "! \$BUILDDIR not set" ; exit 1 ; } +test -n "$SRCDIR" || { echo "! \$SRCDIR not set" ; exit 1 ; } -test -d $BUILDDIR || exit 1 -test -d $SRCDIR || exit 1 -test -f $SRCDIR/CMakeLists.txt || exit 1 +test -d $BUILDDIR || { echo "! $BUILDDIR not a directory" ; exit 1 ; } +test -d $SRCDIR || { echo "! $SRCDIR not a directory" ; exit 1 ; } +test -f $SRCDIR/CMakeLists.txt || { echo "! Missing $SRCDIR/CMakeLists.txt" ; exit 1 ; } cd $BUILDDIR || exit 1 @@ -20,7 +20,6 @@ mkdir "$BUILDDIR/coveritytool" tar xvf coverity_tool.tar.gz -C "$BUILDDIR/coveritytool" --strip-components 2 export PATH="$BUILDDIR/coveritytool/bin:$PATH" - cmake -DCMAKE_BUILD_TYPE=Debug $CMAKE_ARGS $SRCDIR || exit 1 cov-build --dir cov-int make -j2 diff --git a/ci/travis.sh b/ci/travis.sh index 364923b9e..737da95d4 100755 --- a/ci/travis.sh +++ b/ci/travis.sh @@ -8,11 +8,11 @@ # intensive than the coverity add-on, but works on master. # D=`dirname "$0"` -test -d "$D" || exit 1 -test -x "$D/travis-continuous.sh" || exit 1 -test -x "$D/travis-coverity.sh" || exit 1 +test -d "$D" || { echo "! No directory $D" ; exit 1 ; } +test -x "$D/travis-continuous.sh" || { echo "! Missing -continuous" ; exit 1 ; } +test -x "$D/travis-coverity.sh" || { echo "! Missing -coverity" ; exit 1 ; } -test -f "$D/travis-common.sh" && . "$D/travis-config.sh" +test -f "$D/travis-config.sh" && . "$D/travis-config.sh" if test "$TRAVIS_EVENT_TYPE" = "cron" ; then exec "$D/travis-coverity.sh" From c3219a49057f2b526592c3898abde334591f518e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Aug 2018 07:31:46 -0400 Subject: [PATCH 095/112] [displaymanager] Fix call in LightDM code - The parameter list was wrong, and could never have worked (apparently noone mixes LightDM with basic setup, even though it's one of the few with basic_setup()). - Shorten some lines. --- src/modules/displaymanager/main.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 16d9ccb51..3937c1551 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -541,13 +541,9 @@ class DMlightdm(DisplayManager): ] ) - libcalamares.utils.target_env_call('passwd', '-l', 'lightdm') - libcalamares.utils.target_env_call( - ['chown', '-R', 'lightdm:lightdm', '/run/lightdm'] - ) - libcalamares.utils.target_env_call( - ['chmod', '+r' '/etc/lightdm/lightdm.conf'] - ) + libcalamares.utils.target_env_call(['passwd', '-l', 'lightdm']) + libcalamares.utils.target_env_call(['chown', '-R', 'lightdm:lightdm', '/run/lightdm']) + libcalamares.utils.target_env_call(['chmod', '+r' '/etc/lightdm/lightdm.conf']) def desktop_environment_setup(self, default_desktop_environment): os.system( From f97321656f65b1d5d6fe9c9818b6e743fc0b3d9b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Aug 2018 07:44:01 -0400 Subject: [PATCH 096/112] Changelog: add DM changes - Add the DM module changes - Update list of contributors for this release --- CHANGES | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 6bcb46e72..9fc3979e0 100644 --- a/CHANGES +++ b/CHANGES @@ -5,11 +5,16 @@ website will have to do for older versions. = 3.2.2 (unreleased) = +This release contains contributions from (alphabetically by first name): + - Andrius Štikonas + - artoo@cromnix.org + - Caio Carvalho + - Philip Müller + - Simon Quigley + - Walter Lapchynski + == Core == - * Contributions from the following people (alphabetically by first name): - - artoo@cromnix.org - - Caio Carvalho * Example configurations are **no longer installed** by default. The default setting for *INSTALL_CONFIG* has changed. Distributions are strongly encouraged to write their own configuration files and @@ -45,6 +50,14 @@ website will have to do for older versions. a bad configuration). The configuration is a little more flexible because a service (or target) name can be used on its own with sensible defaults. + * The displaymanager module has been entirely revamped. A long-standing + bug which ignored the settings for default desktop has been fixed + (thanks to Walter Lapchynski). Translations have been added to the + error messages. Each DM now has an implementation class for doing + all the configuration steps it needs. This groups the code needed for + a specific DM (and presumably, per-distro) in one place. + Distro's are **strongly advised** to re-test their DM configuration + and installation with the revamped code. **3.2.1** (2018-06-25) From ae0764f52ef791c86af4455f65b1a8422db7c4da Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Aug 2018 07:45:44 -0400 Subject: [PATCH 097/112] CI: be more verbose in the CI --- ci/travis-continuous.sh | 1 + ci/travis-coverity.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/ci/travis-continuous.sh b/ci/travis-continuous.sh index 30fe82996..4ac243f23 100755 --- a/ci/travis-continuous.sh +++ b/ci/travis-continuous.sh @@ -12,4 +12,5 @@ test -f $SRCDIR/CMakeLists.txt || { echo "! Missing $SRCDIR/CMakeLists.txt" ; ex cd $BUILDDIR || exit 1 +echo "# cmake $CMAKE_ARGS $SRCDIR" cmake $CMAKE_ARGS $SRCDIR && make -j2 && make install DESTDIR=/build/INSTALL_ROOT diff --git a/ci/travis-coverity.sh b/ci/travis-coverity.sh index 79b7fbdab..88b6a2ab5 100755 --- a/ci/travis-coverity.sh +++ b/ci/travis-coverity.sh @@ -20,6 +20,7 @@ mkdir "$BUILDDIR/coveritytool" tar xvf coverity_tool.tar.gz -C "$BUILDDIR/coveritytool" --strip-components 2 export PATH="$BUILDDIR/coveritytool/bin:$PATH" +echo "# cmake -DCMAKE_BUILD_TYPE=Debug $CMAKE_ARGS $SRCDIR" cmake -DCMAKE_BUILD_TYPE=Debug $CMAKE_ARGS $SRCDIR || exit 1 cov-build --dir cov-int make -j2 From 81cab43701a746a28cfec95600b0fa0fea644641 Mon Sep 17 00:00:00 2001 From: Harald Sitter Date: Tue, 7 Aug 2018 13:34:38 +0200 Subject: [PATCH 098/112] do not set active flags on the to-be ESP having ESP as active flag AND then trying to set ESP means nothing is set since kpmcore will think ESP is already set (it is listed as active after all). this ultimately meant that nothing was set since there was no delta between the requested flags and the already active flags. --- src/modules/partition/core/PartitionActions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 68ad85cf2..54ccc192f 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -160,7 +160,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass FileSystem::Fat32, firstFreeSector, lastSector, - PartitionTable::FlagEsp + PartitionTable::FlagNone ); PartitionInfo::setFormat( efiPartition, true ); PartitionInfo::setMountPoint( efiPartition, gs->value( "efiSystemPartition" ) From 84ad2852bfe18ee5c922032a24ca173807fd1e63 Mon Sep 17 00:00:00 2001 From: Harald Sitter Date: Wed, 22 Aug 2018 10:14:49 +0200 Subject: [PATCH 099/112] do not set boot flag on ESP ESP == boot. at best this is duplicated information, at worst kpmcore may implode if you try to set a boot flag since that is technically an MBR type flag and means nothing within the context of GPT where ESP is the flag to set. --- src/modules/partition/core/PartitionActions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 68ad85cf2..b1582a2f2 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -165,7 +165,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, const QString& luksPass PartitionInfo::setFormat( efiPartition, true ); PartitionInfo::setMountPoint( efiPartition, gs->value( "efiSystemPartition" ) .toString() ); - core->createPartition( dev, efiPartition, PartitionTable::FlagEsp | PartitionTable::FlagBoot ); + core->createPartition( dev, efiPartition, PartitionTable::FlagEsp ); firstFreeSector = lastSector + 1; } else From d775cee4cfdba4047802c9821c1d80ef69cb81b4 Mon Sep 17 00:00:00 2001 From: Matthias Klumpp Date: Sat, 25 Aug 2018 00:26:21 +0200 Subject: [PATCH 100/112] grubcfg: Only try to decrypt disk that /boot is on --- src/modules/grubcfg/main.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index b19ebf588..d3f292281 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -62,6 +62,12 @@ def modify_grub_default(partitions, root_mount_point, distributor): cryptdevice_params = [] + # GRUB needs to decrypt the partition that /boot is on, which may be / or /boot + boot_mountpoint = "/" + for partition in partitions: + if partition["mountPoint"] == "/boot": + boot_mountpoint = "/boot" + if have_dracut: for partition in partitions: has_luks = "luksMapperName" in partition @@ -72,7 +78,7 @@ def modify_grub_default(partitions, root_mount_point, distributor): swap_outer_uuid = partition["luksUuid"] swap_outer_mappername = partition["luksMapperName"] - if (partition["mountPoint"] == "/" and has_luks): + if (partition["mountPoint"] == boot_mountpoint and has_luks): cryptdevice_params = [ "rd.luks.uuid={!s}".format(partition["luksUuid"]) ] @@ -82,7 +88,7 @@ def modify_grub_default(partitions, root_mount_point, distributor): if partition["fs"] == "linuxswap" and not has_luks: swap_uuid = partition["uuid"] - if (partition["mountPoint"] == "/" and has_luks): + if (partition["mountPoint"] == boot_mountpoint and has_luks): cryptdevice_params = [ "cryptdevice=UUID={!s}:{!s}".format( partition["luksUuid"], partition["luksMapperName"] From e3ca2dd857591d9801207a0cb4cedcc7db1d8d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20M=C3=BCller?= Date: Sun, 26 Aug 2018 21:15:03 +0200 Subject: [PATCH 101/112] [displaymanager] fix desktop_environment_setup ldm --- src/modules/displaymanager/main.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 3937c1551..08eeb6fdb 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -3,7 +3,7 @@ # # === This file is part of Calamares - === # -# Copyright 2014-2017, Philip Müller +# Copyright 2014-2018, Philip Müller # Copyright 2014-2015, Teo Mrnjavac # Copyright 2014, Kevin Kofler # Copyright 2017, Alf Gaida @@ -64,6 +64,12 @@ class DesktopEnvironment: desktop_environments = [ DesktopEnvironment('/usr/bin/startkde', 'plasma'), # KDE Plasma 5 DesktopEnvironment('/usr/bin/startkde', 'kde-plasma'), # KDE Plasma 4 + DesktopEnvironment( + '/usr/bin/budgie-desktop', 'budgie-desktop' # Budgie v10 + ), + DesktopEnvironment( + '/usr/bin/budgie-session', 'budgie-desktop' # Budgie v8 + ), DesktopEnvironment('/usr/bin/gnome-session', 'gnome'), DesktopEnvironment('/usr/bin/startxfce4', 'xfce'), DesktopEnvironment('/usr/bin/cinnamon-session-cinnamon', 'cinnamon'), @@ -74,8 +80,6 @@ desktop_environments = [ DesktopEnvironment('/usr/bin/lxqt-session', 'lxqt'), DesktopEnvironment('/usr/bin/pekwm', 'pekwm'), DesktopEnvironment('/usr/bin/pantheon-session', 'pantheon'), - 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') @@ -548,9 +552,9 @@ class DMlightdm(DisplayManager): def desktop_environment_setup(self, default_desktop_environment): os.system( "sed -i -e \"s/^.*user-session=.*/user-session={!s}/\" " - "{!s}".format( + "{!s}/etc/lightdm/lightdm.conf".format( default_desktop_environment.desktop_file, - lightdm_conf_path + self.root_mount_point ) ) From 01889b0392f27cc4481f05e354d36466426fb80b Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 3 Sep 2018 04:30:52 -0400 Subject: [PATCH 102/112] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_ca.ts | 6 ++--- lang/calamares_el.ts | 20 +++++++-------- lang/calamares_es.ts | 28 ++++++++++----------- lang/calamares_ja.ts | 8 +++--- lang/calamares_pt_BR.ts | 10 +++----- lang/calamares_ru.ts | 56 ++++++++++++++++++++--------------------- 6 files changed, 63 insertions(+), 65 deletions(-) diff --git a/lang/calamares_ca.ts b/lang/calamares_ca.ts index 1a6f2b11c..e675badea 100644 --- a/lang/calamares_ca.ts +++ b/lang/calamares_ca.ts @@ -1791,7 +1791,7 @@ L'instal·lador es tancarà i tots els canvis es perdran. 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. - S'ha establert una partició d'arrencada separada conjuntament amb una partició d'arrel encriptada, però la partició d'arrencada no està encriptada.<br/><br/>Hi ha aspectes de seguretat amb aquest tipus de configuració, perquè hi ha fitxers del sistema importants en una partició no encriptada.<br/>Podeu continuar, si així ho desitgeu, però el desbloqueig del sistema de fitxers succeirà després, durant l'inici del sistema.<br/>Per encriptar la partició d'arrencada, torneu enrere i torneu-la a crear seleccionant <strong>Encripta</strong> a la finestra de creació de la partició. + S'ha establert una partició d'arrencada separada conjuntament amb una partició d'arrel encriptada, però la partició d'arrencada no està encriptada.<br/><br/>Hi ha assumptes de seguretat amb aquest tipus de configuració, perquè hi ha fitxers del sistema importants en una partició no encriptada.<br/>Podeu continuar, si així ho desitgeu, però el desbloqueig del sistema de fitxers succeirà després, durant l'inici del sistema.<br/>Per encriptar la partició d'arrencada, torneu enrere i torneu-la a crear seleccionant <strong>Encripta</strong> a la finestra de creació de la partició. @@ -2292,12 +2292,12 @@ Sortida: rootMountPoint is %1 - El punt de muntatge d'arrel és %1 + El punt de muntatge de l'arrel és %1 Cannot disable root account. - No es pot inhabilitar el compte de root. + No es pot inhabilitar el compte d'arrel. diff --git a/lang/calamares_el.ts b/lang/calamares_el.ts index ad2491e1f..36ed7427e 100644 --- a/lang/calamares_el.ts +++ b/lang/calamares_el.ts @@ -50,7 +50,7 @@ Blank Page - + Κενή Σελίδα @@ -192,7 +192,7 @@ Calamares Initialization Failed - + Η αρχικοποίηση του Calamares απέτυχε @@ -207,7 +207,7 @@ &Install - + &Εγκατάσταση @@ -249,17 +249,17 @@ The installer will quit and all changes will be lost. &Install now - Ε&γκατάσταση τώρα + &Εγκατάσταση τώρα Go &back - Μετάβαση πί&σω + Μετάβαση &πίσω &Done - + &Ολοκληρώθηκε @@ -2087,7 +2087,7 @@ Output: The screen is too small to display the installer. - + Η οθόνη είναι πολύ μικρή για να απεικονίσει το πρόγραμμα εγκατάστασης @@ -2173,17 +2173,17 @@ Output: Failed to write to %1 - + Αδυναμία εγγραφής στο %1 Failed to write keyboard configuration for X11. - + Αδυναμία εγγραφής στοιχείων διαμόρφωσης πληκτρολογίου για Χ11 Failed to write keyboard configuration to existing /etc/default directory. - + Αδυναμία εγγραφής στοιχείων διαμόρφωσης πληκτρολογίου στον υπάρχων κατάλογο /etc/default diff --git a/lang/calamares_es.ts b/lang/calamares_es.ts index c07481a92..95f507f54 100644 --- a/lang/calamares_es.ts +++ b/lang/calamares_es.ts @@ -193,22 +193,22 @@ Para configurar el arranque desde un entorno BIOS, este instalador debe instalar Calamares Initialization Failed - + La inicialización de Calamares falló %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + %1 no se pudo instalar. Calamares no fue capaz de cargar todos los módulos configurados. Esto es un problema con la forma en que Calamares es usado por la distribución <br/>The following modules could not be loaded: - + Los siguientes módulos no se pudieron cargar: &Install - + &Instalar @@ -509,12 +509,12 @@ Saldrá del instalador y se perderán todos los cambios. The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined. - + El comando corre en el ambiente anfitrión y necesita saber el directorio raiz, pero no está definido el punto de montaje de la raiz The command needs to know the user's name, but no username is defined. - + El comando necesita saber el nombre de usuario, pero no hay nombre de usuario definido. @@ -1664,7 +1664,7 @@ Saldrá del instalador y se perderán todos los cambios. Cre&ate - + Cre&ar @@ -1689,12 +1689,12 @@ Saldrá del instalador y se perderán todos los cambios. Can not create new partition - + No se puede crear una partición nueva The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead. - + La tabla de particiones en %1 tiene %2 particiones primarias y no se pueden agregar más. Por favor remueva una partición primaria y agregue una partición extendida en su reemplazo. @@ -1824,7 +1824,7 @@ Saldrá del instalador y se perderán todos los cambios. Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is installed. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. - + Elija una apariencia para KDE Plasma Desktop. También puede omitir este paso y configurar el aspecto una vez que el sistema está instalado. Al hacer clic en una selección de apariencia, obtendrá una vista previa en vivo de esa apariencia. @@ -1840,17 +1840,17 @@ Saldrá del instalador y se perderán todos los cambios. Saving files for later ... - + Guardando archivos para después ... No files configured to save for later. - + No hay archivos configurados para guardarlos para después. Not all of the configured files could be preserved. - + No todos los archivos de configuración se pudieron preservar. @@ -2368,7 +2368,7 @@ Salida: %L1 / %L2 slide counter, %1 of %2 (numeric) - + %L1 / %L2 diff --git a/lang/calamares_ja.ts b/lang/calamares_ja.ts index bafc53eee..63e7f2c28 100644 --- a/lang/calamares_ja.ts +++ b/lang/calamares_ja.ts @@ -197,7 +197,7 @@ %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + %1 はインストールできません。Calamares は全てのモジュールをロードすることをできませんでした。これは、Calamares のこのディストリビューションでの使用法による問題です。 @@ -1694,7 +1694,7 @@ The installer will quit and all changes will be lost. The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead. - + %1 上のパーティションテーブルには既にプライマリパーティション %2 が配置されており、追加することができません。プライマリパーティションを消去して代わりに拡張パーティションを追加してください。 @@ -1845,12 +1845,12 @@ The installer will quit and all changes will be lost. No files configured to save for later. - + 保存するための設定ファイルがありません。 Not all of the configured files could be preserved. - + 設定ファイルは全て保護されるわけではありません。 diff --git a/lang/calamares_pt_BR.ts b/lang/calamares_pt_BR.ts index ae40a024f..26f0c55f1 100644 --- a/lang/calamares_pt_BR.ts +++ b/lang/calamares_pt_BR.ts @@ -259,7 +259,7 @@ O instalador será fechado e todas as alterações serão perdidas. &Done - Completa&do + Concluí&do @@ -318,14 +318,12 @@ O instalador será fechado e todas as alterações serão perdidas. This computer does not satisfy the minimum requirements for installing %1.<br/>Installation cannot continue. <a href="#details">Details...</a> - Este computador não satisfaz os requisitos mínimos para instalar %1. -A instalação não pode continuar. Detalhes: + Este computador não satisfaz os requisitos mínimos para instalar %1.<br/>A instalação não pode continuar. <a href="#details">Detalhes...</a> This computer does not satisfy some of the recommended requirements for installing %1.<br/>Installation can continue, but some features might be disabled. - Este computador não satisfaz alguns dos requisitos recomendados para instalar %1. -A instalação pode continuar, mas alguns recursos podem ser desativados. + Este computador não satisfaz alguns dos requisitos recomendados para instalar %1.<br/>A instalação pode continuar, mas alguns recursos podem ser desativados. @@ -912,7 +910,7 @@ A instalação pode continuar, mas alguns recursos podem ser desativados. Install %2 on %3 system partition <strong>%1</strong>. - Instalar %2 em partição %3 do sistema <strong>%1</strong>. + Instalar %2 na partição %3 do sistema <strong>%1</strong>. diff --git a/lang/calamares_ru.ts b/lang/calamares_ru.ts index 2c05acdc9..24e640cb4 100644 --- a/lang/calamares_ru.ts +++ b/lang/calamares_ru.ts @@ -197,7 +197,7 @@ %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + Не удалось установить %1. Calamares не удалось загрузить все сконфигурированные модули. Эта проблема вызвана тем, как ваш дистрибутив использует Calamares. @@ -507,7 +507,7 @@ The installer will quit and all changes will be lost. The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined. - + Команда выполняется в окружении установщика, и ей необходимо знать путь корневого раздела, но rootMountPoint не определено. @@ -558,7 +558,7 @@ The installer will quit and all changes will be lost. LVM LV name - + Имя LV LVM @@ -1063,7 +1063,7 @@ The installer will quit and all changes will be lost. &OK - + &ОК @@ -1217,7 +1217,7 @@ The installer will quit and all changes will be lost. Network Installation. (Disabled: Received invalid groups data) - + Установка по сети. (Отключено: получены неверные сведения о группах) @@ -1248,12 +1248,12 @@ The installer will quit and all changes will be lost. Memory allocation error when setting '%1' - + Ошибка выделения памяти при установке «%1» Memory allocation error - + Ошибка выделения памяти @@ -1413,12 +1413,12 @@ The installer will quit and all changes will be lost. Unknown setting - %1 - + Неизвестная настройка - %1 Unknown setting - + Неизвестная настройка @@ -1428,27 +1428,27 @@ The installer will quit and all changes will be lost. Bad integer value - + Недопустимое целое значение Setting %1 is not of integer type - + Настройка %1 не является целым числом Setting is not of integer type - + Настройка не является целым числом Setting %1 is not of string type - + Настройка %1 не является строкой Setting is not of string type - + Настройка не является строкой @@ -1458,12 +1458,12 @@ The installer will quit and all changes will be lost. The configuration file is malformed - + Ошибка в структуре конфигурационного файла Fatal failure - + Фатальный сбой @@ -1662,7 +1662,7 @@ The installer will quit and all changes will be lost. Cre&ate - + Со&здать @@ -1804,7 +1804,7 @@ The installer will quit and all changes will be lost. Could not select KDE Plasma Look-and-Feel package - + Не удалось выбрать пакет внешнего вида для KDE Plasma @@ -1822,7 +1822,7 @@ The installer will quit and all changes will be lost. Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is installed. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. - + Выберите внешний вид окружения KDE Plasma. Вы можете пропустить этот шаг, и настроить его после установки системы. Щелкните на выборе внешнего вида, чтобы увидеть, как он будет выглядеть. @@ -1830,7 +1830,7 @@ The installer will quit and all changes will be lost. Look-and-Feel - + Внешний вид @@ -1906,7 +1906,7 @@ Output: Command <i>%1</i> failed to finish in %2 seconds. - + Команда <i>%1</i> не завершилась за %2 с. @@ -2404,7 +2404,7 @@ Output: HTTP request timed out. - + Тайм-аут запроса HTTP. @@ -2428,12 +2428,12 @@ Output: Could not configure machine feedback correctly, script error %1. - + Не удалось настроить отзывы о компьютере, ошибка сценария %1. Could not configure machine feedback correctly, Calamares error %1. - + Не удалось настроить отзывы о компьютере, ошибка Calamares %1. @@ -2451,7 +2451,7 @@ Output: <html><head/><body><p>By selecting this, you will send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html> - + <html><head/><body><p>Если вы это выберете, то не будет отправлено <span style=" font-weight:600;">никаких</span> сведений об установке.</p></body></html> @@ -2470,12 +2470,12 @@ Output: <html><head/><body><p><a href="placeholder"><span style=" text-decoration: underline; color:#2980b9;">Click here for more information about user feedback</span></a></p></body></html> - + <html><head/><body><p><a href="placeholder"><span style=" text-decoration: underline; color:#2980b9;">Щелкните здесь чтобы узнать больше об отзывах пользователей</span></a></p></body></html> Install tracking helps %1 to see how many users they have, what hardware they install %1 to and (with the last two options below), get continuous information about preferred applications. To see what will be sent, please click the help icon next to each area. - + Отслеживание установок позволяет %1 узнать, сколько у них пользователей, на каком оборудовании устанавливается %1, и (с двумя последними опциями) постоянно получать сведения о предпочитаемых приложениях. Чтобы увидеть, что будет отправлено, щелкните по значку справки рядом с каждой областью. @@ -2498,7 +2498,7 @@ Output: Feedback - + Отзывы From 2d763e4d1a790adf49d7d24f5d17e2ecc8976e7a Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 3 Sep 2018 04:30:53 -0400 Subject: [PATCH 103/112] i18n: [python] Automatic merge of Transifex translations --- lang/python/es/LC_MESSAGES/python.mo | Bin 1075 -> 1207 bytes lang/python/es/LC_MESSAGES/python.po | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/python/es/LC_MESSAGES/python.mo b/lang/python/es/LC_MESSAGES/python.mo index c41fdc83592f0859bddf6fe892e81ed57f639adf..f5695552d735414201b94683fcd24714d3f44181 100644 GIT binary patch delta 358 zcmXYry-EZz6ov2Xt~y&-xN4y&-oj2<*B{VAL_w^!5wR6QChGYwbjPT zLYTr%kj2UeuoD#@K=1`TareN-mwQPLDdNZK>3gkmNk|n;fCLPJdl2#ghQKEn0lz)R zQFlKHFJU(a&%g=XfY0Dj_!)izZ(t1bRheiUet@Tm_UILd8WunBB3!O?igCehF);(Kd7Vr^Ox`8U2EK-&AFvh#s1jm%3RzPx# delta 227 zcmdnaxtXK>o)F7a1|Z-7Vi_Qg0b*_-o&&@nZ~}-0f%qg4ivaO$DE$FQgTz@G85m4} zv^bE~2GTx2+5kvb0O<}OUJ1mKK)w+(1A`Pu9!RSI>2x41#K7Rj&;w)`0|n*-X^;Vz zq5S_q8mO0n9f(?7b!^FE!CSPZq%UxVjl$xWXU}RuuzIiLt GBSrv48X80Z diff --git a/lang/python/es/LC_MESSAGES/python.po b/lang/python/es/LC_MESSAGES/python.po index 39b5e54cc..b2ad0b076 100644 --- a/lang/python/es/LC_MESSAGES/python.po +++ b/lang/python/es/LC_MESSAGES/python.po @@ -10,7 +10,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-06-18 07:46-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: strel, 2017\n" +"Last-Translator: Francisco Sánchez López de Lerma , 2018\n" "Language-Team: Spanish (https://www.transifex.com/calamares/teams/20061/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,7 +20,7 @@ msgstr "" #: src/modules/umount/main.py:40 msgid "Unmount file systems." -msgstr "" +msgstr "Desmontar sistemas de archivos." #: src/modules/dummypython/main.py:44 msgid "Dummy python job." From 604c5ba3f1d2a4e4df658bef6b3fc74d2b5d3a37 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 3 Sep 2018 05:08:52 -0400 Subject: [PATCH 104/112] Changelog: add old releases, credit Harald in 3.2.2 --- CHANGES | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/CHANGES b/CHANGES index 9fc3979e0..20ed48f2e 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,7 @@ This release contains contributions from (alphabetically by first name): - Andrius Štikonas - artoo@cromnix.org - Caio Carvalho + - Harald Sitter - Philip Müller - Simon Quigley - Walter Lapchynski @@ -61,5 +62,64 @@ This release contains contributions from (alphabetically by first name): **3.2.1** (2018-06-25) +This release contains contributions from (alphabetically by first name): + - Bill Auguer + - Gabriel Craciunescu + - Phil Mueller + - Raul Rodrigo Segura + + == Core == + + * Qt 5.7 is now the minimum required Qt version. Because KPMCore + (a fairly fundamental dependency) requires Qt 5.7, Calamares + has followed suit. + * New testing application `loadmodule` for loading and running a + single Calamares module. + * New translations Belarussian and Korean. + * Jobs can now be *emergency jobs* which run even after a failure. + * Improved debugging when modules fail to load. + * Bad configuration files will now cause the user-interface of + Calamares to display an error message, rather than silently + ignoring some configuration errors. This will certainly cause + problems for distributions with sloppy configurations. + +== Modules == + + * New module preservefiles, keeps (log) files around after install; + this duplicates functionality with the unmount module, but unmount + is very late, rather limited, and fragile. + * Interactiveterminal module now disables itself if build requirements + are not met, rather than blocking the build. + * Fixes in the timezone map data make the southern hemisphere more + usable and put Reykjavik in its place. + * The packages module can now update the target system if explicitly + told to do so. + * More paths and executables are configurable in the bootloader module. + * Distributions are advised to review the `users.conf` setup **again**, + as some changes in version 3.2.0 caused regressions downstream. + * Distributions are advised to review their `locale.gen` files + **again**. Previous changes were too restrictive, matching only + the specific format Chakra Linux uses. Calamares now preserves + all the comment-lines in the file and writes enabled locales + at the end, with a descriptive comment. **3.2.0** (2018-05-17) + +This release contains contributions from (alphabetically by first name): + - Alf Gaida + - AlmAck + - Caio Carvalho + - Frede H + +== Modules == + + * UI annoyances in the partitioning module were fixed; the + mount-point selector is now more obvious when no mount-point + has been chosen, and the mount-point and flags are preserved + when (re)editing partitions. + * The handling of `@@ROOT@@` substitution in shellprocesses was + backwards; this has been fixed (the substitution is made when + running in the **host**). + * The user shell is no longer hard-coded to `/bin/bash`, + but follows the default setting for useradd(8), e.g. + those set in `/etc/default/useradd`. From aee5676ae8c70b8054808f3c2475b359e5fe9334 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 3 Sep 2018 05:11:27 -0400 Subject: [PATCH 105/112] ci: be more verbose on failure and on install --- ci/travis-continuous.sh | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/ci/travis-continuous.sh b/ci/travis-continuous.sh index 4ac243f23..0b7b8c548 100755 --- a/ci/travis-continuous.sh +++ b/ci/travis-continuous.sh @@ -12,5 +12,25 @@ test -f $SRCDIR/CMakeLists.txt || { echo "! Missing $SRCDIR/CMakeLists.txt" ; ex cd $BUILDDIR || exit 1 -echo "# cmake $CMAKE_ARGS $SRCDIR" -cmake $CMAKE_ARGS $SRCDIR && make -j2 && make install DESTDIR=/build/INSTALL_ROOT +echo "###" +echo "### cmake $CMAKE_ARGS $SRCDIR" +echo "###" +cmake $CMAKE_ARGS $SRCDIR || { echo "! CMake failed" ; exit 1 ; } + +echo -e "###\n### make\n###" +make -j2 || { make -j1 VERBOSE=1 ; echo "! Make failed" ; exit 1 ; } + +echo -e "###\n### make install\n###" +echo "# Build results" +find "$BUILDDIR" -name '*.so' + +echo "# Install" +DESTDIR=/build/INSTALL_ROOT +mkdir -p "$DESTDIR" + +result=true +make install VERBOSE=1 DESTDIR="$DESTDIR" || result=false + +echo "# Install results" +find "$DESTDIR" -type f +$result # Result of make install, above From 9651c588bc82fb796d3c901d8dc2cf991f6aa437 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 3 Sep 2018 05:34:23 -0400 Subject: [PATCH 106/112] CMake: Search for PythonQt headers in more places. Suggested by Denis Proskurin. --- CMakeModules/FindPythonQt.cmake | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CMakeModules/FindPythonQt.cmake b/CMakeModules/FindPythonQt.cmake index f0f4b8a73..eb773a3d9 100644 --- a/CMakeModules/FindPythonQt.cmake +++ b/CMakeModules/FindPythonQt.cmake @@ -24,17 +24,24 @@ string(REGEX REPLACE ) if(NOT EXISTS "${PYTHONQT_INSTALL_DIR}") - find_path(PYTHONQT_INSTALL_DIR include/PythonQt/PythonQt.h DOC "Directory where PythonQt was installed.") + find_path(PYTHONQT_INSTALL_DIR + NAMES + include/PythonQt/PythonQt.h + include/PythonQt5/PythonQt.h + DOC "Directory where PythonQt was installed.") endif() + # XXX Since PythonQt 3.0 is not yet cmakeified, depending # on how PythonQt is built, headers will not always be # installed in "include/PythonQt". That is why "src" # is added as an option. See [1] for more details. # [1] https://github.com/commontk/CTK/pull/538#issuecomment-86106367 find_path(PYTHONQT_INCLUDE_DIR PythonQt.h - PATHS "${PYTHONQT_INSTALL_DIR}/include/PythonQt" + PATHS + "${PYTHONQT_INSTALL_DIR}/include/PythonQt" + "${PYTHONQT_INSTALL_DIR}/include/PythonQt5" "${PYTHONQT_INSTALL_DIR}/src" - DOC "Path to the PythonQt include directory") + DOC "Path to the PythonQt include directory") if ( NOT PythonQt_FIND_QUIETLY ) message( STATUS "Searching for PythonQt (PythonLibs ${PYTHONLIBS_MAJMIN}) .." ) From 54bee71b44427c19641ed9be4476724d0444ff00 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 3 Sep 2018 06:20:44 -0400 Subject: [PATCH 107/112] CMake: Search for PythonQt_QtAll.h Suggested by Denis Proskurin. --- CMakeModules/FindPythonQt.cmake | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CMakeModules/FindPythonQt.cmake b/CMakeModules/FindPythonQt.cmake index eb773a3d9..d1764a3b9 100644 --- a/CMakeModules/FindPythonQt.cmake +++ b/CMakeModules/FindPythonQt.cmake @@ -42,11 +42,20 @@ find_path(PYTHONQT_INCLUDE_DIR PythonQt.h "${PYTHONQT_INSTALL_DIR}/include/PythonQt5" "${PYTHONQT_INSTALL_DIR}/src" DOC "Path to the PythonQt include directory") +find_path(PYTHONQT_ALL_INCLUDE_DIR PythonQt_QtAll.h + PATHS + "${PYTHONQT_INCLUDE_DIR}" + "${PYTHONQT_INSTALL_DIR}" + PATH_SUFFIXES + "extensions/PythonQt_QtAll" + "src" + DOC "Path to the PythonQt 'all' header") if ( NOT PythonQt_FIND_QUIETLY ) message( STATUS "Searching for PythonQt (PythonLibs ${PYTHONLIBS_MAJMIN}) .." ) if ( PYTHONQT_INCLUDE_DIR ) message( STATUS " .. found include ${PYTHONQT_INCLUDE_DIR}" ) + message( STATUS " .. found all include ${PYTHONQT_ALL_INCLUDE_DIR}" ) endif() endif() @@ -146,6 +155,10 @@ if(PYTHONQT_INCLUDE_DIR AND PYTHONQT_LIBRARY AND PYTHONQT_QTALL_LIBRARY) set(PYTHONQT_FOUND 1) set(PythonQt_FOUND ${PYTHONQT_FOUND}) set(PYTHONQT_LIBRARIES ${PYTHONQT_LIBRARY} ${PYTHONQT_LIBUTIL} ${PYTHONQT_QTALL_LIBRARY}) + set(PYTHONQT_INCLUDE_DIRS ${PYTHONQT_INCLUDE_DIR}) + if(PYTHONQT_ALL_INCLUDE_DIR) + list(APPEND PYTHONQT_INCLUDE_DIRS ${PYTHONQT_ALL_INCLUDE_DIR}) + endif() elseif(NOT PythonQt_FIND_QUIETLY) set(_missing "") if (NOT PYTHONQT_INCLUDE_DIR) From 4602b30264e684d5fe3ead7b48e28daab2adf047 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 3 Sep 2018 06:26:26 -0400 Subject: [PATCH 108/112] [libcalamaresui] Use PYTHONQT_INCLUDE_DIRS - document new variable from the CMake module - use it in libcalamaresui to simplify #include'ing the header for the "all" extension. Suggested by Denis Proskurin. --- CMakeModules/FindPythonQt.cmake | 3 +++ src/libcalamaresui/CMakeLists.txt | 3 ++- src/libcalamaresui/modulesystem/PythonQtViewModule.cpp | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeModules/FindPythonQt.cmake b/CMakeModules/FindPythonQt.cmake index d1764a3b9..519e1c93e 100644 --- a/CMakeModules/FindPythonQt.cmake +++ b/CMakeModules/FindPythonQt.cmake @@ -2,6 +2,9 @@ # # Sets PYTHONQT_FOUND, PYTHONQT_INCLUDE_DIR, PYTHONQT_LIBRARY, PYTHONQT_LIBRARIES # +# Also sets PYTHONQT_INCLUDE_DIRS to add whatever directories +# that are needed for extensions. +# # Python is required find_package(PythonLibs) diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index efd0ebb29..79598d514 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -48,7 +48,8 @@ endif() if( WITH_PYTHONQT ) include_directories(${PYTHON_INCLUDE_DIRS}) - include_directories(${PYTHONQT_INCLUDE_DIR}) + # *_DIRS because we also use extensions + include_directories(${PYTHONQT_INCLUDE_DIRS}) list( APPEND calamaresui_SOURCES modulesystem/PythonQtViewModule.cpp diff --git a/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp b/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp index 9d0aa95e2..2af6d81e7 100644 --- a/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp +++ b/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp @@ -31,7 +31,7 @@ #include "JobQueue.h" #include -#include +#include #include #include From fe662345bd1ac47a8dbd4833b965f0ac677444a7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 3 Sep 2018 10:57:20 -0400 Subject: [PATCH 109/112] [partition] Extra helper classes for doing reset and refresh - The ResetHelper only finalized changes to the module on destruction, but calls to refresh() assumed it was already done. This leads to crashes when refresh() uses an intermediate state of the model. Introduce extra helpers, and rename refresh() to avoid calling the old implementation from any code. The new helper just creates and destroys a ResetHelper, before creating and destroying an object that calls the new refreshAfterModelChange(). FIXES #1019 --- .../partition/core/PartitionCoreModule.cpp | 73 ++++++++++++------- .../partition/core/PartitionCoreModule.h | 21 +++++- 2 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index f6eba9288..542b7e329 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -64,6 +64,37 @@ #include #include + +PartitionCoreModule::RefreshHelper::RefreshHelper(PartitionCoreModule* module) + : m_module( module ) +{ +} + +PartitionCoreModule::RefreshHelper::~RefreshHelper() +{ + m_module->refreshAfterModelChange(); +} + +class OperationHelper +{ +public: + OperationHelper( PartitionModel* model, PartitionCoreModule* core ) + : m_modelHelper( model ) + , m_coreHelper( core ) + { + } + + OperationHelper( const OperationHelper& ) = delete; + OperationHelper& operator=( const OperationHelper& ) = delete; + +private: + // Keep these in order: first the model needs to finish, + // then refresh is called. + PartitionModel::ResetHelper m_modelHelper; + PartitionCoreModule::RefreshHelper m_coreHelper; +} ; + + //- DeviceInfo --------------------------------------------- PartitionCoreModule::DeviceInfo::DeviceInfo( Device* _device ) : device( _device ) @@ -242,13 +273,11 @@ PartitionCoreModule::createPartitionTable( Device* device, PartitionTable::Table // keep previous changes info->forgetChanges(); - PartitionModel::ResetHelper helper( partitionModelForDevice( device ) ); + OperationHelper helper( partitionModelForDevice( device ), this ); CreatePartitionTableJob* job = new CreatePartitionTableJob( device, type ); job->updatePreview(); info->jobs << Calamares::job_ptr( job ); } - - refresh(); } void @@ -259,7 +288,7 @@ PartitionCoreModule::createPartition( Device* device, auto deviceInfo = infoForDevice( device ); Q_ASSERT( deviceInfo ); - PartitionModel::ResetHelper helper( partitionModelForDevice( device ) ); + OperationHelper helper( partitionModelForDevice( device ), this ); CreatePartitionJob* job = new CreatePartitionJob( device, partition ); job->updatePreview(); @@ -271,8 +300,6 @@ PartitionCoreModule::createPartition( Device* device, deviceInfo->jobs << Calamares::job_ptr( fJob ); PartitionInfo::setFlags( partition, flags ); } - - refresh(); } void @@ -301,7 +328,7 @@ PartitionCoreModule::createVolumeGroup( QString &vgName, m_deviceInfos << deviceInfo; deviceInfo->jobs << Calamares::job_ptr( job ); - refresh(); + refreshAfterModelChange(); } void @@ -314,7 +341,7 @@ PartitionCoreModule::resizeVolumeGroup( LvmDevice *device, QVector< const Partit deviceInfo->jobs << Calamares::job_ptr( job ); - refresh(); + refreshAfterModelChange(); } void @@ -330,7 +357,7 @@ PartitionCoreModule::deactivateVolumeGroup( LvmDevice *device ) // DeactivateVolumeGroupJob needs to be immediately called job->exec(); - refresh(); + refreshAfterModelChange(); } void @@ -343,7 +370,7 @@ PartitionCoreModule::removeVolumeGroup( LvmDevice *device ) deviceInfo->jobs << Calamares::job_ptr( job ); - refresh(); + refreshAfterModelChange(); } void @@ -352,7 +379,7 @@ PartitionCoreModule::deletePartition( Device* device, Partition* partition ) auto deviceInfo = infoForDevice( device ); Q_ASSERT( deviceInfo ); - PartitionModel::ResetHelper helper( partitionModelForDevice( device ) ); + OperationHelper helper( partitionModelForDevice( device ), this ); if ( partition->roles().has( PartitionRole::Extended ) ) { @@ -420,8 +447,6 @@ PartitionCoreModule::deletePartition( Device* device, Partition* partition ) job->updatePreview(); jobs << Calamares::job_ptr( job ); } - - refresh(); } void @@ -429,12 +454,10 @@ PartitionCoreModule::formatPartition( Device* device, Partition* partition ) { auto deviceInfo = infoForDevice( device ); Q_ASSERT( deviceInfo ); - PartitionModel::ResetHelper helper( partitionModelForDevice( device ) ); + OperationHelper helper( partitionModelForDevice( device ), this ); FormatPartitionJob* job = new FormatPartitionJob( device, partition ); deviceInfo->jobs << Calamares::job_ptr( job ); - - refresh(); } void @@ -445,13 +468,11 @@ PartitionCoreModule::resizePartition( Device* device, { auto deviceInfo = infoForDevice( device ); Q_ASSERT( deviceInfo ); - PartitionModel::ResetHelper helper( partitionModelForDevice( device ) ); + OperationHelper helper( partitionModelForDevice( device ), this ); ResizePartitionJob* job = new ResizePartitionJob( device, partition, first, last ); job->updatePreview(); deviceInfo->jobs << Calamares::job_ptr( job ); - - refresh(); } void @@ -461,13 +482,11 @@ PartitionCoreModule::setPartitionFlags( Device* device, { auto deviceInfo = infoForDevice( device ); Q_ASSERT( deviceInfo ); - PartitionModel::ResetHelper( partitionModelForDevice( device ) ); + OperationHelper( partitionModelForDevice( device ), this ); SetPartFlagsJob* job = new SetPartFlagsJob( device, partition, flags ); deviceInfo->jobs << Calamares::job_ptr( job ); PartitionInfo::setFlags( partition, flags ); - - refresh(); } QList< Calamares::job_ptr > @@ -573,13 +592,11 @@ PartitionCoreModule::refreshPartition( Device* device, Partition* ) // the loss of the current selection. auto model = partitionModelForDevice( device ); Q_ASSERT( model ); - PartitionModel::ResetHelper helper( model ); - - refresh(); + OperationHelper helper( model, this ); } void -PartitionCoreModule::refresh() +PartitionCoreModule::refreshAfterModelChange() { updateHasRootMountPoint(); updateIsDirty(); @@ -796,7 +813,7 @@ PartitionCoreModule::revertAllDevices() ++it; } - refresh(); + refreshAfterModelChange(); } @@ -827,7 +844,7 @@ PartitionCoreModule::revertDevice( Device* dev ) m_bootLoaderModel->init( devices ); - refresh(); + refreshAfterModelChange(); emit deviceReverted( newDev ); } diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index d61311c8a..704fff322 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -54,6 +54,25 @@ class PartitionCoreModule : public QObject { Q_OBJECT public: + /** + * This helper class calls refresh() on the module + * on destruction (nothing else). It is used as + * part of the model-consistency objects, along with + * PartitionModel::ResetHelper. + */ + class RefreshHelper + { + public: + RefreshHelper( PartitionCoreModule* module ); + ~RefreshHelper(); + + RefreshHelper( const RefreshHelper& ) = delete; + RefreshHelper& operator=( const RefreshHelper& ) = delete; + + private: + PartitionCoreModule* m_module; + }; + /** * @brief The SummaryInfo struct is a wrapper for PartitionModel instances for * a given Device. @@ -192,7 +211,7 @@ Q_SIGNALS: void deviceReverted( Device* device ); private: - void refresh(); + void refreshAfterModelChange(); /** * Owns the Device, PartitionModel and the jobs From 13015096d1a117f38c098d0f5cd2bdb2b9ac1a24 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 3 Sep 2018 15:15:00 -0400 Subject: [PATCH 110/112] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_he.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/calamares_he.ts b/lang/calamares_he.ts index b5389d5dd..fed3a48f4 100644 --- a/lang/calamares_he.ts +++ b/lang/calamares_he.ts @@ -1823,7 +1823,7 @@ The installer will quit and all changes will be lost. Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is installed. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. - + נא לבחור מראה ותחושה עבור שולחן העבודה KDE Plasma. ניתן גם לדלג על השלב הזה ולהגדיר מראה ותחושה לאחר הקמת המערכת. בחירה בתצורת מראה ותחושה תעניק לך תצוגה מקדימה חיה של אותה התצורה. @@ -2595,7 +2595,7 @@ Output: <h1>%1</h1><br/><strong>%2<br/>for %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>Copyright 2017 Adriaan de Groot &lt;groot@kde.org&gt;<br/>Thanks to: Anke Boersma, Aurélien Gâteau, Kevin Kofler, Lisa Vitolo, Philip Müller, Pier Luigi Fiorini, Rohan Garg and the <a href="https://www.transifex.com/calamares/calamares/">Calamares translators team</a>.<br/><br/><a href="https://calamares.io/">Calamares</a> development is sponsored by <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software. - + <h1>%1</h1><br/><strong>%2<br/>עבור %3</strong><br/><br/>כל הזכויות שמורות 2014‏-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>כל הזכויות שמורות 2017 Adriaan de Groot &lt;groot@kde.org&gt;<br/>תודתנו נתונה ל־: Anke Boersma, Aurélien Gâteau, Kevin Kofler, Lisa Vitolo, Philip Müller, Pier Luigi Fiorini, Rohan Garg ול<a href="https://www.transifex.com/calamares/calamares/">צוות המתרגמים של Calamares</a>.<br/><br/>הפיתוח של<a href="https://calamares.io/">Calamares</a> מוגש בחסות <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - דואגים לחופש התכנה. From c104d14086e07a1fa2b936f646340683b178a297 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 3 Sep 2018 15:21:30 -0400 Subject: [PATCH 111/112] [partition] Call the helpers in the right order. This fixes the crash by calling the model-reset first, then refreshing. Previously, the destructors that do the work were still being called in the wrong order. FIXES #1019 --- src/modules/partition/core/PartitionCoreModule.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 542b7e329..b8011f066 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -79,8 +79,8 @@ class OperationHelper { public: OperationHelper( PartitionModel* model, PartitionCoreModule* core ) - : m_modelHelper( model ) - , m_coreHelper( core ) + : m_coreHelper( core ) + , m_modelHelper( model ) { } @@ -89,9 +89,10 @@ public: private: // Keep these in order: first the model needs to finish, - // then refresh is called. - PartitionModel::ResetHelper m_modelHelper; + // then refresh is called. Remember that destructors are + // called in *reverse* order of declaration in this class. PartitionCoreModule::RefreshHelper m_coreHelper; + PartitionModel::ResetHelper m_modelHelper; } ; From 46687fcb4cc6f34c6b024a56617313922b17cc06 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 4 Sep 2018 08:03:59 -0400 Subject: [PATCH 112/112] CMake: bump version and changelog --- CHANGES | 2 +- CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 20ed48f2e..078b4d3bb 100644 --- a/CHANGES +++ b/CHANGES @@ -3,7 +3,7 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. -= 3.2.2 (unreleased) = += 3.2.2 (2018-09-04) = This release contains contributions from (alphabetically by first name): - Andrius Štikonas diff --git a/CMakeLists.txt b/CMakeLists.txt index 183bc93f3..67e155c12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,7 @@ set( CALAMARES_DESCRIPTION_SUMMARY set( CALAMARES_VERSION_MAJOR 3 ) set( CALAMARES_VERSION_MINOR 2 ) set( CALAMARES_VERSION_PATCH 2 ) -set( CALAMARES_VERSION_RC 1 ) +set( CALAMARES_VERSION_RC 0 ) ### Transifex (languages) info #