Calamares::JobResult
CreatePartitionTableJob::exec()
{
    Report report( 0 );
    QString message = tr( "The installer failed to create a partition table on %1." ).arg( m_device->name() );

    CoreBackend* backend = CoreBackendManager::self()->backend();
    QScopedPointer< CoreBackendDevice > backendDevice( backend->openDevice( m_device->deviceNode() ) );
    if ( !backendDevice.data() )
    {
        return Calamares::JobResult::error(
                   message,
                   tr( "Could not open device %1." ).arg( m_device->deviceNode() )
               );
    }

    QScopedPointer< PartitionTable > table( createTable() );
    cDebug() << "Creating new partition table of type" << table->typeName()
             << ", uncommitted yet:\n" << table;

    QProcess lsblk;
    lsblk.setProgram( "lsblk" );
    lsblk.setProcessChannelMode( QProcess::MergedChannels );
    lsblk.start();
    lsblk.waitForFinished();
    cDebug() << "lsblk:\n" << lsblk.readAllStandardOutput();

    QProcess mount;
    mount.setProgram( "mount" );
    mount.setProcessChannelMode( QProcess::MergedChannels );
    mount.start();
    mount.waitForFinished();
    cDebug() << "mount:\n" << mount.readAllStandardOutput();

    bool ok = backendDevice->createPartitionTable( report, *table );
    if ( !ok )
    {
        return Calamares::JobResult::error(
                    message,
                    QString( "Text: %1\nCommand: %2\nOutput: %3\nStatus: %4" )
                        .arg( report.toText() )
                        .arg( report.command() )
                        .arg( report.output() )
                        .arg( report.status() )
               );
    }

    return Calamares::JobResult::ok();
}
Calamares::JobResult
DeletePartitionJob::exec()
{
    Report report( 0 );
    QString message = tr( "The installer failed to delete partition %1." ).arg( m_partition->devicePath() );

    if ( m_device->deviceNode() != m_partition->devicePath() )
    {
        return Calamares::JobResult::error(
                   message,
                   tr( "Partition (%1) and device (%2) do not match." )
                   .arg( m_partition->devicePath() )
                   .arg( m_device->deviceNode() )
               );
    }

    CoreBackend* backend = CoreBackendManager::self()->backend();
    QScopedPointer<CoreBackendDevice> backendDevice( backend->openDevice( m_device->deviceNode() ) );
    if ( !backendDevice.data() )
    {
        return Calamares::JobResult::error(
                   message,
                   tr( "Could not open device %1." ).arg( m_device->deviceNode() )
               );
    }

    QScopedPointer<CoreBackendPartitionTable> backendPartitionTable( backendDevice->openPartitionTable() );
    if ( !backendPartitionTable.data() )
    {
        return Calamares::JobResult::error(
                   message,
                   tr( "Could not open partition table." )
               );
    }

    bool ok = backendPartitionTable->deletePartition( report, *m_partition );
    if ( !ok )
    {
        return Calamares::JobResult::error(
                   message,
                   report.toText()
               );
    }

    backendPartitionTable->commit();
    return Calamares::JobResult::ok();
}
Calamares::JobResult
CreatePartitionJob::exec()
{
    int step = 0;
    const qreal stepCount = 4;

    Report report( 0 );
    QString message = tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() );

    progress( step++ / stepCount );
    CoreBackend* backend = CoreBackendManager::self()->backend();
    QScopedPointer<CoreBackendDevice> backendDevice( backend->openDevice( m_device->deviceNode() ) );
    if ( !backendDevice.data() )
    {
        return Calamares::JobResult::error(
                   message,
                   tr( "Could not open device '%1'." ).arg( m_device->deviceNode() )
               );
    }

    progress( step++ / stepCount );
    QScopedPointer<CoreBackendPartitionTable> backendPartitionTable( backendDevice->openPartitionTable() );
    if ( !backendPartitionTable.data() )
    {
        return Calamares::JobResult::error(
                   message,
                   tr( "Could not open partition table." )
               );
    }

    progress( step++ / stepCount );
    QString partitionPath = backendPartitionTable->createPartition( report, *m_partition );
    if ( partitionPath.isEmpty() )
    {
        return Calamares::JobResult::error(
                   message,
                   report.toText()
               );
    }
    m_partition->setPartitionPath( partitionPath );
    backendPartitionTable->commit();

    progress( step++ / stepCount );
    FileSystem& fs = m_partition->fileSystem();
    if ( fs.type() == FileSystem::Unformatted || fs.type() == FileSystem::Extended )
        return Calamares::JobResult::ok();

    if ( !fs.create( report, partitionPath ) )
    {
        return Calamares::JobResult::error(
                   tr( "The installer failed to create file system on partition %1." ).arg( partitionPath ),
                   report.toText()
               );
    }

    if ( !backendPartitionTable->setPartitionSystemType( report, *m_partition ) )
    {
        return Calamares::JobResult::error(
                   tr( "The installer failed to update partition table on disk '%1'." ).arg( m_device->name() ),
                   report.toText()
               );
    }

    backendPartitionTable->commit();
    return Calamares::JobResult::ok();
}