diff --git a/doc/help/elektra-merge-strategy.md b/doc/help/elektra-merge-strategy.md index 2eb9c37c8ba..a7eff1cff3e 100644 --- a/doc/help/elektra-merge-strategy.md +++ b/doc/help/elektra-merge-strategy.md @@ -40,7 +40,9 @@ Currently the following strategies exist: * cut: Removes existing keys below the resultpath and replaces them with the merged keyset. - * import: + * unchanged: (EXPERIMENTAL, only for kdb-mount) + Do not fail if the operation does not change anything. + + * import: (DEPRECATED, avoid using it) Preserves existing keys in the resultpath if they do not exist in the merged keyset. If the key does exist in the merged keyset, it will be overwritten. - (avoid using it) diff --git a/doc/help/kdb-mount.md b/doc/help/kdb-mount.md index 3d4e8f3807c..790ea9f3b0e 100644 --- a/doc/help/kdb-mount.md +++ b/doc/help/kdb-mount.md @@ -74,6 +74,8 @@ Use `kdb file ` to determine where the file(s) are. Add a plugin configuration for all plugins. - `-W`, `--with-recommends`: Also add recommended plugins and warn if they are not available. +- `-f`, `--force`: + Unmount before mounting: Does not fail on already existing mountpoints. diff --git a/doc/news/_preparation_next_release.md b/doc/news/_preparation_next_release.md index 0fb59846457..69a9d7873ce 100644 --- a/doc/news/_preparation_next_release.md +++ b/doc/news/_preparation_next_release.md @@ -30,7 +30,7 @@ For more information, visit [https://libelektra.org](https://libelektra.org). - Fosdem Talk about Elektra - CC-licensed book about Elektra published - Maturing of plugins -- Elektra with encryption: +- Elektra with encryption - Preparation for switch to INI as default storage ### Fosdem Talk about Elektra in Main Track @@ -85,7 +85,7 @@ While `crypto` encrypts individual values within configuration files, `fcrypt` e For this release Peter Nirschl prepared a demo showing Elektra's cryptographic abilities: -![asciicast](https://asciinema.org/a/153014.png)](https://asciinema.org/a/153014) +[![asciicast](https://asciinema.org/a/153014.png)](https://asciinema.org/a/153014) Thanks to Peter Nirschl for this great work! diff --git a/src/libs/tools/src/backend.cpp b/src/libs/tools/src/backend.cpp index 924bad2fa7d..383575fb05e 100644 --- a/src/libs/tools/src/backend.cpp +++ b/src/libs/tools/src/backend.cpp @@ -111,10 +111,10 @@ void Backend::setMountpoint (Key mountpoint, KeySet mountConf) alreadyUsedMountpoints.push_back (Key ("user" + name, KEY_END).getName ()); alreadyUsedMountpoints.push_back (Key ("system" + name, KEY_END).getName ()); } - else - { - alreadyUsedMountpoints.push_back (name); - } + + // always add name itself, too + alreadyUsedMountpoints.push_back (name); + namesAsString += name; namesAsString += " "; } @@ -142,6 +142,11 @@ void Backend::setMountpoint (Key mountpoint, KeySet mountConf) // STEP 3: check for name match if (smp == "/") { + if (std::find (alreadyUsedMountpoints.begin (), alreadyUsedMountpoints.end (), "/") != alreadyUsedMountpoints.end ()) + { + throw MountpointAlreadyInUseException ( + "Root mountpoint not possible, because the root mountpoint already exists.\n"); + } Key specmp ("spec", KEY_END); if (std::find (alreadyUsedMountpoints.begin (), alreadyUsedMountpoints.end (), specmp.getName ()) != alreadyUsedMountpoints.end ()) @@ -169,6 +174,11 @@ void Backend::setMountpoint (Key mountpoint, KeySet mountConf) } else if (smp.at (0) == '/') { + if (std::find (alreadyUsedMountpoints.begin (), alreadyUsedMountpoints.end (), smp) != alreadyUsedMountpoints.end ()) + { + throw MountpointAlreadyInUseException ("Cascading mountpoint " + smp + + " not possible, because cascading mountpoint " + smp + " already exists.\n"); + } Key dkmp ("dir" + smp, KEY_END); if (std::find (alreadyUsedMountpoints.begin (), alreadyUsedMountpoints.end (), dkmp.getName ()) != alreadyUsedMountpoints.end ()) diff --git a/src/plugins/dini/dini.c b/src/plugins/dini/dini.c index 0234a98152e..ac0ea166211 100644 --- a/src/plugins/dini/dini.c +++ b/src/plugins/dini/dini.c @@ -20,6 +20,7 @@ int elektraDiniOpen (Plugin * handle, Key * errorKey ELEKTRA_UNUSED) dini->iniConfig = ksDup (elektraPluginGetConfig (handle)); dini->dump = elektraInvokeOpen ("dump", dini->dumpConfig); dini->ini = elektraInvokeOpen ("ini", dini->iniConfig); + dini->bin = elektraInvokeOpen ("binary", dini->iniConfig); dini->dumpErrors = keyNew ("", KEY_END); @@ -32,6 +33,7 @@ int elektraDiniClose (Plugin * handle, Key * errorKey ELEKTRA_UNUSED) { Dini * dini = elektraPluginGetData (handle); + elektraInvokeClose (dini->bin); elektraInvokeClose (dini->ini); elektraInvokeClose (dini->dump); @@ -73,14 +75,26 @@ int elektraDiniGet (Plugin * handle, KeySet * returned, Key * parentKey) return ELEKTRA_PLUGIN_STATUS_SUCCESS; } - return elektraInvoke2Args (dini->ini, "get", returned, parentKey); + int ret = elektraInvoke2Args (dini->ini, "get", returned, parentKey); + if (dini->bin) + { + ret |= elektraInvoke2Args (dini->bin, "get", returned, parentKey); // postgetstorage + } + return ret; } int elektraDiniSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned ELEKTRA_UNUSED, Key * parentKey ELEKTRA_UNUSED) { // set all keys Dini * dini = elektraPluginGetData (handle); - return elektraInvoke2Args (dini->ini, "set", returned, parentKey); + + int ret = 0; + if (dini->bin) + { + elektraInvoke2Args (dini->bin, "set", returned, parentKey); // presetstorage + } + ret |= elektraInvoke2Args (dini->ini, "set", returned, parentKey); + return ret; } Plugin * ELEKTRA_PLUGIN_EXPORT (dini) diff --git a/src/plugins/dini/dini.h b/src/plugins/dini/dini.h index c3a96a40dfb..8df43428676 100644 --- a/src/plugins/dini/dini.h +++ b/src/plugins/dini/dini.h @@ -26,6 +26,7 @@ typedef struct KeySet * modules; ElektraInvokeHandle * dump; ElektraInvokeHandle * ini; + ElektraInvokeHandle * bin; KeySet * dumpConfig; KeySet * iniConfig; Key * dumpErrors; diff --git a/src/tools/kdb/mount.cpp b/src/tools/kdb/mount.cpp index 08d9bc9e1a3..6118e91aa36 100644 --- a/src/tools/kdb/mount.cpp +++ b/src/tools/kdb/mount.cpp @@ -14,6 +14,8 @@ #include #include +#include + #include #include #include @@ -101,6 +103,15 @@ void MountCommand::buildBackend (Cmdline const & cl) throw invalid_argument (mp + " is not a valid mountpoint"); } + KeySet dupMountConf = mountConf.dup (); + + if (cl.force || cl.strategy != "preserve") + { + Key cutKey (Backends::mountpointsPath, KEY_END); + cutKey.addBaseName (mpk.getName ()); + mountConf.cut (cutKey); + } + backend.setMountpoint (mpk, mountConf); backend.setBackendConfig (cl.getPluginsConfig ("system/")); @@ -161,6 +172,29 @@ void MountCommand::buildBackend (Cmdline const & cl) // Call it a day outputMissingRecommends (backend.resolveNeeds (cl.withRecommends)); backend.serialize (mountConf); + + if (cl.strategy == "unchanged" && cl.debug) + { + cout << "The new configuration is:" << endl; + std::cout << mountConf; + std::cout << "------------------------" << std::endl; + cout << "The configuration originally was:" << endl; + std::cout << dupMountConf; + } + + if (!cl.force && (cl.strategy == "unchanged" && mountConf != dupMountConf)) + { + // throw error because it is not unchanged + try + { + backend.setMountpoint (mpk, dupMountConf); + } + catch (MountpointAlreadyInUseException const & e) + { + throw MountpointAlreadyInUseException ( + std::string ("Requested unchanged mountpoint but mount would lead to changes\n") + e.what ()); + } + } } void MountCommand::readPluginConfig (KeySet & pluginConfig) diff --git a/src/tools/kdb/mount.hpp b/src/tools/kdb/mount.hpp index 366d9f2284b..fe1933ef156 100644 --- a/src/tools/kdb/mount.hpp +++ b/src/tools/kdb/mount.hpp @@ -35,7 +35,7 @@ class MountCommand : public MountBaseCommand virtual std::string getShortOptions () override { - return "dqiR0123cW"; + return "dfqisR0123cW"; } virtual std::string getSynopsis () override diff --git a/src/tools/kdb/mountbase.cpp b/src/tools/kdb/mountbase.cpp index 3b4cc72486e..781b6629e9a 100644 --- a/src/tools/kdb/mountbase.cpp +++ b/src/tools/kdb/mountbase.cpp @@ -69,15 +69,7 @@ void MountBaseCommand::getMountpoint (Cmdline const & cl) { if (cur.getBaseName () == "mountpoint") { - if (cur.getString ().at (0) == '/') - { - mountpoints.push_back (Key ("user" + cur.getString (), KEY_END).getName ()); - mountpoints.push_back (Key ("system" + cur.getString (), KEY_END).getName ()); - } - else - { - mountpoints.push_back (cur.getString ()); - } + mountpoints.push_back (cur.getString ()); }; }