diff --git a/src/modules/luksopenswaphookcfg/CMakeLists.txt b/src/modules/luksopenswaphookcfg/CMakeLists.txt new file mode 100644 index 000000000..6d80df815 --- /dev/null +++ b/src/modules/luksopenswaphookcfg/CMakeLists.txt @@ -0,0 +1,22 @@ +# === This file is part of Calamares - === +# +# SPDX-FileCopyrightText: 2021 Adriaan de Groot +# SPDX-License-Identifier: BSD-2-Clause +# + +# Because LUKS Open Swap Hook (Job) is such a mouthful, we'll +# use LOSH all over the place as a shorthand. +calamares_add_plugin( luksopenswaphook + TYPE job + EXPORT_MACRO PLUGINDLLEXPORT_PRO + SOURCES + LOSHJob.cpp + SHARED_LIB +) + +calamares_add_test( + luksopenswaphooktest + SOURCES + LOSHJob.cpp + Tests.cpp +) diff --git a/src/modules/luksopenswaphookcfg/LOSHInfo.h b/src/modules/luksopenswaphookcfg/LOSHInfo.h new file mode 100644 index 000000000..1a87f4e61 --- /dev/null +++ b/src/modules/luksopenswaphookcfg/LOSHInfo.h @@ -0,0 +1,66 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#ifndef LUKSOPENSWAPHOOKCFG_LOSHINFO_H +#define LUKSOPENSWAPHOOKCFG_LOSHINFO_H + +#include + +/** @brief Information needed to create a suitable config file + * + * The LUKS swap configuration has a handful of keys that need to + * be written to the config file. This struct holds those keys + * and can find the key values from Global Storage (where the + * *partition* module sets them). + */ +struct LOSHInfo +{ + // Member names copied from Python code + QString swap_outer_uuid; + QString swap_mapper_name; + QString mountable_keyfile_device; + QString swap_device_path; + QString keyfile_device_mount_options; + + bool isValid() const { return !swap_device_path.isEmpty(); } + + /** @brief Helper method for doing key-value replacements + * + * Given a named @p key (e.g. "duck", or "swap_device"), returns the + * value set for that key. Invalid keys (e.g. "duck") return an empty string. + */ + QString replacementFor( const QString& key ) const + { + if ( key == QStringLiteral( "swap_device" ) ) + { + return swap_device_path; + } + if ( key == QStringLiteral( "crypt_swap_name" ) ) + { + return swap_mapper_name; + } + if ( key == QStringLiteral( "keyfile_device" ) ) + { + return mountable_keyfile_device; + } + if ( key == QStringLiteral( "keyfile_filename" ) ) + { + return QStringLiteral( "crypto_keyfile.bin" ); + } + if ( key == QStringLiteral( "keyfile_device_mount_options" ) ) + { + return keyfile_device_mount_options; + } + return QString(); + } + + /** @brief Creates a struct from information already set in GS + * + */ + static LOSHInfo fromGlobalStorage(); +}; + +#endif diff --git a/src/modules/luksopenswaphookcfg/LOSHJob.cpp b/src/modules/luksopenswaphookcfg/LOSHJob.cpp new file mode 100644 index 000000000..916ffcb8b --- /dev/null +++ b/src/modules/luksopenswaphookcfg/LOSHJob.cpp @@ -0,0 +1,180 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#include "LOSHJob.h" + +#include "LOSHInfo.h" + +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" +#include "utils/Permissions.h" +#include "utils/PluginFactory.h" +#include "utils/String.h" +#include "utils/Variant.h" + +#include +#include +#include + +LOSHJob::LOSHJob( QObject* parent ) + : Calamares::CppJob( parent ) +{ +} + +LOSHJob::~LOSHJob() {} + + +QString +LOSHJob::prettyName() const +{ + return tr( "Configuring encrypted swap." ); +} + +STATICTEST QString +get_assignment_part( const QString& line ) +{ + static QRegularExpression re( "^[# \\t]*([A-Za-z_]+)[ \\t]*=" ); + auto m = re.match( line ); + if ( m.hasMatch() ) + { + return m.captured( 1 ); + } + return QString(); +} + +/** Writes the config file at @p path + * + * NOTE: @p path is relative to the target system, not an absolute path. + */ +STATICTEST void +write_openswap_conf( const QString& path, QStringList& contents, const LOSHInfo& info ) +{ + if ( info.isValid() ) + { + for ( auto& line : contents ) + { + const QString key = get_assignment_part( line ); + QString replacement = info.replacementFor( key ); + if ( !replacement.isEmpty() ) + { + line.clear(); + line.append( QStringLiteral( "%1=%2" ).arg( key, replacement ) ); + } + } + cDebug() << "Writing" << contents.length() << "line configuration to" << path; + // \n between each two lines, and a \n at the end + CalamaresUtils::System::instance()->createTargetFile( + path, contents.join( '\n' ).append( '\n' ).toUtf8(), CalamaresUtils::System::WriteMode::Overwrite ); + } + else + { + cDebug() << "Will not write an invalid configuration to" << path; + } +} + +Calamares::JobResult +LOSHJob::exec() +{ + const auto* sys = CalamaresUtils::System::instance(); + if ( !sys ) + { + return Calamares::JobResult::internalError( + "LuksOpenSwapHook", tr( "No target system available." ), Calamares::JobResult::InvalidConfiguration ); + } + + Calamares::GlobalStorage* gs + = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + if ( !gs || gs->value( "rootMountPoint" ).toString().isEmpty() ) + { + return Calamares::JobResult::internalError( + "LuksOpenSwapHook", tr( "No rootMountPoint is set." ), Calamares::JobResult::InvalidConfiguration ); + } + if ( m_configFilePath.isEmpty() ) + { + return Calamares::JobResult::internalError( + "LuksOpenSwapHook", tr( "No configFilePath is set." ), Calamares::JobResult::InvalidConfiguration ); + } + + QStringList contents = sys->readTargetFile( m_configFilePath ); + if ( contents.isEmpty() ) + { + contents << QStringLiteral( "# swap_device=" ) << QStringLiteral( "# crypt_swap_name=" ) + << QStringLiteral( "# keyfile_device=" ) << QStringLiteral( "# keyfile_filename=" ) + << QStringLiteral( "# keyfile_device_mount_options" ); + } + + write_openswap_conf( m_configFilePath, contents, LOSHInfo::fromGlobalStorage() ); + return Calamares::JobResult::ok(); +} + +void +LOSHJob::setConfigurationMap( const QVariantMap& configurationMap ) +{ + m_configFilePath = CalamaresUtils::getString( + configurationMap, QStringLiteral( "configFilePath" ), QStringLiteral( "/etc/openswap.conf" ) ); +} + +STATICTEST void +globalStoragePartitionInfo( Calamares::GlobalStorage* gs, LOSHInfo& info ) +{ + if ( !gs ) + { + return; + } + QVariantList l = gs->value( "partitions" ).toList(); + if ( l.isEmpty() ) + { + return; + } + + for ( const auto& pv : l ) + { + const QVariantMap partition = pv.toMap(); + if ( !partition.isEmpty() ) + { + QString mountPoint = partition.value( "mountPoint" ).toString(); + QString fileSystem = partition.value( "fs" ).toString(); + QString luksMapperName = partition.value( "luksMapperName" ).toString(); + // if partition["fs"] == "linuxswap" and "luksMapperName" in partition: + if ( fileSystem == QStringLiteral( "linuxswap" ) && !luksMapperName.isEmpty() ) + { + info.swap_outer_uuid = partition.value( "luksUuid" ).toString(); + info.swap_mapper_name = luksMapperName; + } + else if ( mountPoint == QStringLiteral( "/" ) && !luksMapperName.isEmpty() ) + { + + info.mountable_keyfile_device = QStringLiteral( "/dev/mapper/" ) + luksMapperName; + } + } + } + + if ( !info.mountable_keyfile_device.isEmpty() && !info.swap_outer_uuid.isEmpty() ) + { + info.swap_device_path = QStringLiteral( "/dev/disk/by-uuid/" ) + info.swap_outer_uuid; + } + + QString btrfsRootSubvolume = gs->value( "btrfsRootSubvolume" ).toString(); + if ( !btrfsRootSubvolume.isEmpty() ) + { + CalamaresUtils::removeLeading( btrfsRootSubvolume, '/' ); + info.keyfile_device_mount_options + = QStringLiteral( "keyfile_device_mount_options=--options=subvol=" ) + btrfsRootSubvolume; + } +} + +LOSHInfo +LOSHInfo::fromGlobalStorage() +{ + LOSHInfo i {}; + globalStoragePartitionInfo( + Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr, i ); + return i; +} + +CALAMARES_PLUGIN_FACTORY_DEFINITION( LOSHJobFactory, registerPlugin< LOSHJob >(); ) diff --git a/src/modules/luksopenswaphookcfg/LOSHJob.h b/src/modules/luksopenswaphookcfg/LOSHJob.h new file mode 100644 index 000000000..4a435a935 --- /dev/null +++ b/src/modules/luksopenswaphookcfg/LOSHJob.h @@ -0,0 +1,37 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#ifndef LUKSOPENSWAPHOOKCFG_LOSHJOB_H +#define LUKSOPENSWAPHOOKCFG_LOSHJOB_H + +#include "CppJob.h" +#include "DllMacro.h" +#include "utils/PluginFactory.h" + +#include +#include + +class PLUGINDLLEXPORT LOSHJob : public Calamares::CppJob +{ + Q_OBJECT + +public: + explicit LOSHJob( QObject* parent = nullptr ); + ~LOSHJob() override; + + QString prettyName() const override; + + Calamares::JobResult exec() override; + + void setConfigurationMap( const QVariantMap& configurationMap ) override; + +private: + QString m_configFilePath; +}; + +CALAMARES_PLUGIN_FACTORY_DECLARATION( LOSHJobFactory ) + +#endif diff --git a/src/modules/luksopenswaphookcfg/Tests.cpp b/src/modules/luksopenswaphookcfg/Tests.cpp new file mode 100644 index 000000000..840bd9355 --- /dev/null +++ b/src/modules/luksopenswaphookcfg/Tests.cpp @@ -0,0 +1,253 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "LOSHInfo.h" +#include "LOSHJob.h" + +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" + +#include + +// LOSH = LUKS Open Swap Hook (Job) + +// Implementation details +extern QString get_assignment_part( const QString& line ); +extern void write_openswap_conf( const QString& path, QStringList& contents, const LOSHInfo& info ); + +class LOSHTests : public QObject +{ + Q_OBJECT +public: + LOSHTests(); + ~LOSHTests() override {} + +private Q_SLOTS: + void initTestCase(); + + void testAssignmentExtraction_data(); + void testAssignmentExtraction(); + + void testLOSHInfo(); + void testConfigWriting(); + void testJob(); +}; + +LOSHTests::LOSHTests() {} + +void +LOSHTests::initTestCase() +{ + Logger::setupLogLevel( Logger::LOGDEBUG ); + cDebug() << "LOSH test started."; +} + + +void +LOSHTests::testAssignmentExtraction_data() +{ + QTest::addColumn< QString >( "line" ); + QTest::addColumn< QString >( "match" ); + + QTest::newRow( "empty" ) << QString() << QString(); + QTest::newRow( "comment-only1" ) << QStringLiteral( "# " ) << QString(); + QTest::newRow( "comment-only2" ) << QStringLiteral( "###" ) << QString(); + QTest::newRow( "comment-only3" ) << QStringLiteral( "# # #" ) << QString(); + + QTest::newRow( "comment-text" ) << QStringLiteral( "# NOTE:" ) << QString(); + QTest::newRow( "comment-story" ) << QStringLiteral( "# This is a shell comment" ) << QString(); + // We look for assignments, but only for single-words + QTest::newRow( "comment-space-eq" ) << QStringLiteral( "# Check that a = b" ) << QString(); + + + QTest::newRow( "assignment1" ) << QStringLiteral( "a=1" ) << QStringLiteral( "a" ); + QTest::newRow( "assignment2" ) << QStringLiteral( "a = 1" ) << QStringLiteral( "a" ); + QTest::newRow( "assignment3" ) << QStringLiteral( "# a=1" ) << QStringLiteral( "a" ); + QTest::newRow( "assignment4" ) << QStringLiteral( "cows = 12" ) << QStringLiteral( "cows" ); + QTest::newRow( "assignment5" ) << QStringLiteral( "# # cows=1" ) << QStringLiteral( "cows" ); + QTest::newRow( "assignment6" ) << QStringLiteral( "# moose='cool' # not cows" ) << QStringLiteral( "moose" ); + QTest::newRow( "assignment7" ) << QStringLiteral( " moose=cows=42" ) << QStringLiteral( "moose" ); + QTest::newRow( "assignment8" ) << QStringLiteral( "#swap_device=/dev/something" ) + << QStringLiteral( "swap_device" ); + QTest::newRow( "assignment9" ) << QStringLiteral( "# swap_device=/dev/something" ) + << QStringLiteral( "swap_device" ); + QTest::newRow( "assignment10" ) << QStringLiteral( "swap_device=/dev/something" ) + << QStringLiteral( "swap_device" ); +} + +void +LOSHTests::testAssignmentExtraction() +{ + QFETCH( QString, line ); + QFETCH( QString, match ); + + QCOMPARE( get_assignment_part( line ), match ); +} + +static CalamaresUtils::System* +file_setup( const QTemporaryDir& tempRoot ) +{ + CalamaresUtils::System* ss = CalamaresUtils::System::instance(); + if ( !ss ) + { + ss = new CalamaresUtils::System( true ); + } + + Calamares::GlobalStorage* gs + = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + if ( !gs ) + { + cDebug() << "Creating new JobQueue"; + (void)new Calamares::JobQueue(); + gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + } + if ( gs ) + { + // Working with a rootMountPoint set + gs->insert( "rootMountPoint", tempRoot.path() ); + } + return ss; +} + +static void +make_valid_loshinfo( LOSHInfo& i ) +{ + i.swap_outer_uuid = QStringLiteral( "UUID-0000" ); + i.swap_mapper_name = QStringLiteral( "/dev/mapper/0000" ); + i.swap_device_path = QStringLiteral( "/dev/sda0" ); + i.mountable_keyfile_device = QStringLiteral( "/dev/ada0p0s0" ); +} + +void +LOSHTests::testLOSHInfo() +{ + LOSHInfo i {}; + QVERIFY( !i.isValid() ); + + make_valid_loshinfo( i ); + QVERIFY( i.isValid() ); + QCOMPARE( i.replacementFor( QStringLiteral( "swap_device" ) ), QStringLiteral( "/dev/sda0" ) ); + QCOMPARE( i.replacementFor( QStringLiteral( "duck" ) ), QString() ); +} + + +void +LOSHTests::testConfigWriting() +{ + QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) ); + QVERIFY( tempRoot.isValid() ); + auto* ss = file_setup( tempRoot ); + QVERIFY( ss ); + QVERIFY( Calamares::JobQueue::instance()->globalStorage() ); + QVERIFY( QFile::exists( tempRoot.path() ) ); + QVERIFY( QFileInfo( tempRoot.path() ).isDir() ); + + const QString targetFilePath = QStringLiteral( "losh.conf" ); + const QString filePath = tempRoot.filePath( targetFilePath ); + QStringList contents { QStringLiteral( "# Calamares demo" ), + QStringLiteral( "# swap_device=a thing" ), + QStringLiteral( "# duck duck swap_device=another" ) }; + + // When the information is invalid, file contents are unchanged, + // and no file is written either. + LOSHInfo i {}; + QVERIFY( !i.isValid() ); + QVERIFY( !QFile::exists( filePath ) ); + write_openswap_conf( targetFilePath, contents, i ); // Invalid i + QVERIFY( !QFile::exists( filePath ) ); + QCOMPARE( contents.length(), 3 ); + QCOMPARE( contents.at( 1 ).left( 4 ), QStringLiteral( "# s" ) ); + + // Can we write there at all? + QFile derp( filePath ); + QVERIFY( derp.open( QIODevice::WriteOnly ) ); + QVERIFY( derp.write( "xx", 2 ) ); + derp.close(); + QVERIFY( QFile::exists( filePath ) ); + QVERIFY( QFile::remove( filePath ) ); + + // Once the information is valid, though, the file is written + make_valid_loshinfo( i ); + QVERIFY( i.isValid() ); + QVERIFY( !QFile::exists( filePath ) ); + write_openswap_conf( targetFilePath, contents, i ); // Now it is valid + QVERIFY( QFile::exists( filePath ) ); + QCOMPARE( contents.length(), 3 ); + QCOMPARE( i.swap_device_path, QStringLiteral( "/dev/sda0" ) ); // expected key value + QCOMPARE( contents.at( 1 ), QStringLiteral( "swap_device=/dev/sda0" ) ); // expected line + + // readLine() returns with newlines-added + QFile f( filePath ); + QVERIFY( f.open( QIODevice::ReadOnly ) ); + QCOMPARE( f.readLine(), QStringLiteral( "# Calamares demo\n" ) ); + QCOMPARE( f.readLine(), QStringLiteral( "swap_device=/dev/sda0\n" ) ); + QCOMPARE( f.readLine(), QStringLiteral( "# duck duck swap_device=another\n" ) ); + QCOMPARE( f.readLine(), QString() ); + QVERIFY( f.atEnd() ); + + // Note how the contents is updated on every write_openswap_conf() + i.swap_device_path = QStringLiteral( "/dev/zram/0.zram" ); + write_openswap_conf( targetFilePath, contents, i ); // Still valid + QCOMPARE( contents.length(), 3 ); + QCOMPARE( i.swap_device_path, QStringLiteral( "/dev/zram/0.zram" ) ); // expected key value + QCOMPARE( contents.at( 1 ), QStringLiteral( "swap_device=/dev/zram/0.zram" ) ); // expected line +} + + +void +LOSHTests::testJob() +{ + QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) ); + QVERIFY( tempRoot.isValid() ); + auto* ss = file_setup( tempRoot ); + QVERIFY( ss ); + Calamares::GlobalStorage* gs + = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + QVERIFY( gs ); + + { + QDir d( tempRoot.path() ); + d.mkdir( "etc" ); + } + + QVERIFY( !LOSHInfo::fromGlobalStorage().isValid() ); + QVariantList outerPartition; + QVariantMap innerPartition; + innerPartition.insert( "mountPoint", "/" ); + innerPartition.insert( "fs", "ext4" ); + innerPartition.insert( "luksMapperName", "root" ); + innerPartition.insert( "luksUUID", "0000" ); + outerPartition.append( innerPartition ); + innerPartition.remove( "mountPoint" ); + innerPartition.insert( "fs", "linuxswap" ); + innerPartition.insert( "luksMapperName", "swap" ); + innerPartition.insert( "luksUuid", "0001" ); + outerPartition.append( innerPartition ); + gs->insert( "partitions", outerPartition ); + QVERIFY( LOSHInfo::fromGlobalStorage().isValid() ); + + LOSHJob j; + j.setConfigurationMap( QVariantMap() ); + auto jobresult = j.exec(); + QVERIFY( jobresult ); + + { + QFile f( tempRoot.filePath( "etc/openswap.conf" ) ); + QVERIFY( f.exists() ); + QVERIFY( f.open( QIODevice::ReadOnly ) ); + cDebug() << f.readAll(); + } +} + + +QTEST_GUILESS_MAIN( LOSHTests ) + +#include "utils/moc-warnings.h" + +#include "Tests.moc" diff --git a/src/modules/luksopenswaphookcfg/main.py b/src/modules/luksopenswaphookcfg/main.py deleted file mode 100644 index aaac8a31a..000000000 --- a/src/modules/luksopenswaphookcfg/main.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# === This file is part of Calamares - === -# -# SPDX-FileCopyrightText: 2016 Teo Mrnjavac -# SPDX-FileCopyrightText: 2017 Alf Gaida -# SPDX-FileCopyrightText: 2019 Adriaan de Groot -# SPDX-License-Identifier: GPL-3.0-or-later -# -# Calamares is Free Software: see the License-Identifier above. -# - -import libcalamares -import os.path - - -import gettext -_ = gettext.translation("calamares-python", - localedir=libcalamares.utils.gettext_path(), - languages=libcalamares.utils.gettext_languages(), - fallback=True).gettext - - -def pretty_name(): - return _("Configuring encrypted swap.") - - -def write_openswap_conf(partitions, root_mount_point, openswap_conf_path): - swap_outer_uuid = "" - swap_mapper_name = "" - mountable_keyfile_device = "" - - for partition in partitions: - if partition["fs"] == "linuxswap" and "luksMapperName" in partition: - swap_outer_uuid = partition["luksUuid"] - swap_mapper_name = partition["luksMapperName"] - - elif partition["mountPoint"] == "/" and "luksMapperName" in partition: - mountable_keyfile_device = ( - "/dev/mapper/{!s}".format(partition["luksMapperName"]) - ) - - if not mountable_keyfile_device or not swap_outer_uuid: - return None - - swap_device_path = "/dev/disk/by-uuid/{!s}".format(swap_outer_uuid) - - lines = [] - with open(os.path.join(root_mount_point, - openswap_conf_path), 'r') as openswap_file: - lines = [x.strip() for x in openswap_file.readlines()] - - for i in range(len(lines)): - if lines[i].startswith("swap_device"): - lines[i] = "swap_device={!s}".format(swap_device_path) - - elif lines[i].startswith("crypt_swap_name"): - lines[i] = "crypt_swap_name={!s}".format(swap_mapper_name) - - elif lines[i].startswith("keyfile_device"): - lines[i] = "keyfile_device={!s}".format(mountable_keyfile_device) - - elif lines[i].startswith("keyfile_filename"): - lines[i] = "keyfile_filename=crypto_keyfile.bin" - - elif lines[i].startswith("#keyfile_device_mount_options"): - if libcalamares.globalstorage.contains("btrfsRootSubvolume"): - btrfs_root_subvolume = libcalamares.globalstorage.value("btrfsRootSubvolume") - lines[i] = "keyfile_device_mount_options=--options=subvol=" + btrfs_root_subvolume.lstrip("/") - - with open(os.path.join(root_mount_point, - openswap_conf_path), 'w') as openswap_file: - openswap_file.write("\n".join(lines) + "\n") - - return None - - -def run(): - """ - This module sets up the openswap hook for a resumable encrypted swap. - :return: - """ - - root_mount_point = libcalamares.globalstorage.value("rootMountPoint") - openswap_conf_path = libcalamares.job.configuration["configFilePath"] - partitions = libcalamares.globalstorage.value("partitions") - - if not partitions: - libcalamares.utils.warning("partitions is empty, {!s}".format(partitions)) - return (_("Configuration Error"), - _("No partitions are defined for
{!s}
to use.").format("luksopenswaphookcfg")) - if not root_mount_point: - libcalamares.utils.warning("rootMountPoint is empty, {!s}".format(root_mount_point)) - return (_("Configuration Error"), - _("No root mount point is given for
{!s}
to use.").format("luksopenswaphookcfg")) - - openswap_conf_path = openswap_conf_path.lstrip('/') - - return write_openswap_conf(partitions, root_mount_point, openswap_conf_path) diff --git a/src/modules/luksopenswaphookcfg/module.desc b/src/modules/luksopenswaphookcfg/module.desc deleted file mode 100644 index 919a92792..000000000 --- a/src/modules/luksopenswaphookcfg/module.desc +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-FileCopyrightText: no -# SPDX-License-Identifier: CC0-1.0 ---- -type: "job" -name: "luksopenswaphookcfg" -interface: "python" -script: "main.py"