Merge pull request #1879 from dalto8/pkgchooser-netinstall
Allow the packagechooser module to modify the netinstall module
This commit is contained in:
commit
6a2e80a0b7
@ -15,6 +15,7 @@
|
|||||||
#include "PackageModel.h"
|
#include "PackageModel.h"
|
||||||
#include "ui_page_netinst.h"
|
#include "ui_page_netinst.h"
|
||||||
|
|
||||||
|
#include "GlobalStorage.h"
|
||||||
#include "JobQueue.h"
|
#include "JobQueue.h"
|
||||||
|
|
||||||
#include "network/Manager.h"
|
#include "network/Manager.h"
|
||||||
@ -62,4 +63,19 @@ void
|
|||||||
NetInstallPage::onActivate()
|
NetInstallPage::onActivate()
|
||||||
{
|
{
|
||||||
ui->groupswidget->setFocus();
|
ui->groupswidget->setFocus();
|
||||||
|
|
||||||
|
// The NetInstallSelect global storage value can be used to make additional items selected by default
|
||||||
|
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
|
const QStringList selectNames = gs->value( "netinstallSelect" ).toStringList();
|
||||||
|
if ( !selectNames.isEmpty() )
|
||||||
|
{
|
||||||
|
m_config->model()->setSelections( selectNames );
|
||||||
|
}
|
||||||
|
|
||||||
|
// If NetInstallAdd is found in global storage, add those items to the tree
|
||||||
|
const QVariantList groups = gs->value( "netinstallAdd" ).toList();
|
||||||
|
if ( !groups.isEmpty() )
|
||||||
|
{
|
||||||
|
m_config->model()->appendModelData( groups );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,53 @@
|
|||||||
#include "utils/Variant.h"
|
#include "utils/Variant.h"
|
||||||
#include "utils/Yaml.h"
|
#include "utils/Yaml.h"
|
||||||
|
|
||||||
|
/** @brief Appends groups to the tree
|
||||||
|
*
|
||||||
|
* Uses the data from @p groupList to add elements to the
|
||||||
|
* existing tree that m_rootItem points to. If m_rootItem
|
||||||
|
* is not valid, it does nothing
|
||||||
|
*
|
||||||
|
* Before adding anything to the model, it ensures that there
|
||||||
|
* is no existing data from the same source. If there is, that
|
||||||
|
* data is pruned first
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
setSelections2( const QStringList& selectNames, PackageTreeItem* item )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < item->childCount(); i++ )
|
||||||
|
{
|
||||||
|
auto* child = item->child( i );
|
||||||
|
setSelections2( selectNames, child );
|
||||||
|
}
|
||||||
|
if ( item->isGroup() && selectNames.contains( item->name() ) )
|
||||||
|
{
|
||||||
|
item->setSelected( Qt::CheckState::Checked );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief Collects all the "source" values from @p groupList
|
||||||
|
*
|
||||||
|
* Iterates over @p groupList and returns all nonempty "source"
|
||||||
|
* values from the maps.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static QStringList
|
||||||
|
collectSources( const QVariantList& groupList )
|
||||||
|
{
|
||||||
|
QStringList sources;
|
||||||
|
for ( const QVariant& group : groupList )
|
||||||
|
{
|
||||||
|
QVariantMap groupMap = group.toMap();
|
||||||
|
if ( !groupMap[ "source" ].toString().isEmpty() )
|
||||||
|
{
|
||||||
|
sources.append( groupMap[ "source" ].toString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
|
||||||
PackageModel::PackageModel( QObject* parent )
|
PackageModel::PackageModel( QObject* parent )
|
||||||
: QAbstractItemModel( parent )
|
: QAbstractItemModel( parent )
|
||||||
{
|
{
|
||||||
@ -170,6 +217,15 @@ PackageModel::headerData( int section, Qt::Orientation orientation, int role ) c
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PackageModel::setSelections( const QStringList& selectNames )
|
||||||
|
{
|
||||||
|
if ( m_rootItem )
|
||||||
|
{
|
||||||
|
setSelections2( selectNames, m_rootItem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PackageTreeItem::List
|
PackageTreeItem::List
|
||||||
PackageModel::getPackages() const
|
PackageModel::getPackages() const
|
||||||
{
|
{
|
||||||
@ -303,9 +359,43 @@ PackageModel::setupModelData( const QVariantList& groupList, PackageTreeItem* pa
|
|||||||
void
|
void
|
||||||
PackageModel::setupModelData( const QVariantList& l )
|
PackageModel::setupModelData( const QVariantList& l )
|
||||||
{
|
{
|
||||||
emit beginResetModel();
|
Q_EMIT beginResetModel();
|
||||||
delete m_rootItem;
|
delete m_rootItem;
|
||||||
m_rootItem = new PackageTreeItem();
|
m_rootItem = new PackageTreeItem();
|
||||||
setupModelData( l, m_rootItem );
|
setupModelData( l, m_rootItem );
|
||||||
emit endResetModel();
|
Q_EMIT endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PackageModel::appendModelData( const QVariantList& groupList )
|
||||||
|
{
|
||||||
|
if ( m_rootItem )
|
||||||
|
{
|
||||||
|
Q_EMIT beginResetModel();
|
||||||
|
|
||||||
|
const QStringList sources = collectSources( groupList );
|
||||||
|
|
||||||
|
if ( !sources.isEmpty() )
|
||||||
|
{
|
||||||
|
// Prune any existing data from the same source
|
||||||
|
QList< int > removeList;
|
||||||
|
for ( int i = 0; i < m_rootItem->childCount(); i++ )
|
||||||
|
{
|
||||||
|
PackageTreeItem* child = m_rootItem->child( i );
|
||||||
|
if ( sources.contains( child->source() ) )
|
||||||
|
{
|
||||||
|
removeList.insert( 0, i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( const int& item : qAsConst( removeList ) )
|
||||||
|
{
|
||||||
|
m_rootItem->removeChild( item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new data to the model
|
||||||
|
setupModelData( groupList, m_rootItem );
|
||||||
|
|
||||||
|
Q_EMIT endResetModel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,22 @@ public:
|
|||||||
int rowCount( const QModelIndex& parent = QModelIndex() ) const override;
|
int rowCount( const QModelIndex& parent = QModelIndex() ) const override;
|
||||||
int columnCount( const QModelIndex& parent = QModelIndex() ) const override;
|
int columnCount( const QModelIndex& parent = QModelIndex() ) const override;
|
||||||
|
|
||||||
|
/** @brief Sets the checked flag on matching groups in the tree
|
||||||
|
*
|
||||||
|
* Recursively traverses the tree pointed to by m_rootItem and
|
||||||
|
* checks if a group name matches any of the items in @p selectNames.
|
||||||
|
* If a match is found, set check the box for that group and it's children.
|
||||||
|
*
|
||||||
|
* Individual packages will not be matched.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void setSelections(const QStringList &selectNames );
|
||||||
|
|
||||||
PackageTreeItem::List getPackages() const;
|
PackageTreeItem::List getPackages() const;
|
||||||
PackageTreeItem::List getItemPackages( PackageTreeItem* item ) const;
|
PackageTreeItem::List getItemPackages( PackageTreeItem* item ) const;
|
||||||
|
|
||||||
|
void appendModelData(const QVariantList& groupList);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class ItemTests;
|
friend class ItemTests;
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ PackageTreeItem::PackageTreeItem( const QVariantMap& groupData, GroupTag&& paren
|
|||||||
, m_description( CalamaresUtils::getString( groupData, "description" ) )
|
, m_description( CalamaresUtils::getString( groupData, "description" ) )
|
||||||
, m_preScript( CalamaresUtils::getString( groupData, "pre-install" ) )
|
, m_preScript( CalamaresUtils::getString( groupData, "pre-install" ) )
|
||||||
, m_postScript( CalamaresUtils::getString( groupData, "post-install" ) )
|
, m_postScript( CalamaresUtils::getString( groupData, "post-install" ) )
|
||||||
|
, m_source( CalamaresUtils::getString( groupData, "source" ) )
|
||||||
, m_isGroup( true )
|
, m_isGroup( true )
|
||||||
, m_isCritical( parentCriticality( groupData, parent.parent ) )
|
, m_isCritical( parentCriticality( groupData, parent.parent ) )
|
||||||
, m_isHidden( CalamaresUtils::getBool( groupData, "hidden", false ) )
|
, m_isHidden( CalamaresUtils::getBool( groupData, "hidden", false ) )
|
||||||
@ -248,6 +249,19 @@ PackageTreeItem::setChildrenSelected( Qt::CheckState isSelected )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PackageTreeItem::removeChild( int row )
|
||||||
|
{
|
||||||
|
if ( row < m_childItems.count() )
|
||||||
|
{
|
||||||
|
m_childItems.removeAt( row );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cWarning() << "Attempt to remove invalid child in removeChild() at row " << row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PackageTreeItem::type() const
|
PackageTreeItem::type() const
|
||||||
{
|
{
|
||||||
|
@ -56,6 +56,7 @@ public:
|
|||||||
QString description() const { return m_description; }
|
QString description() const { return m_description; }
|
||||||
QString preScript() const { return m_preScript; }
|
QString preScript() const { return m_preScript; }
|
||||||
QString postScript() const { return m_postScript; }
|
QString postScript() const { return m_postScript; }
|
||||||
|
QString source() const { return m_source; }
|
||||||
|
|
||||||
/** @brief Is this item a group-item?
|
/** @brief Is this item a group-item?
|
||||||
*
|
*
|
||||||
@ -124,6 +125,8 @@ public:
|
|||||||
void setSelected( Qt::CheckState isSelected );
|
void setSelected( Qt::CheckState isSelected );
|
||||||
void setChildrenSelected( Qt::CheckState isSelected );
|
void setChildrenSelected( Qt::CheckState isSelected );
|
||||||
|
|
||||||
|
void removeChild( int row );
|
||||||
|
|
||||||
/** @brief Update selectedness based on the children's states
|
/** @brief Update selectedness based on the children's states
|
||||||
*
|
*
|
||||||
* This only makes sense for groups, which might have packages
|
* This only makes sense for groups, which might have packages
|
||||||
@ -157,6 +160,7 @@ private:
|
|||||||
QString m_description;
|
QString m_description;
|
||||||
QString m_preScript;
|
QString m_preScript;
|
||||||
QString m_postScript;
|
QString m_postScript;
|
||||||
|
QString m_source;
|
||||||
bool m_isGroup = false;
|
bool m_isGroup = false;
|
||||||
bool m_isCritical = false;
|
bool m_isCritical = false;
|
||||||
bool m_isHidden = false;
|
bool m_isHidden = false;
|
||||||
|
@ -27,6 +27,29 @@
|
|||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
#include "utils/Variant.h"
|
#include "utils/Variant.h"
|
||||||
|
|
||||||
|
/** @brief This removes any values from @p groups that match @p source
|
||||||
|
*
|
||||||
|
* This is used to remove duplicates from the netinstallAdd structure
|
||||||
|
* It iterates over @p groups and for each map in the list, if the
|
||||||
|
* "source" element matches @p source, it is removed from the returned
|
||||||
|
* list.
|
||||||
|
*/
|
||||||
|
static QVariantList
|
||||||
|
pruneNetinstallAdd( const QString& source, const QVariant& groups )
|
||||||
|
{
|
||||||
|
QVariantList newGroupList;
|
||||||
|
const QVariantList groupList = groups.toList();
|
||||||
|
for ( const QVariant& group : groupList )
|
||||||
|
{
|
||||||
|
QVariantMap groupMap = group.toMap();
|
||||||
|
if ( groupMap.value( "source", "" ).toString() != source )
|
||||||
|
{
|
||||||
|
newGroupList.append( groupMap );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newGroupList;
|
||||||
|
}
|
||||||
|
|
||||||
const NamedEnumTable< PackageChooserMode >&
|
const NamedEnumTable< PackageChooserMode >&
|
||||||
packageChooserModeNames()
|
packageChooserModeNames()
|
||||||
{
|
{
|
||||||
@ -55,6 +78,8 @@ PackageChooserMethodNames()
|
|||||||
{ "custom", PackageChooserMethod::Legacy },
|
{ "custom", PackageChooserMethod::Legacy },
|
||||||
{ "contextualprocess", PackageChooserMethod::Legacy },
|
{ "contextualprocess", PackageChooserMethod::Legacy },
|
||||||
{ "packages", PackageChooserMethod::Packages },
|
{ "packages", PackageChooserMethod::Packages },
|
||||||
|
{ "netinstall-add", PackageChooserMethod::NetAdd },
|
||||||
|
{ "netinstall-select", PackageChooserMethod::NetSelect },
|
||||||
};
|
};
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
@ -121,6 +146,47 @@ Config::updateGlobalStorage( const QStringList& selected ) const
|
|||||||
CalamaresUtils::Packages::setGSPackageAdditions(
|
CalamaresUtils::Packages::setGSPackageAdditions(
|
||||||
Calamares::JobQueue::instance()->globalStorage(), m_defaultId, packageNames );
|
Calamares::JobQueue::instance()->globalStorage(), m_defaultId, packageNames );
|
||||||
}
|
}
|
||||||
|
else if ( m_method == PackageChooserMethod::NetAdd )
|
||||||
|
{
|
||||||
|
QVariantList netinstallDataList = m_model->getNetinstallDataForNames( selected );
|
||||||
|
if ( netinstallDataList.isEmpty() )
|
||||||
|
{
|
||||||
|
cWarning() << "No netinstall information found for " << selected;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If an earlier packagechooser instance added this data to global storage, combine them
|
||||||
|
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
|
if ( gs->contains( "netinstallAdd" ) )
|
||||||
|
{
|
||||||
|
netinstallDataList
|
||||||
|
+= pruneNetinstallAdd( QStringLiteral( "packageChooser" ), gs->value( "netinstallAdd" ) );
|
||||||
|
}
|
||||||
|
gs->insert( "netinstallAdd", netinstallDataList );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( m_method == PackageChooserMethod::NetSelect )
|
||||||
|
{
|
||||||
|
cDebug() << m_defaultId << "groups to select in netinstall" << selected;
|
||||||
|
QStringList newSelected = selected;
|
||||||
|
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
|
|
||||||
|
// If an earlier packagechooser instance added this data to global storage, combine them
|
||||||
|
if ( gs->contains( "netinstallSelect" ) )
|
||||||
|
{
|
||||||
|
auto selectedOrig = gs->value( "netinstallSelect" );
|
||||||
|
if ( selectedOrig.canConvert( QVariant::StringList ) )
|
||||||
|
{
|
||||||
|
newSelected += selectedOrig.toStringList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cWarning() << "Invalid NetinstallSelect data in global storage. Earlier selections purged";
|
||||||
|
}
|
||||||
|
gs->remove( "netinstallSelect" );
|
||||||
|
}
|
||||||
|
gs->insert( "netinstallSelect", newSelected );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cWarning() << "Unknown packagechooser method" << smash( m_method );
|
cWarning() << "Unknown packagechooser method" << smash( m_method );
|
||||||
|
@ -33,6 +33,8 @@ enum class PackageChooserMethod
|
|||||||
{
|
{
|
||||||
Legacy, // use contextualprocess or other custom
|
Legacy, // use contextualprocess or other custom
|
||||||
Packages, // use the packages module
|
Packages, // use the packages module
|
||||||
|
NetAdd, // adds packages to the netinstall module
|
||||||
|
NetSelect, // makes selections in the netinstall module
|
||||||
};
|
};
|
||||||
|
|
||||||
const NamedEnumTable< PackageChooserMethod >& PackageChooserMethodNames();
|
const NamedEnumTable< PackageChooserMethod >& PackageChooserMethodNames();
|
||||||
|
@ -15,6 +15,16 @@
|
|||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
/** @brief A wrapper for CalamaresUtils::getSubMap that excludes the success param
|
||||||
|
*/
|
||||||
|
static QVariantMap
|
||||||
|
getSubMap( const QVariantMap& map, const QString& key )
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
return CalamaresUtils::getSubMap( map, key, success );
|
||||||
|
}
|
||||||
|
|
||||||
static QPixmap
|
static QPixmap
|
||||||
loadScreenshot( const QString& path )
|
loadScreenshot( const QString& path )
|
||||||
{
|
{
|
||||||
@ -51,12 +61,13 @@ PackageItem::PackageItem( const QString& a_id,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageItem::PackageItem::PackageItem( const QVariantMap& item_map )
|
PackageItem::PackageItem( const QVariantMap& item_map )
|
||||||
: id( CalamaresUtils::getString( item_map, "id" ) )
|
: id( CalamaresUtils::getString( item_map, "id" ) )
|
||||||
, name( CalamaresUtils::Locale::TranslatedString( item_map, "name" ) )
|
, name( CalamaresUtils::Locale::TranslatedString( item_map, "name" ) )
|
||||||
, description( CalamaresUtils::Locale::TranslatedString( item_map, "description" ) )
|
, description( CalamaresUtils::Locale::TranslatedString( item_map, "description" ) )
|
||||||
, screenshot( loadScreenshot( CalamaresUtils::getString( item_map, "screenshot" ) ) )
|
, screenshot( loadScreenshot( CalamaresUtils::getString( item_map, "screenshot" ) ) )
|
||||||
, packageNames( CalamaresUtils::getStringList( item_map, "packages" ) )
|
, packageNames( CalamaresUtils::getStringList( item_map, "packages" ) )
|
||||||
|
, netinstallData( getSubMap( item_map, "netinstall" ) )
|
||||||
{
|
{
|
||||||
if ( name.isEmpty() && id.isEmpty() )
|
if ( name.isEmpty() && id.isEmpty() )
|
||||||
{
|
{
|
||||||
@ -125,6 +136,25 @@ PackageListModel::getInstallPackagesForNames( const QStringList& ids ) const
|
|||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantList
|
||||||
|
PackageListModel::getNetinstallDataForNames( const QStringList& ids ) const
|
||||||
|
{
|
||||||
|
QVariantList l;
|
||||||
|
for ( auto& p : m_packages )
|
||||||
|
{
|
||||||
|
if ( ids.contains( p.id ) )
|
||||||
|
{
|
||||||
|
if ( !p.netinstallData.isEmpty() )
|
||||||
|
{
|
||||||
|
QVariantMap newData = p.netinstallData;
|
||||||
|
newData[ "source" ] = QStringLiteral( "packageChooser" );
|
||||||
|
l.append( newData );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PackageListModel::rowCount( const QModelIndex& index ) const
|
PackageListModel::rowCount( const QModelIndex& index ) const
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@ struct PackageItem
|
|||||||
CalamaresUtils::Locale::TranslatedString description;
|
CalamaresUtils::Locale::TranslatedString description;
|
||||||
QPixmap screenshot;
|
QPixmap screenshot;
|
||||||
QStringList packageNames;
|
QStringList packageNames;
|
||||||
|
QVariantMap netinstallData;
|
||||||
|
|
||||||
/// @brief Create blank PackageItem
|
/// @brief Create blank PackageItem
|
||||||
PackageItem();
|
PackageItem();
|
||||||
@ -111,6 +112,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
QStringList getInstallPackagesForNames( const QStringList& ids ) const;
|
QStringList getInstallPackagesForNames( const QStringList& ids ) const;
|
||||||
|
|
||||||
|
/** @brief Does a name lookup (based on id) and returns the netinstall data
|
||||||
|
*
|
||||||
|
* If there is a package with an id in @p ids, returns their netinstall data
|
||||||
|
*
|
||||||
|
* returns a list of netinstall data or an emply list if none is found
|
||||||
|
*/
|
||||||
|
QVariantList getNetinstallDataForNames( const QStringList& ids ) const;
|
||||||
|
|
||||||
enum Roles : int
|
enum Roles : int
|
||||||
{
|
{
|
||||||
NameRole = Qt::DisplayRole,
|
NameRole = Qt::DisplayRole,
|
||||||
|
@ -33,6 +33,15 @@ mode: required
|
|||||||
# in the `exec` section. These package settings will then be handed
|
# in the `exec` section. These package settings will then be handed
|
||||||
# off to whatever package manager is configured there.
|
# off to whatever package manager is configured there.
|
||||||
#
|
#
|
||||||
|
# - "netinstall-select"
|
||||||
|
# When this is set, the id(s) selected are passed to the netinstall module.
|
||||||
|
# Any id that matches a group name in that module is set to checked
|
||||||
|
#
|
||||||
|
# - "netinstall-add"
|
||||||
|
# With this method, the packagechooser module is used to add groups to the
|
||||||
|
# netinstall module. For this to hav=e any effect. You must set netinstall,
|
||||||
|
# which is described below.
|
||||||
|
#
|
||||||
# There is no need to put this module in the `exec` section. There
|
# There is no need to put this module in the `exec` section. There
|
||||||
# are no jobs that this module provides. You should put **other**
|
# are no jobs that this module provides. You should put **other**
|
||||||
# modules, either *contextualprocess* or *packages* or some custom
|
# modules, either *contextualprocess* or *packages* or some custom
|
||||||
@ -101,13 +110,19 @@ labels:
|
|||||||
# an additional attempt is made to load the image from the **branding**
|
# an additional attempt is made to load the image from the **branding**
|
||||||
# directory.
|
# directory.
|
||||||
#
|
#
|
||||||
# The following field is **optional** for an item:
|
# The following fields are **optional** for an item:
|
||||||
#
|
#
|
||||||
# - *packages* :
|
# - *packages* :
|
||||||
# List of package names for the product. If using the *method*
|
# List of package names for the product. If using the *method*
|
||||||
# "packages", consider this item mandatory (because otherwise
|
# "packages", consider this item mandatory (because otherwise
|
||||||
# selecting the item would install no packages).
|
# selecting the item would install no packages).
|
||||||
#
|
#
|
||||||
|
# - *netinstall* :
|
||||||
|
# The data in this field should follow the format of a group
|
||||||
|
# from the netinstall module documented in
|
||||||
|
# src/modules/netinstall/netinstall.conf. This is only used
|
||||||
|
# when method is set to "netinstall-add"
|
||||||
|
#
|
||||||
# # AppData Items #
|
# # AppData Items #
|
||||||
#
|
#
|
||||||
# For data provided by AppData XML: the item has an *appdata*
|
# For data provided by AppData XML: the item has an *appdata*
|
||||||
|
Loading…
Reference in New Issue
Block a user