示例#1
0
void MountCommand::buildBackend (Cmdline const & cl)
{
	MountBackendBuilder backend;

	Key mpk (mp, KEY_CASCADING_NAME, KEY_END);

	if (!mpk.isValid ())
	{
		throw invalid_argument (mp + " is not a valid mountpoint");
	}

	backend.setMountpoint (mpk, mountConf);

	backend.setBackendConfig (cl.getPluginsConfig ("system/"));

	PluginSpec resolver (cl.resolver);
	if (cl.debug)
	{
		cout << "Trying to load the resolver plugin " << resolver.getName () << endl;
	}

	backend.addPlugin (PluginSpec (resolver));

	if (cl.interactive)
	{
		cout << endl;
		cout << "Enter a path to a file in the filesystem." << endl;
		cout << "The path must either not exist or be a file." << endl;
		cout << "For user or cascading mountpoints it must be a relative path." << endl;
		cout << "Then, the path will be resolved dynamically." << endl;
		cout << "Path: ";
		cin >> path;
	}
示例#2
0
std::vector<PluginSpec> PluginVariantDatabase::getPluginVariantsFromSysconf (PluginSpec const & whichplugin, KeySet const & sysconf,
									     KeySet const & genconfToIgnore) const
{
	std::vector<PluginSpec> result;

	KeySet ksSysconf (sysconf);

	// first find possible variants
	Key kVariantBase ("system/elektra/plugins", KEY_END);
	kVariantBase.addBaseName (whichplugin.getName ());
	kVariantBase.addBaseName ("variants");

	KeySet ksPluginVariantSysconf (ksSysconf.cut (kVariantBase));
	KeySet ksToIterate (ksPluginVariantSysconf);
	for (auto kCurrent : ksToIterate)
	{
		Key kCurrentTest (kVariantBase);
		kCurrentTest.addBaseName (kCurrent.getBaseName ());
		if (kCurrentTest == kCurrent)
		{
			PluginSpec variant (whichplugin);
			KeySet ksVariantConfToAdd;

			// new base for plugin conf
			Key kVariantPluginConf ("system/", KEY_END);

			// add system conf for plugin variant
			Key kVariantSysconf (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "config"));
			this->addKeysBelowKeyToConf (kVariantSysconf, ksPluginVariantSysconf, kVariantPluginConf, ksVariantConfToAdd);

			// check if the variant was disabled : system/elektra/plugins/simpleini/variants/space/disable
			Key kDisable = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "disable"));
			if (kDisable && kDisable.getString () == "1")
			{
				continue; // skip this variant
			}

			// check if the variant is in the genconfToIgnore list
			Key kGenconfVariant (kVariantPluginConf);
			kGenconfVariant.addBaseName (kCurrent.getBaseName ());
			Key kIgnore = genconfToIgnore.lookup (kGenconfVariant);
			if (kIgnore)
			{
				continue; // this variant was added by genconf already
			}

			if (ksVariantConfToAdd.size () == 0)
			{
				continue; // no config means no variant
			}

			variant.appendConfig (ksVariantConfToAdd);
			result.push_back (variant);
		}
	}

	return result;
}
示例#3
0
Key PluginVariantDatabase::buildVariantSysconfKey (PluginSpec const & whichplugin, std::string const & variant,
						   std::string const & attr) const
{
	Key result ("system/elektra/plugins", KEY_END);
	result.addBaseName (whichplugin.getName ());
	result.addBaseName ("variants");
	result.addBaseName (variant);
	result.addBaseName (attr);
	return result;
}
示例#4
0
PluginDatabase::func_t ModulesPluginDatabase::getSymbol (PluginSpec const & spec, std::string const & which) const
{
	try
	{
		PluginPtr plugin = impl->modules.load (spec.getName (), spec.getConfig ());
		return plugin->getSymbol (which);
	}
	catch (...)
	{
		return NULL;
	}
}
示例#5
0
PluginDatabase::Status ModulesPluginDatabase::status (PluginSpec const & spec) const
{
	PluginPtr plugin;
	try
	{
		KeySet conf = spec.getConfig ();
		conf.append (Key ("system/module", KEY_VALUE, "this plugin was loaded for the status", KEY_END));
		plugin = impl->modules.load (spec.getName (), conf);
		return real;
	}
	catch (...)
	{
		if (hasProvides (*this, spec.getName ()))
		{
			return provides;
		}
		else
		{
			return missing;
		}
	}
}
示例#6
0
std::string ModulesPluginDatabase::lookupInfo (PluginSpec const & spec, std::string const & which) const
{
	PluginPtr plugin;
	try
	{
		plugin = impl->modules.load (spec.getName (), spec.getConfig ());
	}
	catch (...)
	{
		throw;
	}

	return plugin->lookupInfo (which);
}
示例#7
0
PluginDatabase::Status MockPluginDatabase::status (PluginSpec const & spec) const
{
	auto it = data.find (spec);
	if (it != data.end ())
	{
		return real;
	}

	if (hasProvides (*this, spec.getName ()))
	{
		return provides;
	}

	return missing;
}
示例#8
0
void PluginAdder::addPlugin (PluginSpec const & spec)
{
	PluginPtr plugin = modules.load (spec);
	if (!plugin)
	{
		throw NoPlugin (spec.getName ());
	}
	std::shared_ptr<Plugin> sharedPlugin = std::move (plugin);

	std::istringstream ss (sharedPlugin->lookupInfo ("placements"));
	std::string placement;
	while (ss >> placement)
	{
		if (sharedPlugin->lookupInfo ("stacking") == "" && placement == "postgetstorage")
		{
			// reverse postgetstorage, except stacking is set
			plugins[placement].push_front (sharedPlugin);
		}
		else
		{
			plugins[placement].push_back (sharedPlugin);
		}
	}
}
示例#9
0
	bool operator() (PluginSpec const & s1, PluginSpec const & s2) const
	{
		return s1.getName () == s2.getName ();
	}
/**
 * @brief Add a plugin.
 *
 * @pre Needs to be a unique new name (use refname if you want to add the same module multiple times)
 *
 * Will automatically resolve virtual plugins to actual plugins.
 * 
 * Also calls the checkconf function if provided by the plugin. The checkconf function has the 
 * following signature: int checkconf (Key * errorKey, KeySet * config) and allows a plugin to 
 * verify its configuration at mount time.
 *
 * @see resolveNeeds()
 * @param plugin
 */
void BackendBuilder::addPlugin (PluginSpec const & plugin)
{
	typedef int (*checkConfPtr) (ckdb::Key *, ckdb::KeySet *);

	for (auto & p : toAdd)
	{
		if (p.getFullName () == plugin.getFullName ())
		{
			throw PluginAlreadyInserted (plugin.getFullName ());
		}
	}

	PluginSpec newPlugin = plugin;

	// if the plugin is actually a provider use it (otherwise we will get our name back):
	PluginSpec provides = pluginDatabase->lookupProvides (plugin.getName ());
	if (provides.getName () != newPlugin.getName ())
	{
		// keep our config and refname
		newPlugin.setName (provides.getName ());
		newPlugin.appendConfig (provides.getConfig ());
	}

	// call plugin's checkconf function (if provided)
	// this enables a plugin to verify its configuration at mount time
	checkConfPtr checkConfFunction = reinterpret_cast<checkConfPtr> (pluginDatabase->getSymbol (newPlugin, "checkconf"));
	if (checkConfFunction)
	{
		ckdb::Key * errorKey = ckdb::keyNew (0);

		// merge plugin config and backend config together
		ckdb::KeySet * pluginConfig = newPlugin.getConfig ().dup ();
		ckdb::ksAppend (pluginConfig, backendConf.getKeySet ());

		// call the plugin's checkconf function
		int checkResult = checkConfFunction (errorKey, pluginConfig);
		if (checkResult == -1)
		{
			ckdb::ksDel (pluginConfig);
			throw PluginConfigInvalid (errorKey);
		}
		else if (checkResult == 1)
		{
			// separate plugin config from the backend config
			ckdb::Key * backendParent = ckdb::keyNew ("system/", KEY_END);
			ckdb::KeySet * newBackendConfig = ckdb::ksCut (pluginConfig, backendParent);

			// take over the new configuration
			KeySet modifiedPluginConfig = KeySet (pluginConfig);
			KeySet modifiedBackendConfig = KeySet (newBackendConfig);

			newPlugin.setConfig (modifiedPluginConfig);
			setBackendConfig (modifiedBackendConfig);

			ckdb::keyDel (backendParent);
		}
		else
		{
			ckdb::ksDel (pluginConfig);
		}
		ckdb::keyDel (errorKey);
	}

	toAdd.push_back (newPlugin);
	sort ();
}
bool PluginManager::loadPlugins()
{
    QStringList pluginSpecNameFilters;
    pluginSpecNameFilters.append("*.xml");
    QString filename;
    PluginSpec *pluginSpec;
    bool disablePluginViewer = false;
    QString currentPath = QDir::current().absolutePath();


    // Load plugin specs
    for (int i = 0; i < pluginPaths.size(); i++)
    {
        qDebug() << pluginPaths.at(i);
        QDir dir(pluginPaths.at(i));
        dir.setNameFilters(pluginSpecNameFilters);
        QDirIterator dirIterator(dir, QDirIterator::Subdirectories);

        while (dirIterator.hasNext())
        {
            dirIterator.next();
            filename = dirIterator.fileInfo().absoluteFilePath();

            pluginSpec = new PluginSpec(filename);

            qDebug() << "Loaded pluginspec: " << pluginSpec->getVendor() + "." + pluginSpec->getName();
            pluginMap.insert(pluginSpec->getVendor() + "." + pluginSpec->getName(), pluginSpec);
        }
    }

    // First load the core plugin
    pluginSpec = pluginMap.value(corePluginName);

    if ( !(pluginSpec && loadPlugin(pluginSpec) ) )
    {
        qDebug() << "could not load core plugin";
        return false;
    }

    qDebug() << "read selected Plugins file: " << selectedPluginsFile;
    QFile selectedPlugins(selectedPluginsFile);
    if (!selectedPlugins.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "could not open file";
    }

    QString pluginToLoad;
    QTextStream  in(&selectedPlugins);

    pluginToLoad = in.readLine();

    while (!pluginToLoad.isNull())
    {
        qDebug() << "selectedPlugin: " << pluginToLoad;
        if (!pluginToLoad.startsWith('#'))
        {
            pluginConfig.insert(pluginToLoad, true);
            pluginSpec = pluginMap.value(pluginToLoad);
            if ( !(pluginSpec && loadPlugin(pluginSpec) ) )
            {
                qDebug() << "could not load plugin: " << pluginToLoad;
                QDir::setCurrent(currentPath);
                return false;
            }

            qDebug() << pluginSpec->getCategory();
            if (pluginSpec->getCategory() == "GUI")
            {
                disablePluginViewer = true;
            }
        }
        else
            pluginConfig.insert(pluginToLoad.remove("#"), false);

        pluginToLoad = in.readLine();
    }

    if (!disablePluginViewer)
        showPluginViewer();

    // reset the current path, because plugin loaders would change
    // it during the loading process
    QDir::setCurrent(currentPath);

    return true;
}