-
Notifications
You must be signed in to change notification settings - Fork 123
Conversation
{ | ||
int argc; | ||
|
||
LPWSTR * args = CommandLineToArgvW (GetCommandLineW (), &argc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation is a bit weird and I'm not entirely sure it will work if any non ASCII characters are passed as command-line arguments, but it is the best I could do.
The only alternative is using GetCommandLine
(will use ASCII mode when UNICODE
is not defined), but because there is no non-Unicode CommandLineToArgv
, we would have to parse the string ourselves. Because ASCII mode in Windows isn't necessarily ASCII, but rather any 8-bit character encoding, that could be even more difficult than it already is (quotes, escaping, etc.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be okay for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks nice!
src/include/kdbconfig.h.in
Outdated
@@ -200,8 +200,25 @@ | |||
#cmakedefine HAVE_HSEARCHR | |||
#endif | |||
|
|||
/* define if the gopts plugin shall use the procfs implementation */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better define this only locally for your plugin.
* | ||
*/ | ||
|
||
#define TESTAPP_PATH "@TESTAPP_PATH@" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(here)
src/plugins/gopts/gopts.c
Outdated
#elif defined(ELEKTRA_GOPTS_SYSCTL) | ||
#include "gopts_sysctl.h" | ||
#else | ||
// define anyway to get rid of IDE warnings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
define it before (as prototype)?
{ | ||
int argc; | ||
|
||
LPWSTR * args = CommandLineToArgvW (GetCommandLineW (), &argc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be okay for now.
The more I work on this, the more I realize, this plugin won't work the way we intended it to. At least not without some major modifications to the core of Elektra.
All of these modifications to the core might be possible, but considering that there are some major changes to the plugin framework planned and most of the changes required for this plugin might interfere with these, I don't think now is the right time to implement this plugin. What might actually solve all these problems, is the The only problem is, I don't know how the plugin framework handles, if a plugin returns Keys outside the given parentKey. |
We can add further places. Or we could use infos/ordering to make the validation earlier.
Actually, you can mount plugins to spec (only). Spec is excluded from cascading mountpoints on purpose.
I think such applications can also simply throw the content from proc/.
I think the framework currently throws the keys away. But I also think that it somehow makes sense to have proc/ as exception as it is no ordinary namespaces (no plugin is responsible for it). |
now also works, if KDB_DB_USER is not set to ~/.config
the plugin is disabled by default and a very quick and dirty temporary(!) solution to enable it is provided
@markus2330 The plugin is now added as a global plugin by default (like My next step will be adding If |
jenkins build all please |
I think this is done now... @markus2330 please review |
Why is the jenkins build green/OK when there is one terminated/failed build? |
I guess only the Jenkins devs could answer that one .... |
jenkins build libelektra please |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this PR! Overall some very nice improvements and cleanups to kdb, list, and internalnotification.
The code is nice and clean. I only reviewed the changes but won't be able to test it on my machine until late this evening.
contract. In principle this a very powerful tool that may be used for a lot of things. For now it only supports a few conditions concerning | ||
plugins: | ||
|
||
- You can specify that a plugin should be mounted globally. This is can for example be used to enable the new [gopts](#gopts) plugin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"This is can for example" -> "This can for example"
@@ -171,7 +198,7 @@ compiled against an older 0.8 version of Elektra will continue to work | |||
|
|||
### Core | |||
|
|||
- <<TODO>> | |||
- `kdbGet` now calls global postgetstorage plugins with the parent key passed to `kdbGet`, instead of a random mountpoint. _(Klemens Böswirth)_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I noticed (but didn't look into): At least some errors returned from global plugins are suppressed by kdbGet
. You may want to look into that while working on #2457.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, we didn't even use return values until #2307. The global plugin implementation needs to be re-worked and tested properly, so that it matches the proposal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work. A few change requests.
### <<HIGHLIGHT2>> | ||
### kdbEnsure | ||
|
||
`kdbEnsure` is a new function in `elektra-kdb`. It can be used to ensure that a KDB instance meets certain conditions specified in a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conditions -> clauses (2x)
- Conversely you can also define that a plugin should not be mounted globally, e.g. to disable the `spec` plugin, which is enabled by default. | ||
- Additionally you may want to enforce that a global plugin uses a certain configuration. For this case you can specify that the plugin | ||
should be remounted, i.e. unmounted and immediately mounted again. | ||
- In future non-global plugins will support the same features. But because of the different architecture involved, for now only unmounting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to mention it. We might or might not add it.
@@ -60,10 +60,30 @@ class KDBException : public Exception | |||
return m_str.c_str (); | |||
} | |||
|
|||
private: | |||
protected: | |||
Key m_key; | |||
mutable std::string m_str; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be private?
ksDel (pluginConfig); | ||
return ensurePluginUnmounted (handle, mountpoint, pluginName, errorKey); | ||
case PLUGIN_STATE_MOUNTED: | ||
return 0; // TODO: ensurePluginMounted (handle, mountpoint, pluginName, pluginConfig, errorKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also assert here that this is not called? (2x)
src/libs/elektra/kdb.c
Outdated
* If `<mountpoint>` is NOT `global`, currently only `unmounted` is supported (not `mounted` and `remounted`). | ||
* | ||
* NOTE: This function only works properly, if the list plugin is mounted in all global positions. | ||
* If this is not the case, 1 will be returned, because this is seen as an implicit condition in the contract. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to fail if you cannot do it. The application has no control over if the list plugin is there or not. And it expects that kdbEnsure
actually ensured its contract if it returned successfully.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return value 1 indicates a failure. Only 0 means success.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is non-standard compared to other kdb calls. Can you change that to be -1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could change it to -2, if you want all negative return values + 0 for success...
1 is returned, if the contract could not ensured, but the kdbEnsure
call was entirely valid. e.g. if a plugin could not be mounted
-1 meanwhile is used to indicate that either the contract is malformed, or something else about the kdbEnsure
call is wrong.
If 1 is returned, the application should show a meaningful message to the user, because they might need to change their KDB configuration. If -1 is returned, the application probably has a bug, and without changing the code there is little to no chance of fixing the problem...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could change it to -2, if you want all negative return values + 0 for success...
I do not think we need this distinction in the return value as you can simply set different errors in the errorKey.
Furthermore, I think it might be useful to indicate if something was done at all.
So I would propose following return codes:
- 1: could not run kdbEnsure successfully (error is in the errorKey)
0: kdbEnsure successful but nothing was to do
1: mounted or unmounted something, so the application now has different mountpoints than the rest of the system
This would be basically identical to return codes of the other kdb* calls (and also the resolver).
Iirc there are now also macros defined for these values.
src/libs/elektra/kdb.c
Outdated
* This function can be used the given KDB @p handle meets certain conditions, | ||
* specified in @p contract. Currently the following conditions are supported: | ||
* | ||
* - `system/plugins/<mountpoint>/<pluginname>` defines the state of the plugin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the name system/elektra/ensure/plugins/...
? system/plugins
is not reserved and it will create problems once these keys should be read from KDB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can change it, but I don't see a reason, why these keys should be stored in the KDB. They are not configuration, they are static specification. IMO the use case for kdbEnsure
is that an application wants to make sure the KDB is in a state that is usable to the application. Changing this contract should only be necessary, if the code changes, i.e. recompiling is necessary.
That is also the reason, why I decided it is okay to consume the contract. If the keys came from the KDB this would be rather inconvenient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can change it, but I don't see a reason, why these keys should be stored in the KDB.
It is not about storing them there but it might be useful to be able to query the contracts of applications (with a functionality similar to the specload).
src/libs/elektra/kdb.c
Outdated
* | ||
* @param handle contains internal information of @link kdbOpen() opened @endlink key database | ||
* @param contract KeySet containing the contract described above. | ||
* Because of the implementation, this will always be `ksDel()`ed. <b>Even in error cases.</b> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
" Because of the implementation" is redundant information. Maybe you wanted to say: "To allow kdbEnsure(.., ksNew(...)
..."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you wanted to say: "To allow kdbEnsure(.., ksNew(...)..."
That is a nice side effect, but in most cases won't make for good, readable code. The actual reason is that I use ksCut
and wanted to avoid having to ksDup
first, because the contract shouldn't be needed after calling kdbEnsure
anyway.
src/tools/kdb/CMakeLists.txt
Outdated
@@ -20,7 +20,7 @@ if (BUILD_SHARED) | |||
add_executable (kdb $<TARGET_OBJECTS:kdb-objects>) | |||
add_dependencies (kdb kdberrors_generated elektra_error_codes_generated) | |||
|
|||
target_link_libraries (kdb elektra-core elektra-kdb elektratools) | |||
target_link_libraries (kdb elektra-core elektra-kdb elektratools elektra-proposal) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is ugly and should be avoided. Which methods from proposal do you need?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, this is actually just an artifact from some earlier tests, because I didn't actually change the kdb
tool. I just used it for testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, perfect, then you can simply change it back.
|
||
## Usage | ||
|
||
The preferred way of using this plugin is via `kdbEnsure`: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't global mounting possible, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically yes, but the kdb
tool doesn't call kdbEnsure
yet (to make sure gopts
is unmounted, when accessing third-party configuration), so kdb get
etc may break in certain cases.
gopts
is unmounted by default for now. My plan was to make it mounted by default in future and just unmount it in kdb
. That is however quite tedious work, because each command uses its own KDB
instance, not created through some shared means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about subclassing KDB (where gopts
is ensured to be not there) and replace all KDB with the subclass? (Should be a simply search&replace.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to create KDBCommand
, an abstract subclass of Command
that provides a KDB
instance to its subclasses. I think this is a nicer solution, because later on KDB should use gopts
for its own config and only the commands accessing the rest of the KDB should use the version without gopts
.
I will modify kdb
in a follow-up PR and then we might mount gopts
by default.
The preferred way of using this plugin is via `kdbEnsure`: | ||
|
||
```c | ||
KDB * kdb = kdbOpen (parentKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if this code is also as stand-alone minimal-working example available.
Btw. did you also try if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR looks good as far as I can tell. I am not familiar with the updated parts of Elektra at all though, so I am not really the right person to review this pull request. I also only skimmed over the code, since a proper review would probably require multiple hours of work.
int KDB::ensure (const KeySet & contract, Key & parentKey) | ||
{ | ||
// have to ksDup because contract is consumed and ksDel()ed by kdbEnsure | ||
int ret = ckdb::kdbEnsure (handle, ckdb::ksDup (contract.getKeySet ()), parentKey.getKey ()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can replace
ckdb::ksDup (contract.getKeySet ())
with the shorter
contract.dup ()
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No that won't work, because that will cause a double free, because the C++ class KeySet will call ksDel()
in the destructor.
src/libs/elektra/kdb.c
Outdated
* | ||
* @param handle contains internal information of @link kdbOpen() opened @endlink key database | ||
* @param contract KeySet containing the contract described above. | ||
* Because of the implementation, this will always be `ksDel()`ed. <b>Even in error cases.</b> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since Doxygen also supports Markdown syntax, I think it might make sense to use
**Even in error cases.**
instead of
<b>Even in error cases.</b>
.
src/plugins/list/README.md
Outdated
Plugin * elektraListFindPlugin (Plugin * handle, const char * pluginName) | ||
``` | ||
|
||
`elektraListMountPlugin` can be used to add a new plugin to the config. The placement will be query from the plugin it self (from its |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you maybe mean “queried” instead of “query”?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know, “it self” should be written as one word in this context.
src/plugins/gopts/testapp.c
Outdated
{ | ||
if (strcmp (name, TEST_EMPTY) == 0) | ||
{ | ||
*parentKey = keyNew ("spec/tests/gopts", KEY_END); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it would make sense to create the parent key only once. As far as I can tell, each of the if
-statements creates exactly the same key.
src/plugins/list/README.md
Outdated
@@ -48,6 +48,23 @@ A list of set-placements for the plugin. Same for "get" and "error" | |||
|
|||
Plugin specific config. | |||
|
|||
## Exported functions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use title case for all headings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs to be added to doc/CODING.md?
It is available in Python (tested) and should be available in any binding that is auto-generated.
It is technically possible right now, but because |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very good now! Two small comments.
KS_END); | ||
} | ||
|
||
static int setupSpec (void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please mention here that this is only like this to be self-contained, not that an application should do this.
@@ -102,7 +102,7 @@ kdb ls user/tests/multifile | |||
|
|||
kdb rm -r user/tests/multifile/test.ini | |||
|
|||
stat ~/.config/multifile/test.ini | |||
stat $(dirname $(kdb file user))/multifile/test.ini |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We also should add build jobs which use non-standard config paths (ideally also with some umlauts, white spaces, ...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK most if not all build jobs (certainly the Jenkins ones) use non-standard config paths inside the workspace directory. I also run all local tests with a similar setup.
About umlauts/white-space I am not sure, we might want to create an issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the multifile test cases are not running on our build server?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just checked and at least the debian-stable-full
build runs this test successfully... Maybe some of the changes to kdbGet
I made, brought up a hidden bug which was suppressed before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for looking into it!
@markus2330 I think we can merge this, if not, please tell me what I missed |
Thank you so much for this very nice PR! It is great that not only LCDproc will from now have command-line arguments. @ulschaef hopefully will also soon have finished the command-line argument completion, which would make our solution complete 👍 |
Closes #2427
Basics
doc/news/_preparation_next_release.md
which contains_(my name)_
)Please always add something to the the release notes.
(first line should have
module: short statement
syntax)close #X
, should be in the commit messages.Checklist
Review
@markus2330 please review my pull request