Merge branch 'kpmcore-manager'

Introduces a "partitioning service" into libcalamares,
shuffles a bunch of things into it, tries to help out
with settling the system between partitioning actions.
This commit is contained in:
Adriaan de Groot 2020-02-13 13:41:53 +01:00
commit e72ecaafd3
64 changed files with 1356 additions and 505 deletions

View File

@ -44,7 +44,9 @@ set( libSources
network/Manager.cpp
# Partition service
partition/Mount.cpp
partition/PartitionSize.cpp
partition/Sync.cpp
# Utility service
utils/CalamaresUtilsSystem.cpp
@ -111,6 +113,38 @@ if( Qt5Xml_FOUND )
list( APPEND OPTIONAL_PUBLIC_LIBRARIES Qt5::Network Qt5::Xml )
endif()
### OPTIONAL KPMcore support
#
#
find_package( KPMcore 3.3 )
set_package_properties(
KPMcore PROPERTIES
URL "https://invent.kde.org/kde/kpmcore"
DESCRIPTION "KDE Partitioning library"
TYPE RECOMMENDED
PURPOSE "For partitioning service"
)
if ( KPMcore_FOUND )
find_package( Qt5 REQUIRED DBus ) # Needed for KPMCore
find_package( KF5 REQUIRED I18n WidgetsAddons ) # Needed for KPMCore
if( KPMcore_VERSION VERSION_GREATER_EQUAL "4.0" )
add_definitions( -DWITH_KPMCORE4API ) # kpmcore 4 with new API
elseif( KPMcore_VERSION VERSION_GREATER "3.3.70" )
message( FATAL_ERROR "KPMCore beta versions ${KPMcore_VERSION} not supported" )
endif()
include_directories( ${KPMCORE_INCLUDE_DIR} )
list( APPEND libSources
partition/FileSystem.cpp
partition/KPMManager.cpp
partition/PartitionIterator.cpp
partition/PartitionQuery.cpp
)
list( APPEND OPTIONAL_PRIVATE_LIBRARIES kpmcore )
endif()
### LIBRARY
#
#

View File

@ -36,12 +36,13 @@ public:
: QThread( queue )
, m_queue( queue )
, m_jobIndex( 0 )
, m_jobCount( 0 )
{
}
virtual ~JobThread() override;
void setJobs( const JobList& jobs )
void setJobs( JobList&& jobs )
{
m_jobs = jobs;
@ -73,7 +74,7 @@ public:
}
emitProgress();
cDebug() << "Starting" << ( anyFailed ? "EMERGENCY JOB" : "job" ) << job->prettyName();
cDebug() << "Starting" << ( anyFailed ? "EMERGENCY JOB" : "job" ) << job->prettyName() << " (there are" << m_jobs.count() << " left)";
connect( job.data(), &Job::progress, this, &JobThread::emitProgress );
JobResult result = job->exec();
if ( !anyFailed && !result )
@ -103,6 +104,7 @@ private:
QList< qreal > m_jobWeights;
JobQueue* m_queue;
int m_jobIndex;
int m_jobCount;
void emitProgress( qreal jobPercent = 0 )
{
@ -193,7 +195,7 @@ void
JobQueue::start()
{
Q_ASSERT( !m_thread->isRunning() );
m_thread->setJobs( m_jobs );
m_thread->setJobs( std::move( m_jobs ) );
m_jobs.clear();
m_thread->start();
}

View File

@ -22,6 +22,7 @@
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "PythonHelper.h"
#include "partition/Mount.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include "utils/String.h"
@ -63,10 +64,10 @@ mount( const std::string& device_path,
const std::string& filesystem_name,
const std::string& options )
{
return CalamaresUtils::System::instance()->mount( QString::fromStdString( device_path ),
QString::fromStdString( mount_point ),
QString::fromStdString( filesystem_name ),
QString::fromStdString( options ) );
return CalamaresUtils::Partition::mount( QString::fromStdString( device_path ),
QString::fromStdString( mount_point ),
QString::fromStdString( filesystem_name ),
QString::fromStdString( options ) );
}

View File

@ -0,0 +1,74 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
* Copyright 2015-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2018-2019 Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "FileSystem.h"
#include <QObject>
namespace CalamaresUtils
{
namespace Partition
{
QString
prettyNameForFileSystemType( FileSystem::Type t )
{
switch ( t )
{
case FileSystem::Unknown:
return QObject::tr( "unknown" );
case FileSystem::Extended:
return QObject::tr( "extended" );
case FileSystem::Unformatted:
return QObject::tr( "unformatted" );
case FileSystem::LinuxSwap:
return QObject::tr( "swap" );
case FileSystem::Fat16:
case FileSystem::Fat32:
case FileSystem::Ntfs:
case FileSystem::Xfs:
case FileSystem::Jfs:
case FileSystem::Hfs:
case FileSystem::Ufs:
case FileSystem::Hpfs:
case FileSystem::Luks:
case FileSystem::Ocfs2:
case FileSystem::Zfs:
case FileSystem::Nilfs2:
return FileSystem::nameForType( t ).toUpper();
case FileSystem::ReiserFS:
return "ReiserFS";
case FileSystem::Reiser4:
return "Reiser4";
case FileSystem::HfsPlus:
return "HFS+";
case FileSystem::Btrfs:
return "Btrfs";
case FileSystem::Exfat:
return "exFAT";
case FileSystem::Lvm2_PV:
return "LVM PV";
default:
return FileSystem::nameForType( t );
}
}
} // namespace Partition
} // namespace CalamaresUtils

View File

@ -0,0 +1,39 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
* Copyright 2015-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* NOTE: this functionality is only available when Calamares is compiled
* with KPMcore support.
*/
#ifndef PARTITION_FILESYSTEM_H
#define PARTITION_FILESYSTEM_H
#include <kpmcore/fs/filesystem.h>
namespace CalamaresUtils
{
namespace Partition
{
QString prettyNameForFileSystemType( FileSystem::Type t );
} // namespace Partition
} // namespace CalamaresUtils
#endif // PARTITION_PARTITIONQUERY_H

View File

@ -0,0 +1,128 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "KPMManager.h"
#include "utils/Logger.h"
#include <kpmcore/backend/corebackend.h>
#include <kpmcore/backend/corebackendmanager.h>
#if defined( WITH_KPMCORE4API )
#include <kpmcore/util/externalcommand.h>
#endif
#include <QObject>
namespace CalamaresUtils
{
namespace Partition
{
class InternalManager
{
public:
InternalManager();
~InternalManager();
};
static bool s_kpm_loaded = false;
/*
* We have one living InternalManager object at a time.
* It is managed by shared_ptr<>s help by KPMManager
* objects, but since we can create KPMManager objects
* independent of each other, all of which share ownership
* of the same InternalManager, hang on to one extra reference
* to the InternalManager so we can hand it out in getInternal().
*/
static std::weak_ptr< InternalManager > s_backend;
InternalManager::InternalManager()
{
cDebug() << "KPMCore backend starting ..";
Q_ASSERT( s_backend.expired() );
if ( !s_kpm_loaded )
{
QByteArray backendName = qgetenv( "KPMCORE_BACKEND" );
if ( !CoreBackendManager::self()->load( backendName.isEmpty() ? CoreBackendManager::defaultBackendName()
: backendName ) )
{
cWarning() << "Failed to load backend plugin" << backendName;
}
else
{
auto* backend_p = CoreBackendManager::self()->backend();
cDebug() << Logger::SubEntry << "Backend @" << (void*)backend_p << backend_p->id() << backend_p->version();
s_kpm_loaded = true;
}
}
}
InternalManager::~InternalManager()
{
cDebug() << "Cleaning up KPMCore backend ..";
#if defined( WITH_KPMCORE4API )
auto backend_p = CoreBackendManager::self()->backend();
if ( backend_p )
{
ExternalCommand::stopHelper();
}
#endif
}
std::shared_ptr< InternalManager >
getInternal()
{
if ( s_backend.expired() )
{
auto p = std::make_shared< InternalManager >();
s_backend = p;
return p;
}
return s_backend.lock();
}
KPMManager::KPMManager()
: m_d( getInternal() )
{
cDebug() << "KPMManager" << s_backend.use_count() << "created.";
}
KPMManager::~KPMManager()
{
cDebug() << "KPMManager" << s_backend.use_count() << "being destroyed.";
}
KPMManager::operator bool() const
{
return s_kpm_loaded;
}
CoreBackend*
KPMManager::backend() const
{
return s_kpm_loaded ? CoreBackendManager::self()->backend() : nullptr;
}
} // namespace Partition
} // namespace CalamaresUtils

View File

@ -0,0 +1,69 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* NOTE: this functionality is only available when Calamares is compiled
* with KPMcore support.
*/
#ifndef PARTITION_KPMMANAGER_H
#define PARTITION_KPMMANAGER_H
#include <memory>
class CoreBackend;
namespace CalamaresUtils
{
namespace Partition
{
/// @brief Handle to KPMCore
class InternalManager;
/** @brief KPMCore loader and cleanup
*
* A Calamares plugin that uses KPMCore should hold an object of
* this class; its only responsibility is to load KPMCore
* and to cleanly unload it on destruction (with KPMCore 4,
* also to shutdown the privileged helper application).
*
* It loads the default plugin ("parted" with KPMCore 3, "sfdisk"
* with KPMCore 4), but this can be overridden by setting the
* environment variable KPMCORE_BACKEND. Setting it to
* "dummy" will load the dummy plugin instead.
*/
class KPMManager
{
public:
KPMManager();
~KPMManager();
/// @brief Is KPMCore loaded correctly?
operator bool() const;
/// @brief Gets the KPMCore backend (e.g. CoreBackendManager::self()->backend() )
CoreBackend* backend() const;
private:
std::shared_ptr< InternalManager > m_d;
};
} // namespace Partition
} // namespace CalamaresUtils
#endif // PARTITION_KPMMANAGER_H

View File

@ -0,0 +1,132 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
* Copyright 2017-2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Mount.h"
#include "partition/Sync.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include <QDir>
#include <QTemporaryDir>
namespace CalamaresUtils
{
namespace Partition
{
int
mount( const QString& devicePath, const QString& mountPoint, const QString& filesystemName, const QString& options )
{
if ( devicePath.isEmpty() || mountPoint.isEmpty() )
{
if ( devicePath.isEmpty() )
{
cWarning() << "Can't mount an empty device.";
}
if ( mountPoint.isEmpty() )
{
cWarning() << "Can't mount on an empty mountpoint.";
}
return static_cast< int >( ProcessResult::Code::NoWorkingDirectory );
}
QDir mountPointDir( mountPoint );
if ( !mountPointDir.exists() )
{
bool ok = mountPointDir.mkpath( mountPoint );
if ( !ok )
{
cWarning() << "Could not create mountpoint" << mountPoint;
return static_cast< int >( ProcessResult::Code::NoWorkingDirectory );
}
}
QStringList args = { "mount" };
if ( !filesystemName.isEmpty() )
{
args << "-t" << filesystemName;
}
if ( !options.isEmpty() )
{
if ( options.startsWith( '-' ) )
{
args << options;
}
else
{
args << "-o" << options;
}
}
args << devicePath << mountPoint;
auto r = CalamaresUtils::System::runCommand( args, std::chrono::seconds( 10 ) );
sync();
return r.getExitCode();
}
int
unmount( const QString& path, const QStringList& options )
{
auto r
= CalamaresUtils::System::runCommand( QStringList { "umount" } << options << path, std::chrono::seconds( 10 ) );
sync();
return r.getExitCode();
}
struct TemporaryMount::Private
{
QString m_devicePath;
QTemporaryDir m_mountDir;
};
TemporaryMount::TemporaryMount( const QString& devicePath, const QString& filesystemName, const QString& options )
: m_d( new Private )
{
m_d->m_devicePath = devicePath;
m_d->m_mountDir.setAutoRemove( false );
int r = mount( devicePath, m_d->m_mountDir.path(), filesystemName, options );
if ( !r )
{
delete m_d;
m_d = nullptr;
}
}
TemporaryMount::~TemporaryMount()
{
if ( m_d )
{
unmount( m_d->m_devicePath, { "-R" } );
delete m_d;
m_d = nullptr;
}
}
QString
TemporaryMount::path() const
{
return m_d ? m_d->m_mountDir.path() : QString();
}
} // namespace Partition
} // namespace CalamaresUtils

View File

@ -0,0 +1,80 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
* Copyright 2017-2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PARTITION_MOUNT_H
#define PARTITION_MOUNT_H
#include "DllMacro.h"
#include <QString>
#include <QStringList>
namespace CalamaresUtils
{
namespace Partition
{
/**
* Runs the mount utility with the specified parameters.
* @param devicePath the path of the partition to mount.
* @param mountPoint the full path of the target mount point.
* @param filesystemName the name of the filesystem (optional).
* @param options any additional options as passed to mount -o (optional).
* If @p options starts with a dash (-) then it is passed unchanged
* and no -o option is added; this is used in handling --bind mounts.
* @returns the program's exit code, or:
* Crashed = QProcess crash
* FailedToStart = QProcess cannot start
* NoWorkingDirectory = bad arguments
*/
DLLEXPORT int mount( const QString& devicePath,
const QString& mountPoint,
const QString& filesystemName = QString(),
const QString& options = QString() );
/** @brief Unmount the given @p path (device or mount point).
*
* Runs umount(8) in the host system.
*
* @returns the program's exit code, or special codes like mount().
*/
DLLEXPORT int unmount( const QString& path, const QStringList& options = QStringList() );
class DLLEXPORT TemporaryMount
{
public:
TemporaryMount( const QString& devicePath,
const QString& filesystemName = QString(),
const QString& options = QString() );
TemporaryMount( const TemporaryMount& ) = delete;
TemporaryMount& operator=( const TemporaryMount& ) = delete;
~TemporaryMount();
bool isValid() const { return m_d; }
QString path() const;
private:
struct Private;
Private* m_d = nullptr;
};
} // namespace Partition
} // namespace CalamaresUtils
#endif

View File

@ -2,7 +2,7 @@
*
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
* Copyright 2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2017, Adriaan de Groot <groot@kde.org>
* Copyright 2017, 2019 Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -25,12 +25,19 @@
#include <kpmcore/core/partition.h>
#include <kpmcore/core/partitiontable.h>
namespace CalamaresUtils
{
namespace Partition
{
using Partition = ::Partition;
PartitionIterator::PartitionIterator( PartitionTable* table )
: m_table( table )
{}
{
}
Partition*
PartitionIterator::operator*() const
Partition* PartitionIterator::operator*() const
{
return m_current;
}
@ -39,7 +46,9 @@ void
PartitionIterator::operator++()
{
if ( !m_current )
{
return;
}
if ( m_current->hasChildren() )
{
// Go to the first child
@ -78,18 +87,21 @@ PartitionIterator::operator==( const PartitionIterator& other ) const
bool
PartitionIterator::operator!=( const PartitionIterator& other ) const
{
return ! ( *this == other );
return !( *this == other );
}
PartitionIterator
PartitionIterator::begin( Device* device )
{
if ( !device )
{
return PartitionIterator( nullptr );
Q_ASSERT(device);
}
PartitionTable* table = device->partitionTable();
if ( !table )
{
return PartitionIterator( nullptr );
}
return PartitionIterator::begin( table );
}
@ -101,7 +113,9 @@ PartitionIterator::begin( PartitionTable* table )
// Does not usually happen, but it did happen on a tiny (10MiB) disk with an MBR
// partition table.
if ( children.isEmpty() )
{
return it;
}
it.m_current = children.first();
return it;
}
@ -110,10 +124,14 @@ PartitionIterator
PartitionIterator::end( Device* device )
{
if ( !device )
{
return PartitionIterator( nullptr );
}
PartitionTable* table = device->partitionTable();
if ( !table )
{
return PartitionIterator( nullptr );
}
return PartitionIterator::end( table );
}
@ -123,3 +141,6 @@ PartitionIterator::end( PartitionTable* table )
{
return PartitionIterator( table );
}
} // namespace Partition
} // namespace CalamaresUtils

View File

@ -2,6 +2,7 @@
*
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
* Copyright 2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -17,37 +18,57 @@
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PARTITIONITERATOR_H
#define PARTITIONITERATOR_H
/*
* NOTE: this functionality is only available when Calamares is compiled
* with KPMcore support.
*/
#ifndef PARTITION_PARTITIONITERATOR_H
#define PARTITION_PARTITIONITERATOR_H
class Device;
class Partition;
class PartitionTable;
/**
namespace CalamaresUtils
{
namespace Partition
{
/** @brief Iterator over KPMCore partitions
*
* A forward-only iterator to go through the partitions of a device,
* independently of whether they are primary, logical or extended.
*
* An iterator can be created from a device (then it refers to the
* partition table of that device) or a partition table. The
* partition table must remain valid throughout iteration.
*
* A nullptr is valid, for an empty iterator.
*/
class PartitionIterator
{
public:
Partition* operator*() const;
::Partition* operator*() const;
void operator++();
bool operator==( const PartitionIterator& other ) const;
bool operator!=( const PartitionIterator& other ) const;
static PartitionIterator begin( Device* device );
static PartitionIterator begin( PartitionTable* table );
static PartitionIterator end( Device* device );
static PartitionIterator end( PartitionTable* table );
static PartitionIterator begin( ::Device* device );
static PartitionIterator begin( ::PartitionTable* table );
static PartitionIterator end( ::Device* device );
static PartitionIterator end( ::PartitionTable* table );
private:
PartitionIterator( PartitionTable* table );
PartitionIterator( ::PartitionTable* table );
PartitionTable* m_table;
Partition* m_current = nullptr;
::PartitionTable* m_table;
::Partition* m_current = nullptr;
};
#endif /* PARTITIONITERATOR_H */
} // namespace Partition
} // namespace CalamaresUtils
#endif // PARTITION_PARTITIONITERATOR_H

View File

@ -0,0 +1,102 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
* Copyright 2015-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2018-2019 Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "PartitionQuery.h"
#include "PartitionIterator.h"
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
namespace CalamaresUtils
{
namespace Partition
{
// Types from KPMCore
using ::Device;
using ::Partition;
bool
isPartitionFreeSpace( Partition* partition )
{
return partition->roles().has( PartitionRole::Unallocated );
}
bool
isPartitionNew( Partition* partition )
{
#if defined( WITH_KPMCORE4API )
constexpr auto NewState = Partition::State::New;
#else
constexpr auto NewState = Partition::StateNew;
#endif
return partition->state() == NewState;
}
Partition*
findPartitionByCurrentMountPoint( const QList< Device* >& devices, const QString& mountPoint )
{
for ( auto device : devices )
for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it )
if ( ( *it )->mountPoint() == mountPoint )
{
return *it;
}
return nullptr;
}
Partition*
findPartitionByPath( const QList< Device* >& devices, const QString& path )
{
if ( path.simplified().isEmpty() )
{
return nullptr;
}
for ( auto device : devices )
for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it )
if ( ( *it )->partitionPath() == path.simplified() )
{
return *it;
}
return nullptr;
}
QList< Partition* >
findPartitions( const QList< Device* >& devices, std::function< bool( Partition* ) > criterionFunction )
{
QList< Partition* > results;
for ( auto device : devices )
for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it )
if ( criterionFunction( *it ) )
{
results.append( *it );
}
return results;
}
} // namespace Partition
} // namespace CalamaresUtils

View File

@ -0,0 +1,78 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
* Copyright 2015-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* NOTE: this functionality is only available when Calamares is compiled
* with KPMcore support.
*/
#ifndef PARTITION_PARTITIONQUERY_H
#define PARTITION_PARTITIONQUERY_H
#include <QList>
#include <functional>
class Device;
class Partition;
namespace CalamaresUtils
{
namespace Partition
{
using ::Device;
using ::Partition;
/** @brief Is this a free-space area? */
bool isPartitionFreeSpace( Partition* );
/** @brief Is this partition newly-to-be-created?
*
* Returns true if the partition is planned to be created by the installer as
* opposed to already existing on the disk.
*/
bool isPartitionNew( Partition* );
/**
* Iterates on all devices and return the first partition which is (already)
* mounted on @p mountPoint.
*/
Partition* findPartitionByCurrentMountPoint( const QList< Device* >& devices, const QString& mountPoint );
// TODO: add this distinction
// Partition* findPartitionByIntendedMountPoint( const QList< Device* >& devices, const QString& mountPoint );
/**
* Iterates on all devices and partitions and returns a pointer to the Partition object
* for the given path, or nullptr if a Partition for the given path cannot be found.
*/
Partition* findPartitionByPath( const QList< Device* >& devices, const QString& path );
/**
* Iterates on all devices and partitions and returns a list of pointers to the Partition
* objects that satisfy the conditions defined in the criterion function.
*/
QList< Partition* > findPartitions( const QList< Device* >& devices,
std::function< bool( Partition* ) > criterionFunction );
} // namespace Partition
} // namespace CalamaresUtils
#endif // PARTITION_PARTITIONQUERY_H

View File

@ -0,0 +1,36 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Sync.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
void
CalamaresUtils::Partition::sync()
{
auto r = CalamaresUtils::System::runCommand( { "/sbin/udevadm", "settle" }, std::chrono::seconds( 10 ) );
if ( r.getExitCode() != 0 )
{
cWarning() << "Could not settle disks.";
r.explainProcess( "udevadm", std::chrono::seconds( 10 ) );
}
CalamaresUtils::System::runCommand( { "/bin/sync" }, std::chrono::seconds( 10 ) );
}

View File

@ -0,0 +1,46 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PARTITION_SYNC_H
#define PARTITION_SYNC_H
namespace CalamaresUtils
{
namespace Partition
{
/** @brief Run "udevadm settle" or other disk-sync mechanism.
*
* Call this after mounting, unmount, toggling swap, or other functions
* that might cause the disk to be "busy" for other disk-modifying
* actions (in particular, KPMcore actions with the sfdisk backend
* are sensitive, and systemd tends to keep disks busy after a change
* for a while).
*/
void sync();
/** @brief RAII class for calling sync() */
struct Syncer
{
~Syncer() { sync(); }
};
} // namespace Partition
} // namespace CalamaresUtils
#endif

View File

@ -117,53 +117,6 @@ System::instance()
}
int
System::mount( const QString& devicePath,
const QString& mountPoint,
const QString& filesystemName,
const QString& options )
{
if ( devicePath.isEmpty() || mountPoint.isEmpty() )
{
if ( devicePath.isEmpty() )
{
cWarning() << "Can't mount an empty device.";
}
if ( mountPoint.isEmpty() )
{
cWarning() << "Can't mount on an empty mountpoint.";
}
return static_cast< int >( ProcessResult::Code::NoWorkingDirectory );
}
QDir mountPointDir( mountPoint );
if ( !mountPointDir.exists() )
{
bool ok = mountPointDir.mkpath( mountPoint );
if ( !ok )
{
cWarning() << "Could not create mountpoint" << mountPoint;
return static_cast< int >( ProcessResult::Code::NoWorkingDirectory );
}
}
QString program( "mount" );
QStringList args = { devicePath, mountPoint };
if ( !filesystemName.isEmpty() )
{
args << "-t" << filesystemName;
}
if ( !options.isEmpty() )
{
args << "-o" << options;
}
return QProcess::execute( program, args );
}
ProcessResult
System::runCommand( System::RunLocation location,
const QStringList& args,

View File

@ -103,23 +103,6 @@ public:
static System* instance();
/**
* Runs the mount utility with the specified parameters.
* @param devicePath the path of the partition to mount.
* @param mountPoint the full path of the target mount point.
* @param filesystemName the name of the filesystem (optional).
* @param options any additional options as passed to mount -o (optional).
* @returns the program's exit code, or:
* Crashed = QProcess crash
* FailedToStart = QProcess cannot start
* NoWorkingDirectory = bad arguments
*/
DLLEXPORT int mount( const QString& devicePath,
const QString& mountPoint,
const QString& filesystemName = QString(),
const QString& options = QString() );
/** (Typed) Boolean describing where a particular command should be run,
* whether in the host (live) system or in the (chroot) target system.
*/
@ -152,6 +135,16 @@ public:
const QString& stdInput = QString(),
std::chrono::seconds timeoutSec = std::chrono::seconds( 0 ) );
/** @brief Convenience wrapper for runCommand()
*
* Runs the given command-line @p args in the host in the current direcory
* with no input, and the given @p timeoutSec for completion.
*/
static inline ProcessResult runCommand( const QStringList& args, std::chrono::seconds timeoutSec )
{
return runCommand( RunLocation::RunInHost, args, QString(), QString(), timeoutSec );
}
/** @brief Convenience wrapper for runCommand().
* Runs the command in the location specified through the boolean
* doChroot(), which is what you usually want for running commands

View File

@ -1,6 +1,7 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -18,6 +19,7 @@
#include "PythonQtUtilsWrapper.h"
#include "partition/Mount.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include "utils/String.h"
@ -46,7 +48,7 @@ Utils::mount( const QString& device_path,
const QString& filesystem_name,
const QString& options ) const
{
return CalamaresUtils::System::instance()->mount( device_path, mount_point, filesystem_name, options );
return CalamaresUtils::Partition::mount( device_path, mount_point, filesystem_name, options );
}

View File

@ -8,11 +8,10 @@ set( _partition_defs "" )
if ( KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND )
include_directories( ${KPMCORE_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/src/modules/partition )
if ( KPMcore_VERSION VERSION_GREATER "3.3.0")
list( APPEND _partition_defs WITH_KPMCORE331API) # kpmcore > 3.3.0 with deprecations
endif()
if ( KPMcore_VERSION VERSION_GREATER "3.90")
list( APPEND _partition_defs WITH_KPMCORE4API) # kpmcore 4 with new API
if( KPMcore_VERSION VERSION_GREATER_EQUAL "4.0" )
list( APPEND _partition_defs WITH_KPMCORE4API ) # kpmcore 4 with new API
elseif( KPMcore_VERSION VERSION_GREATER "3.3.70" )
message( FATAL_ERROR "KPMCore beta versions ${KPMcore_VERSION} are not supported" )
endif()
# The PartitionIterator is a small class, and it's easiest -- but also a
@ -22,7 +21,6 @@ if ( KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
ResizeFSJob.cpp
${PROJECT_SOURCE_DIR}/src/modules/partition/core/PartitionIterator.cpp
LINK_PRIVATE_LIBRARIES
kpmcore
calamares

View File

@ -18,6 +18,14 @@
#include "ResizeFSJob.h"
#include "CalamaresVersion.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "partition/PartitionIterator.h"
#include "utils/Logger.h"
#include "utils/Units.h"
#include "utils/Variant.h"
#include <QProcess>
#include <QDateTime>
#include <QThread>
@ -29,17 +37,7 @@
#include <kpmcore/ops/resizeoperation.h>
#include <kpmcore/util/report.h>
#include "CalamaresVersion.h"
#include "JobQueue.h"
#include "GlobalStorage.h"
#include "utils/Logger.h"
#include "utils/Units.h"
#include "utils/Variant.h"
// From partition module
#include "core/PartitionIterator.h"
using CalamaresUtils::Partition::PartitionIterator;
ResizeFSJob::ResizeFSJob( QObject* parent )
: Calamares::CppJob( parent )
@ -60,13 +58,13 @@ ResizeFSJob::prettyName() const
}
ResizeFSJob::PartitionMatch
ResizeFSJob::findPartition( CoreBackend* backend )
ResizeFSJob::findPartition()
{
using DeviceList = QList< Device* >;
#ifdef WITH_KPMCORE331API
DeviceList devices = backend->scanDevices( /* not includeReadOnly, not includeLoopback */ ScanFlag(0) );
#if defined( WITH_KPMCORE4API )
DeviceList devices = m_kpmcore.backend()->scanDevices( /* not includeReadOnly, not includeLoopback */ ScanFlag(0) );
#else
DeviceList devices = backend->scanDevices( /* excludeReadOnly */ true );
DeviceList devices = m_kpmcore.backend()->scanDevices( /* excludeReadOnly */ true );
#endif
cDebug() << "ResizeFSJob found" << devices.count() << "devices.";
@ -172,35 +170,17 @@ ResizeFSJob::exec()
tr( "Invalid configuration" ),
tr( "The file-system resize job has an invalid configuration and will not run." ) );
// Get KPMCore
auto backend_p = CoreBackendManager::self()->backend();
if ( backend_p )
cDebug() << "KPMCore backend @" << ( void* )backend_p << backend_p->id() << backend_p->version();
else
{
cDebug() << "No KPMCore backend loaded yet";
QByteArray backendName = qgetenv( "KPMCORE_BACKEND" );
if ( !CoreBackendManager::self()->load( backendName.isEmpty() ? CoreBackendManager::defaultBackendName() : backendName ) )
{
cWarning() << "Could not load KPMCore backend.";
return Calamares::JobResult::error(
tr( "KPMCore not Available" ),
tr( "Calamares cannot start KPMCore for the file-system resize job." ) );
}
backend_p = CoreBackendManager::self()->backend();
}
if ( !backend_p )
if ( !m_kpmcore)
{
cWarning() << "Could not load KPMCore backend (2).";
return Calamares::JobResult::error(
tr( "KPMCore not Available" ),
tr( "Calamares cannot start KPMCore for the file-system resize job." ) );
}
backend_p->initFSSupport(); // Might not be enough, see below
m_kpmcore.backend()->initFSSupport(); // Might not be enough, see below
// Now get the partition and FS we want to work on
PartitionMatch m = findPartition( backend_p );
PartitionMatch m = findPartition();
if ( !m.first || !m.second )
return Calamares::JobResult::error(
tr( "Resize Failed" ),

View File

@ -24,6 +24,7 @@
#include <CppJob.h>
#include "partition/KPMManager.h"
#include "partition/PartitionSize.h"
#include "utils/PluginFactory.h"
@ -72,6 +73,7 @@ public:
}
private:
CalamaresUtils::Partition::KPMManager m_kpmcore;
PartitionSize m_size;
PartitionSize m_atleast;
QString m_fsname; // Either this, or devicename, is set, not both
@ -79,8 +81,8 @@ private:
bool m_required;
using PartitionMatch = QPair<Device*, Partition*>;
/** @brief Find the configured FS using KPMCore @p backend */
PartitionMatch findPartition( CoreBackend* backend );
/** @brief Find the configured FS */
PartitionMatch findPartition();
/** @brief Return a new end-sector for the given dev-part pair. */
qint64 findGrownEnd( PartitionMatch );

View File

@ -20,7 +20,7 @@ find_package(ECM ${ECM_VERSION} REQUIRED NO_MODULE)
find_package( KPMcore 3.3 )
set_package_properties(
KPMcore PROPERTIES
PURPOSE "For partitioning module"
PURPOSE "For partition module"
)
find_package( KF5Config CONFIG )
find_package( KF5I18n CONFIG )
@ -51,7 +51,6 @@ if ( KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND
core/PartitionActions.cpp
core/PartitionCoreModule.cpp
core/PartitionInfo.cpp
core/PartitionIterator.cpp
core/PartitionLayout.cpp
core/PartitionModel.cpp
core/PartUtils.cpp

View File

@ -20,8 +20,9 @@
#include "core/ColorUtils.h"
#include "core/KPMHelpers.h"
#include "core/PartitionIterator.h"
#include "partition/PartitionIterator.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
// KPMcore
@ -32,6 +33,10 @@
#include <QColor>
#include <QMap>
using CalamaresUtils::Partition::PartitionIterator;
using CalamaresUtils::Partition::isPartitionFreeSpace;
using CalamaresUtils::Partition::isPartitionNew;
static const int NUM_PARTITION_COLORS = 5;
static const int NUM_NEW_PARTITION_COLORS = 4;
//Let's try to use the Breeze palette
@ -89,7 +94,7 @@ colorForPartition( Partition* partition )
return FREE_SPACE_COLOR;
}
if ( KPMHelpers::isPartitionFreeSpace( partition ) )
if ( isPartitionFreeSpace( partition ) )
return FREE_SPACE_COLOR;
if ( partition->roles().has( PartitionRole::Extended ) )
return EXTENDED_COLOR;
@ -124,16 +129,16 @@ colorForPartition( Partition* partition )
Partition* child = *it;
if ( child == partition )
break;
if ( !KPMHelpers::isPartitionFreeSpace( child ) &&
if ( !isPartitionFreeSpace( child ) &&
!child->hasChildren() )
{
if ( KPMHelpers::isPartitionNew( child ) )
if ( isPartitionNew( child ) )
++newColorIdx;
++colorIdx;
}
}
if ( KPMHelpers::isPartitionNew( partition ) )
if ( isPartitionNew( partition ) )
return NEW_PARTITION_COLORS[ newColorIdx % NUM_NEW_PARTITION_COLORS ];
if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone &&
@ -170,9 +175,9 @@ colorForPartitionInFreeSpace( Partition* partition )
Partition* child = *it;
if ( child == partition )
break;
if ( !KPMHelpers::isPartitionFreeSpace( child ) &&
if ( !isPartitionFreeSpace( child ) &&
!child->hasChildren() &&
KPMHelpers::isPartitionNew( child ) )
isPartitionNew( child ) )
++newColorIdx;
}
return NEW_PARTITION_COLORS[ newColorIdx % NUM_NEW_PARTITION_COLORS ];

View File

@ -20,23 +20,24 @@
#include "DeviceList.h"
#include "PartitionCoreModule.h"
#include "core/DeviceModel.h"
#include "core/KPMHelpers.h"
#include "core/PartitionIterator.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "partition/PartitionIterator.h"
#include "utils/Logger.h"
#include <kpmcore/backend/corebackend.h>
#include <kpmcore/backend/corebackendmanager.h>
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <utils/Logger.h>
#include <JobQueue.h>
#include <GlobalStorage.h>
#include <QProcess>
#include <QTemporaryDir>
using CalamaresUtils::Partition::PartitionIterator;
namespace PartUtils
{
@ -108,7 +109,7 @@ QList< Device* > getDevices( DeviceType which, qint64 minimumSize )
bool writableOnly = (which == DeviceType::WritableOnly);
CoreBackend* backend = CoreBackendManager::self()->backend();
#ifdef WITH_KPMCORE331API
#if defined( WITH_KPMCORE4API )
DeviceList devices = backend->scanDevices( /* not includeReadOnly, not includeLoopback */ ScanFlag(0) );
#else
DeviceList devices = backend->scanDevices( /* excludeReadOnly */ true );

View File

@ -21,7 +21,9 @@
#include "core/KPMHelpers.h"
#include "core/PartitionInfo.h"
#include "core/PartitionIterator.h"
#include "partition/PartitionIterator.h"
#include "utils/Logger.h"
// KPMcore
#include <kpmcore/core/device.h>
@ -30,47 +32,11 @@
#include <kpmcore/backend/corebackendmanager.h>
#include <kpmcore/fs/luks.h>
#include "utils/Logger.h"
#include <QDebug>
using CalamaresUtils::Partition::PartitionIterator;
namespace KPMHelpers
{
static bool s_KPMcoreInited = false;
bool
initKPMcore()
{
if ( s_KPMcoreInited )
return true;
QByteArray backendName = qgetenv( "KPMCORE_BACKEND" );
if ( !CoreBackendManager::self()->load( backendName.isEmpty() ? CoreBackendManager::defaultBackendName() : backendName ) )
{
cWarning() << "Failed to load backend plugin" << backendName;
return false;
}
s_KPMcoreInited = true;
return true;
}
bool
isPartitionFreeSpace( Partition* partition )
{
return partition->roles().has( PartitionRole::Unallocated );
}
bool
isPartitionNew( Partition* partition )
{
return partition->state() == KPM_PARTITION_STATE(New);
}
Partition*
findPartitionByMountPoint( const QList< Device* >& devices, const QString& mountPoint )
{
@ -82,33 +48,6 @@ findPartitionByMountPoint( const QList< Device* >& devices, const QString& mount
}
Partition*
findPartitionByPath( const QList< Device* >& devices, const QString& path )
{
if ( path.simplified().isEmpty() )
return nullptr;
for ( auto device : devices )
for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it )
if ( ( *it )->partitionPath() == path.simplified() )
return *it;
return nullptr;
}
QList< Partition* >
findPartitions( const QList< Device* >& devices,
std::function< bool ( Partition* ) > criterionFunction )
{
QList< Partition* > results;
for ( auto device : devices )
for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it )
if ( criterionFunction( *it ) )
results.append( *it );
return results;
}
Partition*
createNewPartition( PartitionNode* parent,
const Device& device,
@ -197,48 +136,4 @@ clonePartition( Device* device, Partition* partition )
partition->activeFlags() );
}
QString
prettyNameForFileSystemType( FileSystem::Type t )
{
switch ( t )
{
case FileSystem::Unknown:
return QObject::tr( "unknown" );
case FileSystem::Extended:
return QObject::tr( "extended" );
case FileSystem::Unformatted:
return QObject::tr( "unformatted" );
case FileSystem::LinuxSwap:
return QObject::tr( "swap" );
case FileSystem::Fat16:
case FileSystem::Fat32:
case FileSystem::Ntfs:
case FileSystem::Xfs:
case FileSystem::Jfs:
case FileSystem::Hfs:
case FileSystem::Ufs:
case FileSystem::Hpfs:
case FileSystem::Luks:
case FileSystem::Ocfs2:
case FileSystem::Zfs:
case FileSystem::Nilfs2:
return FileSystem::nameForType( t ).toUpper();
case FileSystem::ReiserFS:
return "ReiserFS";
case FileSystem::Reiser4:
return "Reiser4";
case FileSystem::HfsPlus:
return "HFS+";
case FileSystem::Btrfs:
return "Btrfs";
case FileSystem::Exfat:
return "exFAT";
case FileSystem::Lvm2_PV:
return "LVM PV";
default:
return FileSystem::nameForType( t );
}
}
} // namespace

View File

@ -34,7 +34,7 @@ class Partition;
class PartitionNode;
class PartitionRole;
#ifdef WITH_KPMCORE331API
#if defined( WITH_KPMCORE4API )
#define KPM_PARTITION_FLAG(x) PartitionTable::Flag::x
#define KPM_PARTITION_STATE(x) Partition::State::x
#define KPM_PARTITION_FLAG_ESP PartitionTable::Flag::Boot
@ -50,46 +50,12 @@ class PartitionRole;
namespace KPMHelpers
{
/**
* Thin wrapper on top of CoreBackendManager. Hides things like initializing the
* Config instance or instantiating the backend.
*
* Initialize PartitionManager Config object and load a PartitionManager
* backend. It loads the "libparted" plugin by default, but this can be
* overloaded by settings the environment variable KPMCORE_BACKEND. Setting it to
* "dummy" will load the dummy plugin instead.
*
* @return true if initialization was successful.
*/
bool initKPMcore();
bool isPartitionFreeSpace( Partition* );
/**
* Returns true if the partition is planned to be created by the installer as
* opposed to already existing on the disk.
*/
bool isPartitionNew( Partition* );
/**
* Iterates on all devices and return the first partition which is associated
* with mountPoint. This uses PartitionInfo::mountPoint(), not Partition::mountPoint()
*/
Partition* findPartitionByMountPoint( const QList< Device* >& devices, const QString& mountPoint );
/**
* Iterates on all devices and partitions and returns a pointer to the Partition object
* for the given path, or nullptr if a Partition for the given path cannot be found.
*/
Partition* findPartitionByPath( const QList< Device* >& devices, const QString& path );
/**
* Iterates on all devices and partitions and returns a list of pointers to the Partition
* objects that satisfy the conditions defined in the criterion function.
*/
QList< Partition* > findPartitions( const QList< Device* >& devices,
std::function< bool ( Partition* ) > criterionFunction );
/**
* Helper function to create a new Partition object (does not create anything
* on the disk) associated with a FileSystem.
@ -113,8 +79,6 @@ Partition* createNewEncryptedPartition( PartitionNode* parent,
Partition* clonePartition( Device* device, Partition* partition );
QString prettyNameForFileSystemType( FileSystem::Type t );
static inline QString
untranslatedFS( FileSystem& fs )
{

View File

@ -25,21 +25,26 @@
#include "core/DeviceModel.h"
#include "core/KPMHelpers.h"
#include "core/PartitionInfo.h"
#include "core/PartitionIterator.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "partition/Mount.h"
#include "partition/PartitionIterator.h"
#include "partition/PartitionQuery.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include <kpmcore/backend/corebackend.h>
#include <kpmcore/backend/corebackendmanager.h>
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <utils/CalamaresUtilsSystem.h>
#include <utils/Logger.h>
#include <JobQueue.h>
#include <GlobalStorage.h>
#include <QProcess>
#include <QTemporaryDir>
using CalamaresUtils::Partition::isPartitionFreeSpace;
using CalamaresUtils::Partition::isPartitionNew;
namespace PartUtils
{
@ -132,7 +137,7 @@ canBeResized( Partition* candidate )
return false;
}
if ( KPMHelpers::isPartitionFreeSpace( candidate ) )
if ( isPartitionFreeSpace( candidate ) )
{
cDebug() << Logger::SubEntry << "NO, partition is free space";
return false;
@ -205,7 +210,7 @@ canBeResized( PartitionCoreModule* core, const QString& partitionPath )
for ( int i = 0; i < dm->rowCount(); ++i )
{
Device* dev = dm->deviceForIndex( dm->index( i ) );
Partition* candidate = KPMHelpers::findPartitionByPath( { dev }, partitionWithOs );
Partition* candidate = CalamaresUtils::Partition::findPartitionByPath( { dev }, partitionWithOs );
if ( candidate )
{
return canBeResized( candidate );
@ -241,13 +246,11 @@ lookForFstabEntries( const QString& partitionPath )
<< "for fstab (fs=" << r.getOutput() << ')';
FstabEntryList fstabEntries;
QTemporaryDir mountsDir;
mountsDir.setAutoRemove( false );
int exit = QProcess::execute( "mount", { "-o", mountOptions.join(','), partitionPath, mountsDir.path() } );
if ( !exit ) // if all is well
CalamaresUtils::Partition::TemporaryMount mount( partitionPath, QString(), mountOptions.join(',') );
if ( mount.isValid() )
{
QFile fstabFile( mountsDir.path() + "/etc/fstab" );
QFile fstabFile( mount.path() + "/etc/fstab" );
cDebug() << Logger::SubEntry << "reading" << fstabFile.fileName();
@ -265,9 +268,6 @@ lookForFstabEntries( const QString& partitionPath )
}
else
cWarning() << "Could not read fstab from mounted fs";
if ( QProcess::execute( "umount", { "-R", mountsDir.path() } ) )
cWarning() << "Could not unmount" << mountsDir.path();
}
else
cWarning() << "Could not mount existing fs";

View File

@ -27,7 +27,6 @@
#include "core/DeviceList.h"
#include "core/DeviceModel.h"
#include "core/PartitionInfo.h"
#include "core/PartitionIterator.h"
#include "core/PartitionModel.h"
#include "core/KPMHelpers.h"
#include "core/PartUtils.h"
@ -45,12 +44,13 @@
#include "jobs/ResizeVolumeGroupJob.h"
#include "jobs/SetPartitionFlagsJob.h"
#include "utils/Variant.h"
#ifdef DEBUG_PARTITION_LAME
#include "JobExample.h"
#endif
#include "partition/PartitionIterator.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
#include "utils/Variant.h"
// KPMcore
#include <kpmcore/core/device.h>
@ -70,6 +70,9 @@
#include <QFutureWatcher>
#include <QtConcurrent/QtConcurrent>
using CalamaresUtils::Partition::PartitionIterator;
using CalamaresUtils::Partition::isPartitionFreeSpace;
using CalamaresUtils::Partition::isPartitionNew;
PartitionCoreModule::RefreshHelper::RefreshHelper(PartitionCoreModule* module)
: m_module( module )
@ -144,7 +147,7 @@ PartitionCoreModule::PartitionCoreModule( QObject* parent )
, m_deviceModel( new DeviceModel( this ) )
, m_bootLoaderModel( new BootLoaderModel( this ) )
{
if ( !KPMHelpers::initKPMcore() )
if ( !m_kpmcore )
qFatal( "Failed to initialize KPMcore backend" );
}
@ -395,7 +398,7 @@ PartitionCoreModule::deletePartition( Device* device, Partition* partition )
// deleting them, so let's play it safe and keep our own list.
QList< Partition* > lst;
for ( auto childPartition : partition->children() )
if ( !KPMHelpers::isPartitionFreeSpace( childPartition ) )
if ( !isPartitionFreeSpace( childPartition ) )
lst << childPartition;
for ( auto childPartition : lst )
@ -653,7 +656,7 @@ PartitionCoreModule::scanForEfiSystemPartitions()
}
QList< Partition* > efiSystemPartitions =
KPMHelpers::findPartitions( devices, PartUtils::isEfiBootable );
CalamaresUtils::Partition::findPartitions( devices, PartUtils::isEfiBootable );
if ( efiSystemPartitions.isEmpty() )
cWarning() << "system is EFI but no EFI system partitions found.";
@ -687,14 +690,9 @@ PartitionCoreModule::scanForLVMPVs()
#if defined( WITH_KPMCORE4API )
VolumeManagerDevice::scanDevices( physicalDevices );
for ( auto p : LVM::pvList::list() )
#else
#if defined( WITH_KPMCORE331API )
LvmDevice::scanSystemLVM( physicalDevices );
for ( auto p : LVM::pvList::list() )
#else
LvmDevice::scanSystemLVM( physicalDevices );
for ( auto p : LVM::pvList )
#endif
#endif
{
m_lvmPVs << p.partition().data();
@ -728,7 +726,7 @@ PartitionCoreModule::scanForLVMPVs()
if ( innerFS && innerFS->type() == FileSystem::Type::Lvm2_PV )
m_lvmPVs << p;
}
#ifdef WITH_KPMCORE4API
#if defined( WITH_KPMCORE4API )
else if ( p->fileSystem().type() == FileSystem::Type::Luks2 )
{
// Encrypted LVM PVs

View File

@ -26,6 +26,7 @@
#include "core/PartitionModel.h"
#include "Job.h"
#include "partition/KPMManager.h"
// KPMcore
#include <kpmcore/core/lvmdevice.h>
@ -235,6 +236,8 @@ Q_SIGNALS:
void deviceReverted( Device* device );
private:
CalamaresUtils::Partition::KPMManager m_kpmcore;
void refreshAfterModelChange();
/**

View File

@ -22,6 +22,9 @@
#include "core/ColorUtils.h"
#include "core/PartitionInfo.h"
#include "core/KPMHelpers.h"
#include "partition/FileSystem.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
// CalaPM
@ -36,6 +39,9 @@
// Qt
#include <QColor>
using CalamaresUtils::Partition::isPartitionFreeSpace;
using CalamaresUtils::Partition::isPartitionNew;
//- ResetHelper --------------------------------------------
PartitionModel::ResetHelper::ResetHelper( PartitionModel* model )
: m_model( model )
@ -140,17 +146,17 @@ PartitionModel::data( const QModelIndex& index, int role ) const
int col = index.column();
if ( col == NameColumn )
{
if ( KPMHelpers::isPartitionFreeSpace( partition ) )
if ( isPartitionFreeSpace( partition ) )
return tr( "Free Space" );
else
{
return KPMHelpers::isPartitionNew( partition )
return isPartitionNew( partition )
? tr( "New partition" )
: partition->partitionPath();
}
}
if ( col == FileSystemColumn )
return KPMHelpers::prettyNameForFileSystemType( partition->fileSystem().type() );
return CalamaresUtils::Partition::prettyNameForFileSystemType( partition->fileSystem().type() );
if ( col == MountPointColumn )
return PartitionInfo::mountPoint( partition );
if ( col == SizeColumn )
@ -172,16 +178,16 @@ PartitionModel::data( const QModelIndex& index, int role ) const
QString name;
if ( col == NameColumn )
{
if ( KPMHelpers::isPartitionFreeSpace( partition ) )
if ( isPartitionFreeSpace( partition ) )
name = tr( "Free Space" );
else
{
name = KPMHelpers::isPartitionNew( partition )
name = isPartitionNew( partition )
? tr( "New partition" )
: partition->partitionPath();
}
}
QString prettyFileSystem = KPMHelpers::prettyNameForFileSystemType( partition->fileSystem().type() );
QString prettyFileSystem = CalamaresUtils::Partition::prettyNameForFileSystemType( partition->fileSystem().type() );
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
QString prettySize = KFormat().formatByteSize( size );
return QVariant(name + " " + prettyFileSystem + " " + prettySize);
@ -189,10 +195,10 @@ PartitionModel::data( const QModelIndex& index, int role ) const
case SizeRole:
return ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
case IsFreeSpaceRole:
return KPMHelpers::isPartitionFreeSpace( partition );
return isPartitionFreeSpace( partition );
case IsPartitionNewRole:
return KPMHelpers::isPartitionNew( partition );
return isPartitionNew( partition );
case FileSystemLabelRole:
if ( partition->fileSystem().supportGetLabel() != FileSystem::cmdSupportNone &&

View File

@ -28,7 +28,6 @@
#include "core/PartitionActions.h"
#include "core/PartitionCoreModule.h"
#include "core/PartitionInfo.h"
#include "core/PartitionIterator.h"
#include "core/PartitionModel.h"
#include "BootInfoWidget.h"
@ -40,14 +39,16 @@
#include "ReplaceWidget.h"
#include "ScanningDialog.h"
#include "utils/CalamaresUtilsGui.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "partition/PartitionIterator.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
#include "utils/Retranslator.h"
#include "utils/Units.h"
#include "Branding.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/CalamaresUtilsGui.h"
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
@ -65,6 +66,9 @@
#include <QtConcurrent/QtConcurrent>
using PartitionActions::Choices::SwapChoice;
using CalamaresUtils::Partition::PartitionIterator;
using CalamaresUtils::Partition::isPartitionFreeSpace;
using CalamaresUtils::Partition::findPartitionByPath;
/** @brief Given a set of swap choices, return a sensible value from it.
*
@ -691,7 +695,7 @@ ChoicePage::doAlongsideApply()
for ( int i = 0; i < dm->rowCount(); ++i )
{
Device* dev = dm->deviceForIndex( dm->index( i ) );
Partition* candidate = KPMHelpers::findPartitionByPath( { dev }, path );
Partition* candidate = findPartitionByPath( { dev }, path );
if ( candidate )
{
qint64 firstSector = candidate->firstSector();
@ -754,7 +758,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current )
Partition* selectedPartition =
static_cast< Partition* >( current.data( PartitionModel::PartitionPtrRole )
.value< void* >() );
if ( KPMHelpers::isPartitionFreeSpace( selectedPartition ) )
if ( isPartitionFreeSpace( selectedPartition ) )
{
//NOTE: if the selected partition is free space, we don't deal with
// a separate /home partition at all because there's no existing
@ -768,7 +772,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current )
if ( parent && parent->roles().has( PartitionRole::Extended ) )
{
newRoles = PartitionRole( PartitionRole::Logical );
newParent = KPMHelpers::findPartitionByPath( { selectedDevice() }, parent->partitionPath() );
newParent = findPartitionByPath( { selectedDevice() }, parent->partitionPath() );
}
}
@ -782,7 +786,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current )
// We can't use the PartitionPtrRole because we need to make changes to the
// main DeviceModel, not the immutable copy.
QString partPath = current.data( PartitionModel::PartitionPathRole ).toString();
selectedPartition = KPMHelpers::findPartitionByPath( { selectedDevice() },
selectedPartition = findPartitionByPath( { selectedDevice() },
partPath );
if ( selectedPartition )
{
@ -805,7 +809,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current )
gs->value( "defaultFileSystemType" ).toString(),
m_encryptWidget->passphrase()
} );
Partition* homePartition = KPMHelpers::findPartitionByPath( { selectedDevice() },
Partition* homePartition = findPartitionByPath( { selectedDevice() },
*homePartitionPath );
if ( homePartition && doReuseHomePartition )

View File

@ -31,9 +31,10 @@
#include "ui_CreatePartitionDialog.h"
#include "utils/Logger.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
// KPMcore
#include <kpmcore/core/device.h>
@ -279,7 +280,7 @@ CreatePartitionDialog::checkMountPointSelection()
void
CreatePartitionDialog::initPartResizerWidget( Partition* partition )
{
QColor color = KPMHelpers::isPartitionFreeSpace( partition )
QColor color = CalamaresUtils::Partition::isPartitionFreeSpace( partition )
? ColorUtils::colorForPartitionInFreeSpace( partition )
: ColorUtils::colorForPartition( partition );
m_partitionSizeController->init( m_device, partition, color );

View File

@ -40,11 +40,13 @@
#include "ui_PartitionPage.h"
#include "ui_CreatePartitionTableDialog.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
#include "utils/Retranslator.h"
#include "Branding.h"
#include "JobQueue.h"
#include "GlobalStorage.h"
// KPMcore
#include <kpmcore/core/device.h>
@ -132,7 +134,7 @@ PartitionPage::updateButtons()
Q_ASSERT( model );
Partition* partition = model->partitionForIndex( index );
Q_ASSERT( partition );
bool isFree = KPMHelpers::isPartitionFreeSpace( partition );
bool isFree = CalamaresUtils::Partition::isPartitionFreeSpace( partition );
bool isExtended = partition->roles().has( PartitionRole::Extended );
bool isInVG = m_core->isInVG( partition );
@ -392,7 +394,7 @@ PartitionPage::onEditClicked()
Partition* partition = model->partitionForIndex( index );
Q_ASSERT( partition );
if ( KPMHelpers::isPartitionNew( partition ) )
if ( CalamaresUtils::Partition::isPartitionNew( partition ) )
updatePartitionToCreate( model->device(), partition );
else
editExistingPartition( model->device(), partition );
@ -452,7 +454,7 @@ PartitionPage::onPartitionViewActivated()
// but I don't expect there will be other occurences of triggering the same
// action from multiple UI elements in this page, so it does not feel worth
// the price.
if ( KPMHelpers::isPartitionFreeSpace( partition ) )
if ( CalamaresUtils::Partition::isPartitionFreeSpace( partition ) )
m_ui->createButton->click();
else
m_ui->editButton->click();

View File

@ -19,10 +19,12 @@
#include "PartitionSplitterWidget.h"
#include "core/ColorUtils.h"
#include "core/PartitionIterator.h"
#include "core/KPMHelpers.h"
#include "partition/PartitionIterator.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
#include "utils/CalamaresUtilsGui.h"
#include <kpmcore/core/device.h>
@ -33,6 +35,8 @@
#include <QMouseEvent>
#include <QStyleOption>
using CalamaresUtils::Partition::PartitionIterator;
static const int VIEW_HEIGHT = qMax( CalamaresUtils::defaultFontHeight() + 8, // wins out with big fonts
int( CalamaresUtils::defaultFontHeight() * 0.6 ) + 22 ); // wins out with small fonts
static const int CORNER_RADIUS = 3;
@ -66,7 +70,7 @@ PartitionSplitterWidget::init( Device* dev, bool drawNestedPartitions )
PartitionSplitterItem newItem = {
( *it )->partitionPath(),
ColorUtils::colorForPartition( *it ),
KPMHelpers::isPartitionFreeSpace( *it ),
CalamaresUtils::Partition::isPartitionFreeSpace( *it ),
( *it )->capacity(),
PartitionSplitterItem::Normal,
{}

View File

@ -75,7 +75,7 @@ PartitionViewStep::PartitionViewStep( QObject* parent )
m_waitingWidget = new WaitingWidget( QString() );
m_widget->addWidget( m_waitingWidget );
CALAMARES_RETRANSLATE( qobject_cast< WaitingWidget* >( m_waitingWidget )->setText( tr( "Gathering system information..." ) ); )
CALAMARES_RETRANSLATE( m_waitingWidget->setText( tr( "Gathering system information..." ) ); )
m_core = new PartitionCoreModule( this ); // Unusable before init is complete!
// We're not done loading, but we need the configuration map first.

View File

@ -35,6 +35,7 @@ class ChoicePage;
class PartitionPage;
class PartitionCoreModule;
class QStackedWidget;
class WaitingWidget;
template<typename T> class QFutureWatcher;
@ -82,7 +83,7 @@ private:
ChoicePage* m_choicePage;
PartitionPage* m_manualPartitionPage;
QWidget* m_waitingWidget;
WaitingWidget* m_waitingWidget;
QFutureWatcher<void>* m_future;
QSet< PartitionActions::Choices::SwapChoice > m_swapChoices;

View File

@ -21,7 +21,9 @@
#include "ClearMountsJob.h"
#include "core/PartitionInfo.h"
#include "core/PartitionIterator.h"
#include "partition/Sync.h"
#include "partition/PartitionIterator.h"
#include "utils/Logger.h"
// KPMcore
@ -33,6 +35,7 @@
#include <QProcess>
#include <QStringList>
using CalamaresUtils::Partition::PartitionIterator;
ClearMountsJob::ClearMountsJob( Device* device )
: Calamares::Job()
@ -57,25 +60,47 @@ ClearMountsJob::prettyStatusMessage() const
}
QStringList
getPartitionsForDevice( const QString& deviceName )
{
QStringList partitions;
QFile dev_partitions( "/proc/partitions" );
if ( dev_partitions.open( QFile::ReadOnly ) )
{
cDebug() << "Reading from" << dev_partitions.fileName();
QTextStream in( &dev_partitions );
(void) in.readLine(); // That's the header line, skip it
while ( !in.atEnd() )
{
// The fourth column (index from 0, so index 3) is the name of the device;
// keep it if it is followed by something.
QStringList columns = in.readLine().split( ' ', QString::SkipEmptyParts );
if ( ( columns.count() >= 4 ) && ( columns[3].startsWith( deviceName ) ) && ( columns[3] != deviceName ) )
{
partitions.append( columns[3] );
}
}
}
else
{
cDebug() << "Could not open" << dev_partitions.fileName();
}
return partitions;
}
Calamares::JobResult
ClearMountsJob::exec()
{
QStringList goodNews;
CalamaresUtils::Partition::Syncer s;
QString deviceName = m_device->deviceNode().split( '/' ).last();
QStringList goodNews;
QProcess process;
process.setProgram( "sh" );
process.setArguments( {
"-c",
QString( "echo $(awk '{print $4}' /proc/partitions | sed -e '/name/d' -e '/^$/d' -e '/[1-9]/!d' | grep %1)" )
.arg( deviceName )
} );
process.start();
process.waitForFinished();
const QString partitions = process.readAllStandardOutput();
const QStringList partitionsList = partitions.simplified().split( ' ' );
QStringList partitionsList = getPartitionsForDevice( deviceName );
// Build a list of partitions of type 82 (Linux swap / Solaris).
// We then need to clear them just in case they contain something resumable from a

View File

@ -19,7 +19,7 @@
#ifndef CLEARMOUNTSJOB_H
#define CLEARMOUNTSJOB_H
#include <Job.h>
#include "Job.h"
class Device;

View File

@ -19,7 +19,7 @@
#ifndef CLEARTEMPMOUNTSJOB_H
#define CLEARTEMPMOUNTSJOB_H
#include <Job.h>
#include "Job.h"
class Device;

View File

@ -20,7 +20,7 @@
#ifndef CREATEPARTITIONJOB_H
#define CREATEPARTITIONJOB_H
#include <jobs/PartitionJob.h>
#include "PartitionJob.h"
class Device;
class Partition;

View File

@ -20,21 +20,22 @@
#include "jobs/CreatePartitionTableJob.h"
#include "core/PartitionIterator.h"
#include "partition/PartitionIterator.h"
#include "utils/Logger.h"
// KPMcore
#include <core/device.h>
#include <core/partition.h>
#include <core/partitiontable.h>
#include <fs/filesystem.h>
#include <ops/createpartitiontableoperation.h>
#include <util/report.h>
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/core/partitiontable.h>
#include <kpmcore/fs/filesystem.h>
#include <kpmcore/ops/createpartitiontableoperation.h>
#include <kpmcore/util/report.h>
// Qt
#include <QProcess>
using CalamaresUtils::Partition::PartitionIterator;
CreatePartitionTableJob::CreatePartitionTableJob( Device* device, PartitionTable::TableType type )
: m_device( device )
, m_type( type )
@ -99,7 +100,7 @@ CreatePartitionTableJob::exec()
cDebug() << "lsblk:\n" << lsblk.readAllStandardOutput();
QProcess mount;
mount.setProgram( "mount" );
mount.setProgram( "mount" ); // Debug output only, not mounting something
mount.setProcessChannelMode( QProcess::MergedChannels );
mount.start();
mount.waitForFinished();

View File

@ -20,7 +20,8 @@
#ifndef CREATEPARTITIONTABLEJOB_H
#define CREATEPARTITIONTABLEJOB_H
#include <Job.h>
#include "Job.h"
#include "partition/KPMManager.h"
// KPMcore
#include <kpmcore/core/partitiontable.h>
@ -50,6 +51,7 @@ public:
}
private:
CalamaresUtils::Partition::KPMManager m_kpmcore;
Device* m_device;
PartitionTable::TableType m_type;
PartitionTable* createTable();

View File

@ -19,12 +19,13 @@
#ifndef CREATEVOLUMEGROUPJOB_H
#define CREATEVOLUMEGROUPJOB_H
#include <Job.h>
#include <kpmcore/core/partition.h>
#include "Job.h"
#include "partition/KPMManager.h"
#include <QVector>
class Partition;
class CreateVolumeGroupJob : public Calamares::Job
{
Q_OBJECT
@ -40,6 +41,7 @@ public:
void undoPreview();
private:
CalamaresUtils::Partition::KPMManager m_kpmcore;
QString m_vgName;
QVector< const Partition* > m_pvList;
qint32 m_peSize;

View File

@ -20,6 +20,7 @@
#define DEACTIVATEVOLUMEGROUPJOB_H
#include "Job.h"
#include "partition/KPMManager.h"
class LvmDevice;
@ -35,6 +36,7 @@ public:
Calamares::JobResult exec() override;
private:
CalamaresUtils::Partition::KPMManager m_kpmcore;
LvmDevice* m_device;
};

View File

@ -21,12 +21,12 @@
#include "jobs/DeletePartitionJob.h"
// KPMcore
#include <core/device.h>
#include <core/partition.h>
#include <core/partitiontable.h>
#include <fs/filesystem.h>
#include <ops/deleteoperation.h>
#include <util/report.h>
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/core/partitiontable.h>
#include <kpmcore/fs/filesystem.h>
#include <kpmcore/ops/deleteoperation.h>
#include <kpmcore/util/report.h>
DeletePartitionJob::DeletePartitionJob( Device* device, Partition* partition )
: PartitionJob( partition )

View File

@ -20,7 +20,7 @@
#ifndef DELETEPARTITIONJOB_H
#define DELETEPARTITIONJOB_H
#include <jobs/PartitionJob.h>
#include "PartitionJob.h"
class Device;
class Partition;

View File

@ -18,22 +18,25 @@
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jobs/FillGlobalStorageJob.h"
#include "FillGlobalStorageJob.h"
#include "core/KPMHelpers.h"
#include "core/PartitionInfo.h"
#include "core/PartitionIterator.h"
#include "Branding.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "partition/PartitionIterator.h"
#include "utils/Logger.h"
#include "Branding.h"
// KPMcore
#include <core/device.h>
#include <core/partition.h>
#include <fs/filesystem.h>
#include <fs/luks.h>
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/fs/filesystem.h>
#include <kpmcore/fs/luks.h>
// Qt
#include <QDebug>
@ -43,6 +46,7 @@
using KPMHelpers::untranslatedFS;
using KPMHelpers::userVisibleFS;
using CalamaresUtils::Partition::PartitionIterator;
typedef QHash< QString, QString > UuidForPartitionHash;

View File

@ -20,7 +20,7 @@
#ifndef FILLGLOBALSTORAGEJOB_H
#define FILLGLOBALSTORAGEJOB_H
#include <Job.h>
#include "Job.h"
// Qt
#include <QList>

View File

@ -24,12 +24,12 @@
#include "utils/Logger.h"
// KPMcore
#include <core/device.h>
#include <core/partition.h>
#include <core/partitiontable.h>
#include <fs/filesystem.h>
#include <ops/createfilesystemoperation.h>
#include <util/report.h>
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/core/partitiontable.h>
#include <kpmcore/fs/filesystem.h>
#include <kpmcore/ops/createfilesystemoperation.h>
#include <kpmcore/util/report.h>
using KPMHelpers::untranslatedFS;
using KPMHelpers::userVisibleFS;

View File

@ -20,7 +20,7 @@
#ifndef FORMATPARTITIONJOB_H
#define FORMATPARTITIONJOB_H
#include <jobs/PartitionJob.h>
#include "PartitionJob.h"
class Device;
class Partition;

View File

@ -16,7 +16,7 @@
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include <jobs/PartitionJob.h>
#include "PartitionJob.h"
PartitionJob::PartitionJob( Partition* partition )
: m_partition( partition )

View File

@ -1,6 +1,7 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -19,12 +20,13 @@
#ifndef PARTITIONJOB_H
#define PARTITIONJOB_H
#include <Job.h>
#include "Job.h"
#include "partition/KPMManager.h"
class Partition;
/**
* Base class for jobs which affect a partition.
* Base class for jobs which affect a partition and which use KPMCore.
*/
class PartitionJob : public Calamares::Job
{
@ -46,6 +48,7 @@ public slots:
void iprogress( int percent );
protected:
CalamaresUtils::Partition::KPMManager m_kpmcore;
Partition* m_partition;
};

View File

@ -19,7 +19,8 @@
#ifndef REMOVEVOLUMEGROUPJOB_H
#define REMOVEVOLUMEGROUPJOB_H
#include <Job.h>
#include "Job.h"
#include "partition/KPMManager.h"
class LvmDevice;
@ -35,6 +36,7 @@ public:
Calamares::JobResult exec() override;
private:
CalamaresUtils::Partition::KPMManager m_kpmcore;
LvmDevice* m_device;
};

View File

@ -23,9 +23,9 @@
#include "utils/Units.h"
// KPMcore
#include <core/device.h>
#include <ops/resizeoperation.h>
#include <util/report.h>
#include <kpmcore/core/device.h>
#include <kpmcore/ops/resizeoperation.h>
#include <kpmcore/util/report.h>
using CalamaresUtils::BytesToMiB;

View File

@ -20,7 +20,7 @@
#ifndef RESIZEPARTITIONJOB_H
#define RESIZEPARTITIONJOB_H
#include <jobs/PartitionJob.h>
#include "PartitionJob.h"
class Device;
class Partition;

View File

@ -19,7 +19,8 @@
#ifndef RESIZEVOLUMEGROUPJOB_H
#define RESIZEVOLUMEGROUPJOB_H
#include <Job.h>
#include "Job.h"
#include "partition/KPMManager.h"
#include <QVector>
@ -42,6 +43,7 @@ private:
QString targetPartitions() const;
private:
CalamaresUtils::Partition::KPMManager m_kpmcore;
LvmDevice* m_device;
QVector< const Partition* > m_partitionList;
};

View File

@ -27,11 +27,11 @@
#include "utils/Units.h"
// KPMcore
#include <core/device.h>
#include <core/partition.h>
#include <fs/filesystem.h>
#include <ops/setpartflagsoperation.h>
#include <util/report.h>
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/fs/filesystem.h>
#include <kpmcore/ops/setpartflagsoperation.h>
#include <kpmcore/util/report.h>
using CalamaresUtils::BytesToMiB;
using KPMHelpers::untranslatedFS;

View File

@ -22,7 +22,7 @@
#ifndef SETPARTITIONFLAGSJOB_H
#define SETPARTITIONFLAGSJOB_H
#include <jobs/PartitionJob.h>
#include "PartitionJob.h"
#include <kpmcore/core/partitiontable.h>

View File

@ -1,18 +1,9 @@
find_package( Qt5 COMPONENTS Gui REQUIRED )
# Roundabout way of saying ..
set( PartitionModule_SOURCE_DIR .. )
set( partitionjobtests_SRCS
${PartitionModule_SOURCE_DIR}/core/KPMHelpers.cpp
${PartitionModule_SOURCE_DIR}/core/PartitionInfo.cpp
${PartitionModule_SOURCE_DIR}/core/PartitionIterator.cpp
${PartitionModule_SOURCE_DIR}/jobs/CreatePartitionJob.cpp
${PartitionModule_SOURCE_DIR}/jobs/CreatePartitionTableJob.cpp
${PartitionModule_SOURCE_DIR}/jobs/DeletePartitionJob.cpp
${PartitionModule_SOURCE_DIR}/jobs/PartitionJob.cpp
${PartitionModule_SOURCE_DIR}/jobs/ResizePartitionJob.cpp
PartitionJobTests.cpp
)
# This is set by parent CMakeLists.txt
# set( _partition_defs )
include_directories(
${Qt5Gui_INCLUDE_DIRS}
@ -22,7 +13,16 @@ include_directories(
)
if( ECM_FOUND AND BUILD_TESTING )
ecm_add_test( ${partitionjobtests_SRCS}
ecm_add_test(
${PartitionModule_SOURCE_DIR}/core/KPMHelpers.cpp
${PartitionModule_SOURCE_DIR}/core/PartitionInfo.cpp
${PartitionModule_SOURCE_DIR}/jobs/CreatePartitionJob.cpp
${PartitionModule_SOURCE_DIR}/jobs/CreatePartitionTableJob.cpp
${PartitionModule_SOURCE_DIR}/jobs/DeletePartitionJob.cpp
${PartitionModule_SOURCE_DIR}/jobs/PartitionJob.cpp
${PartitionModule_SOURCE_DIR}/jobs/ResizePartitionJob.cpp
PartitionJobTests.cpp
TEST_NAME partitionjobtests
LINK_LIBRARIES
${CALAMARES_LIBRARIES}
@ -33,4 +33,20 @@ if( ECM_FOUND AND BUILD_TESTING )
set_target_properties( partitionjobtests PROPERTIES AUTOMOC TRUE )
target_compile_definitions( partitionjobtests PRIVATE ${_partition_defs} )
ecm_add_test(
${PartitionModule_SOURCE_DIR}/jobs/ClearMountsJob.cpp
ClearMountsJobTests.cpp
TEST_NAME clearmountsjobtests
LINK_LIBRARIES
${CALAMARES_LIBRARIES}
kpmcore
Qt5::Core
Qt5::Test
)
set_target_properties( clearmountsjobtests PROPERTIES AUTOMOC TRUE )
target_compile_definitions( clearmountsjobtests PRIVATE ${_partition_defs} )
endif()

View File

@ -0,0 +1,66 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ClearMountsJobTests.h"
#include "utils/Logger.h"
#include <QtTest/QtTest>
QTEST_GUILESS_MAIN( ClearMountsJobTests )
/* Not exactly public API */
QStringList
getPartitionsForDevice( const QString& deviceName );
QStringList
getPartitionsForDevice_other(const QString& deviceName)
{
QProcess process;
process.setProgram( "sh" );
process.setArguments( {
"-c",
QString( "echo $(awk '{print $4}' /proc/partitions | sed -e '/name/d' -e '/^$/d' -e '/[1-9]/!d' | grep %1)" )
.arg( deviceName )
} );
process.start();
process.waitForFinished();
const QString partitions = process.readAllStandardOutput();
const QStringList partitionsList = partitions.simplified().split( ' ' );
return partitionsList;
}
ClearMountsJobTests::ClearMountsJobTests()
{
Logger::setupLogLevel(6);
}
void ClearMountsJobTests::testFindPartitions()
{
QStringList partitions = getPartitionsForDevice( "sda" );
QStringList other_part = getPartitionsForDevice_other( "sda" );
cDebug() << "Initial implementation:" << Logger::DebugList( partitions );
cDebug() << "Other implementation:" << Logger::DebugList( other_part );
QCOMPARE( partitions, other_part );
}

View File

@ -0,0 +1,34 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLEARMOUNTSJOBTESTS_H
#define CLEARMOUNTSJOBTESTS_H
#include <QObject>
class ClearMountsJobTests : public QObject
{
Q_OBJECT
public:
ClearMountsJobTests();
private Q_SLOTS:
void testFindPartitions();
};
#endif

View File

@ -19,16 +19,18 @@
#include <PartitionJobTests.h>
#include "partition/KPMManager.h"
#include "partition/PartitionQuery.h"
#include "utils/Logger.h"
#include "utils/Units.h"
#include <core/KPMHelpers.h>
#include <jobs/CreatePartitionJob.h>
#include <jobs/CreatePartitionTableJob.h>
#include <jobs/ResizePartitionJob.h>
#include <core/KPMHelpers.h>
// CalaPM
#include <backend/corebackend.h>
#include <backend/corebackendmanager.h>
#include <fs/filesystemfactory.h>
// Qt
@ -40,6 +42,7 @@ QTEST_GUILESS_MAIN( PartitionJobTests )
using namespace Calamares;
using CalamaresUtils::operator""_MiB;
using CalamaresUtils::Partition::isPartitionFreeSpace;
class PartitionMounter
{
@ -56,15 +59,14 @@ public:
~PartitionMounter()
{
if ( !m_mounted )
{
return;
}
int ret = QProcess::execute( "umount", QStringList() << m_mountPointDir.path() );
QCOMPARE( ret, 0 );
}
QString mountPoint() const
{
return m_mounted ? m_mountPointDir.path() : QString();
}
QString mountPoint() const { return m_mounted ? m_mountPointDir.path() : QString(); }
private:
QString m_devicePath;
@ -77,9 +79,9 @@ static QByteArray
generateTestData( qint64 size )
{
QByteArray ba;
ba.resize( static_cast<int>( size ) );
ba.resize( static_cast< int >( size ) );
// Fill the array explicitly to keep Valgrind happy
for ( auto it = ba.data() ; it < ba.data() + size ; ++it )
for ( auto it = ba.data(); it < ba.data() + size; ++it )
{
*it = char( rand() & 0xff );
}
@ -102,9 +104,9 @@ writeFile( const QString& path, const QByteArray data )
if ( count < 0 )
{
QString msg = QString( "Writing file failed. Only %1 bytes written out of %2. Error: '%3'." )
.arg( ptr - data.constData() )
.arg( data.size() )
.arg( file.errorString() );
.arg( ptr - data.constData() )
.arg( data.size() )
.arg( file.errorString() );
QFAIL( qPrintable( msg ) );
}
ptr += count;
@ -114,9 +116,11 @@ writeFile( const QString& path, const QByteArray data )
static Partition*
firstFreePartition( PartitionNode* parent )
{
for( auto child : parent->children() )
if ( KPMHelpers::isPartitionFreeSpace( child ) )
for ( auto child : parent->children() )
if ( isPartitionFreeSpace( child ) )
{
return child;
}
return nullptr;
}
@ -143,7 +147,9 @@ QueueRunner::run()
m_queue->start();
QEventLoop loop;
while ( !m_finished )
{
loop.processEvents();
}
return m_success;
}
@ -161,10 +167,13 @@ QueueRunner::onFailed( const QString& message, const QString& details )
QFAIL( qPrintable( msg ) );
}
CalamaresUtils::Partition::KPMManager* kpmcore = nullptr;
//- PartitionJobTests ------------------------------------------------------------------
PartitionJobTests::PartitionJobTests()
: m_runner( &m_queue )
{}
{
}
void
PartitionJobTests::initTestCase()
@ -173,21 +182,27 @@ PartitionJobTests::initTestCase()
if ( devicePath.isEmpty() )
{
// The 0 is to keep the macro parameters happy
QSKIP( "Skipping test, CALAMARES_TEST_DISK is not set. It should point to a disk which can be safely formatted", 0 );
QSKIP( "Skipping test, CALAMARES_TEST_DISK is not set. It should point to a disk which can be safely formatted",
0 );
}
QVERIFY( KPMHelpers::initKPMcore() );
kpmcore = new CalamaresUtils::Partition::KPMManager();
FileSystemFactory::init();
refreshDevice();
}
void
PartitionJobTests::cleanupTestCase()
{
delete kpmcore;
}
void
PartitionJobTests::refreshDevice()
{
QString devicePath = qgetenv( "CALAMARES_TEST_DISK" );
CoreBackend* backend = CoreBackendManager::self()->backend();
m_device.reset( backend->scanDevice( devicePath ) );
m_device.reset( kpmcore->backend()->scanDevice( devicePath ) );
QVERIFY( !m_device.isNull() );
}
@ -206,7 +221,7 @@ PartitionJobTests::testPartitionTable()
}
void
PartitionJobTests::queuePartitionTableCreation( PartitionTable::TableType type)
PartitionJobTests::queuePartitionTableCreation( PartitionTable::TableType type )
{
auto job = new CreatePartitionTableJob( m_device.data(), type );
job->updatePreview();
@ -214,7 +229,10 @@ PartitionJobTests::queuePartitionTableCreation( PartitionTable::TableType type)
}
CreatePartitionJob*
PartitionJobTests::newCreatePartitionJob( Partition* freeSpacePartition, PartitionRole role, FileSystem::Type type, qint64 size )
PartitionJobTests::newCreatePartitionJob( Partition* freeSpacePartition,
PartitionRole role,
FileSystem::Type type,
qint64 size )
{
Q_ASSERT( freeSpacePartition );
@ -222,25 +240,27 @@ PartitionJobTests::newCreatePartitionJob( Partition* freeSpacePartition, Partiti
qint64 lastSector;
if ( size > 0 )
{
lastSector = firstSector + size / m_device->logicalSize();
}
else
{
lastSector = freeSpacePartition->lastSector();
FileSystem* fs = FileSystemFactory::create( type, firstSector, lastSector
,m_device->logicalSize()
);
}
FileSystem* fs = FileSystemFactory::create( type, firstSector, lastSector, m_device->logicalSize() );
Partition* partition = new Partition(
freeSpacePartition->parent(),
*m_device,
role,
fs, firstSector, lastSector,
QString() /* path */,
KPM_PARTITION_FLAG(None) /* availableFlags */,
QString() /* mountPoint */,
false /* mounted */,
KPM_PARTITION_FLAG(None) /* activeFlags */,
KPM_PARTITION_STATE(New)
);
Partition* partition = new Partition( freeSpacePartition->parent(),
*m_device,
role,
fs,
firstSector,
lastSector,
QString() /* path */,
KPM_PARTITION_FLAG( None ) /* availableFlags */,
QString() /* mountPoint */,
false /* mounted */,
KPM_PARTITION_FLAG( None ) /* activeFlags */,
KPM_PARTITION_STATE( New ) );
return new CreatePartitionJob( m_device.data(), partition );
}
@ -253,7 +273,7 @@ PartitionJobTests::testCreatePartition()
freePartition = firstFreePartition( m_device->partitionTable() );
QVERIFY( freePartition );
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Primary ), FileSystem::Ext4, 1_MiB);
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Primary ), FileSystem::Ext4, 1_MiB );
Partition* partition1 = job->partition();
QVERIFY( partition1 );
job->updatePreview();
@ -261,7 +281,7 @@ PartitionJobTests::testCreatePartition()
freePartition = firstFreePartition( m_device->partitionTable() );
QVERIFY( freePartition );
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Primary ), FileSystem::LinuxSwap, 1_MiB);
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Primary ), FileSystem::LinuxSwap, 1_MiB );
Partition* partition2 = job->partition();
QVERIFY( partition2 );
job->updatePreview();
@ -269,7 +289,7 @@ PartitionJobTests::testCreatePartition()
freePartition = firstFreePartition( m_device->partitionTable() );
QVERIFY( freePartition );
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Primary ), FileSystem::Fat32, 1_MiB);
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Primary ), FileSystem::Fat32, 1_MiB );
Partition* partition3 = job->partition();
QVERIFY( partition3 );
job->updatePreview();
@ -294,7 +314,7 @@ PartitionJobTests::testCreatePartitionExtended()
freePartition = firstFreePartition( m_device->partitionTable() );
QVERIFY( freePartition );
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Primary ), FileSystem::Ext4, 10_MiB);
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Primary ), FileSystem::Ext4, 10_MiB );
Partition* partition1 = job->partition();
QVERIFY( partition1 );
job->updatePreview();
@ -302,14 +322,15 @@ PartitionJobTests::testCreatePartitionExtended()
freePartition = firstFreePartition( m_device->partitionTable() );
QVERIFY( freePartition );
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Extended ), FileSystem::Extended, 10_MiB);
job = newCreatePartitionJob(
freePartition, PartitionRole( PartitionRole::Extended ), FileSystem::Extended, 10_MiB );
job->updatePreview();
m_queue.enqueue( job_ptr( job ) );
Partition* extendedPartition = job->partition();
freePartition = firstFreePartition( extendedPartition );
QVERIFY( freePartition );
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Logical ), FileSystem::Ext4, 0);
job = newCreatePartitionJob( freePartition, PartitionRole( PartitionRole::Logical ), FileSystem::Ext4, 0 );
Partition* partition2 = job->partition();
QVERIFY( partition2 );
job->updatePreview();
@ -333,10 +354,10 @@ PartitionJobTests::testResizePartition_data()
QTest::addColumn< unsigned int >( "newStartMiB" );
QTest::addColumn< unsigned int >( "newSizeMiB" );
QTest::newRow("grow") << 10 << 50 << 10 << 70;
QTest::newRow("shrink") << 10 << 70 << 10 << 50;
QTest::newRow("moveLeft") << 10 << 50 << 8 << 50;
QTest::newRow("moveRight") << 10 << 50 << 12 << 50;
QTest::newRow( "grow" ) << 10 << 50 << 10 << 70;
QTest::newRow( "shrink" ) << 10 << 70 << 10 << 50;
QTest::newRow( "moveLeft" ) << 10 << 50 << 8 << 50;
QTest::newRow( "moveRight" ) << 10 << 50 << 12 << 50;
}
void
@ -350,9 +371,9 @@ PartitionJobTests::testResizePartition()
const qint64 sectorsPerMiB = 1_MiB / m_device->logicalSize();
qint64 oldFirst = sectorsPerMiB * oldStartMiB;
qint64 oldLast = oldFirst + sectorsPerMiB * oldSizeMiB - 1;
qint64 oldLast = oldFirst + sectorsPerMiB * oldSizeMiB - 1;
qint64 newFirst = sectorsPerMiB * newStartMiB;
qint64 newLast = newFirst + sectorsPerMiB * newSizeMiB - 1;
qint64 newLast = newFirst + sectorsPerMiB * newSizeMiB - 1;
// Make the test data file smaller than the full size of the partition to
// accomodate for the file system overhead
@ -366,15 +387,13 @@ PartitionJobTests::testResizePartition()
Partition* freePartition = firstFreePartition( m_device->partitionTable() );
QVERIFY( freePartition );
Partition* partition = KPMHelpers::createNewPartition(
freePartition->parent(),
*m_device,
PartitionRole( PartitionRole::Primary ),
FileSystem::Ext4,
oldFirst,
oldLast,
KPM_PARTITION_FLAG(None)
);
Partition* partition = KPMHelpers::createNewPartition( freePartition->parent(),
*m_device,
PartitionRole( PartitionRole::Primary ),
FileSystem::Ext4,
oldFirst,
oldLast,
KPM_PARTITION_FLAG( None ) );
CreatePartitionJob* job = new CreatePartitionJob( m_device.data(), partition );
job->updatePreview();
m_queue.enqueue( job_ptr( job ) );
@ -386,7 +405,8 @@ PartitionJobTests::testResizePartition()
// Write a test file in the partition
refreshDevice();
QVERIFY( m_device->partitionTable() );
Partition* partition = m_device->partitionTable()->findPartitionBySector( oldFirst, PartitionRole( PartitionRole::Primary ) );
Partition* partition
= m_device->partitionTable()->findPartitionBySector( oldFirst, PartitionRole( PartitionRole::Primary ) );
QVERIFY( partition );
QCOMPARE( partition->firstSector(), oldFirst );
QCOMPARE( partition->lastSector(), oldLast );
@ -411,7 +431,8 @@ PartitionJobTests::testResizePartition()
{
refreshDevice();
QVERIFY( m_device->partitionTable() );
Partition* partition = m_device->partitionTable()->findPartitionBySector( newFirst, PartitionRole( PartitionRole::Primary ) );
Partition* partition
= m_device->partitionTable()->findPartitionBySector( newFirst, PartitionRole( PartitionRole::Primary ) );
QVERIFY( partition );
QCOMPARE( partition->firstSector(), newFirst );
QCOMPARE( partition->lastSector(), newLast );

View File

@ -59,6 +59,7 @@ public:
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void testPartitionTable();
void testCreatePartition();
void testCreatePartitionExtended();
@ -71,7 +72,8 @@ private:
QueueRunner m_runner;
void queuePartitionTableCreation( PartitionTable::TableType type );
CreatePartitionJob* newCreatePartitionJob( Partition* freeSpacePartition, PartitionRole, FileSystem::Type type, qint64 size );
CreatePartitionJob*
newCreatePartitionJob( Partition* freeSpacePartition, PartitionRole, FileSystem::Type type, qint64 size );
void refreshDevice();
};

View File

@ -274,34 +274,29 @@ class UnpackOperation:
def mount_image(self, entry, imgmountdir):
"""
Mount given image as loop device.
Mount given @p entry as loop device on @p imgmountdir.
A *file* entry (e.g. one with *sourcefs* set to *file*)
is not mounted and just ignored.
:param entry:
:param imgmountdir:
:param entry: the entry to mount (source is the important property)
:param imgmountdir: where to mount it
:returns: None, but throws if the mount failed
"""
if entry.is_file():
return
if os.path.isdir(entry.source):
subprocess.check_call(["mount",
"--bind", entry.source,
imgmountdir])
r = libcalamares.utils.mount(entry.source, imgmountdir, "", "--bind")
elif os.path.isfile(entry.source):
subprocess.check_call(["mount",
entry.source,
imgmountdir,
"-t", entry.sourcefs,
"-o", "loop"
])
r = libcalamares.utils.mount(entry.source, imgmountdir, entry.sourcefs, "loop")
else: # entry.source is a device
subprocess.check_call(["mount",
entry.source,
imgmountdir,
"-t", entry.sourcefs
])
r = libcalamares.utils.mount(entry.source, imgmountdir, entry.sourcefs, "")
if r != 0:
raise subprocess.CalledProcessError(r, "mount")
def unpack_image(self, entry, imgmountdir):
"""