-
Notifications
You must be signed in to change notification settings - Fork 123
Reliable way to lookup plugins providing certain functionality #994
Comments
Thank you for the analysis! First off: I do not understand what "functions", "array", "object", and "numeric" are in this context. Do you think here of capabilities what can be parsed? (E.g. json without array-syntax?) Where are such sub-formats relevant? It seems to me that such a plugin simply is not implemented completely (That would be "unfinished" in infos/status) Second: I am not sure what your requirements are. Some requirements are mentioned between the lines, but an explicit list of them would be great. Third: How does option 1 and "infos/offers/format" differ? Now some details/replies:
Yes, we can change them from storage -> info?
That would be "unfinished" in infos/status, too. (Except for "info" plugins, they are by design only get)
ni actually has "ini" as infos/provides. The question is if it should, because it assumes sections to be keys and keys to be meta keys. So it will be useless for your purpose.
What about crontab or hosts? They are very widely used, but also very limited.
Currently you can find a suitable xml, json and ini plugin; but you cannot get a list of all formats. I really like your "format" idea, it basically would solve this gap. (Btw. the implementation is not trivial, some plugins like augeas offer many formats.) I do not understand, however, why format needs to be in a different clause (of the contract), what do you think about `infos/provides = storage format/ini"?
Both functionality and formats build up an ambigue ontology. A list of tags might not address this. For example is toml ini? A toml parser most likely will happily parse ini files... @sanssecours Can you also share your thoughts? |
Ok, probably my examples were terribly bad, sorry. I'm actually talking about exactly what you mentioned some lines below:
I'm simply looking for some (easy) way to determine whether a plugin is suitable for a snippet or not (i.e. the snippet can be represented with the plugin / in the language of the plugin). I doubt it is as easy as asking "can this plugin represent any snippet - yes or no?", so we might need some more differentiations of what the plugins actually can do. Obviously remains the questions whether this makes sense or not and if it is even possible to create such a list of functionalities (from the point of view of Elektra).
I wasn't really talking about adding the actual format to the
That's another sub-topic that could be discussed: make transparent (through the
I actually tried something like this already, but with
Resolving this issue and all questions that will potentially arise should be the goal of this issue. I will clearify my requirements in the initial post. |
I do not understand what you want to detect. This requirement sounds to me like the auto-detection feature you rejected earlier: It would require some heuristics on a configuration file that can tell that a snippet is likely some format. This problem is not solvable by contracts alone, it needs code that counts characters distributions, tries to parse, and so on. So we should clearly define what this issue is about, do you only want to get a list of formats (the user can select from) or do you want a detection of a format based on the snippet?
The contract can be modified dynamically, so I see no limitation of what it can represent. Which "list of functionalities" do you mean? How do you detect functionalities within snippets?
You are right, it currently is impossible. "Provides" is there for a different reason: It is used during the mounting process to have virtual dependencies (so you can mount "json" even though the plugin is called "yajl"). We need, however, some clear idea what a format is. E.g. xmltool can only parse xml files following a specific xmlschema. Is this already the "xml"-format? And it is also very unclear to me what "capable of handling" means: the "line" and "ini" plugin can parse any file, but nevertheless they might be the wrong choice. |
Depends on the perspective of view. Currently I'm primarily talking about export, as import depends too on the behavior of current plugins anyway (e.g. do they fail if they could not parse the config?). For the export you would only have to know if the plugin supports the constructs used by the snippet, but you are right, a generic interface is probably not going to work.
In the first place I want to get a list of formats for the user, but in a second step it would be sweet if it was possible to determine whether the users choice makes sense or not (because the export/import worked or not). But somehow I doubt that it is as easy as imagined and it would probably make more sense to write more generic plugins.
Yes, I know that and it is still valuable for my purpose, because when there are several plugins for the same format, I want the best possible.
If I'm not wrong, the line plugin can handle only an array at root level. So it is not capable of array/object structures with higher depth for example. And other plugins have similar limitations, but it would still be hard to find a generic way to detect these problems I guess.
Well, that's a very good point. I've no idea where to put xml currently, but I wouldn't say the line plugin is capable of handling most snippets out there, so I would not give it a format (is it even a common one?). One method to detect whether a format can handle a snippet could be to export, import and compare. |
Ok, that is an important missing piece for my understanding what you mean ;) I was talking about import, which I considered more important because you can simply remember how a snippet was imported for later exports.
Yes they fail, what should a XML parser do with an INI or JSON file?
For this we can specify formats in the contract.
What do you mean here? Generic in which way?
Such round-tripping tests would be really great! Such feedback would be very valueable for improving our parsers. Do you think its too greedy if the licence for uploaded snippets allows us to use snippets for test cases?
That limitation is somehow arbitrary and can easily be fixed. But the line plugin discards all its keys, and only preserves values by design. So it only has round-tripping properties when you only use the "line" plugin, but not so many useful properties for transformation between configuration file formats.
The grand goal is that every limitation of every plugin can be worked around with other plugins. E.g. if a plugin can only store values at leaves (like JSON), a dir2leafvalue plugin (#106) could do proper transformations. In the same way we could transform any keyset to an array (with the names encoded in the values) and so on.
The idea is that plugins tell their limitations via infos/needs, so that during mount/import/export the correct plugins can be assembled which work around the problems. Obviously sometimes we want limitations in structure, e.g. it would be strange to try to encode an arbitrary XML file as host file. In these cases, the plugins should describe their structure as type (e.g. the fstab plugin does this, see Concededly, both points are currently more an idea than fully realized.
In its current incarnation the XML plugin is quite useless for your purposes. It is only designed to import/export Elektra config. But it would be straight-forward to implement an XML plugin that transforms any XML file to a KeySet (e.g. elements to key names and attributes to meta data). Maybe @sanssecours will improve the situation here.
It seems to be confusing what the "line" plugin does . The line plugin is no "format", it takes any file line by line and transforms it to an Elektra array. I updated the docu in a409888
Yes, that round-tripping works is essential, you really should do that test, see above. Great idea! |
I do not think that I have much to add to the discussion:
|
That doesn't tell you whether the import made sense or not.
I think the last time I played with the XML plugin, it did not fail on my ini file, but created an empty KeySet and succeeded.
Again you answered your own question. ^^
But that means it is no "language" (as @sanssecours called it), so I would not offer it within the scope of the service anyway?!
The problem with this is that it (should) only work with export (export, re-import & compare keyset), but not with import (import, export & compare the conf. snippet), because I cannot rely on the fact that our plugins export the same way they can import (e.g. ignore white-space during import). So import still depends on the users choice of the snippet format/language. With all the discussion, more question arise for me:
|
Yes, that is why I was talking about how to know if an import worked. And the export should cause no problem if the same format is chosen. But I think the main piece of misunderstanding was that actually there are two use cases which we intermixed: 1.) Someone uploads a snippet and sees the content as file
That would be a severe bug, please report it. I cannot reproduce it, I always get error 110 (Start tag expected, '<' not found).
It is still unclear to me what you mean. You were the first in this thread who used the term "generic".
The line plugin would be ok for use case "1.)", but unusable for "2.)". (see above in this post). For "2.)" limited storages (like hosts) are important. Btw. I think we should avoid "language" because it can be confused with the implementation language of the plugin, which can be useful information, too. "format" does not have this issue.
Here we have again differences between use case "1.)" and "2.)". In use case "2.)" we exactly have the better supported variant: we start with export and re-import it as snippet in your tool. For use case "1.)" (starting with file-content) it is true that most plugins currently have severe issues. (Not only whitespaces, but some even lose comments or ordering of the lines). @sanssecours work should improve that situation. Till then we can only tag plugins with "format" that preserve content well enough (taking augeas into account, this are still dozens of formats). For such plugins (like "ini". "yajl" or "hosts") we could simply ignore whitespaces for comparing after roundtrip.
Yes, for use case "2.)", hosts and so on are very important. But also for "1.)" only specific plugins can check the syntax. Which changes in the API do you mean?
Actually most formats will work (ini, xml, json,...) only other limited storages will fail (you cannot export a hosts file as fstab). So we somehow should systematically describe which formats are limited. That could be part of Is this something you can work with?
I am missing context: where and when do you want to offer what? Can you complete the use cases and refer to it? If you mean some kind of drop-down menu while uploading snippets: Yes, you can always list all plugins, but for usability it seems to be essential that you somehow order the list so that the top choices (and the default one) actually were tested with the snippet (and round-tripped successfully). |
I don't think you can always know, but checking for success of the plugin and non-empty result set is a good start.
I don't really get the difference, as "snippet" is always a piece of configuration in a certain format that can be represented in plain text.
Not based on (special behavior introduced by) Elektra, but able to handle anything.
You rely on too much uncertainties here in my opinion. For me it doesn't matter where the snippet comes from (and I don't think it should). Even an Elektra installation can be twenty versions off with deprecated plugins creating unusable stuff. Also the user could try to change the exported snippet by hand and cause additional trouble.
Agree.
How to know possible configurations (lenses) for the augeas plugin? And doesn't that violate the common approach of just calling a plugin? (suddenly introduce configuration for some plugins)
Again, how to know "for such plugins"? I hate special cases. There has to be a common way to know what to do in-code (and too many of those special common ways are stupid too, oviously, because then it's not maintainable outside-code anymore).
It is not so much about the importance, but rather if I can set them side-by-side, meaning they are "equal" in terms of what I give to the user. Have a look at the current API and tell me whether this info is enough to cope with hosts or not. For me, currently, every format/plugin is equal. That import and export will fail is very likely when using the wrong plugin, but that's it. No more distinction here.
That's going into the direction I was looking for with this issue, yes. It will require me to save what format was used during import (not a big deal). But I think it will also require an API change, because every snippet can now have different export options (we know that without even attempting an export).
Currently there is above mentioned API resource to get a list of supported formats/plugins. This list is valid for the whole API, for both import and export (responsibility to only include plugins that can do both, get and set, remains to the maintaining admin). But if some snippets are limited by default, e.g. because it's a hosts snippet, then I'd need a reduced list of possible formats/plugins. Or I just fail on every export, that's also an option. 😄 Although I currently convert the snippet, for the detailed entry resource, into every available format anyway. Maybe the change isn't really necessary.
You are mixing im- and export. And saving any additional data means huge effort in the end. This point also asks for an API change, as the format list would be different for each snippet (import format first)... |
What do you mean? A successful round-trip verifies that it will work (at least for this input).
The difference is important when you export with something else than you imported. E.g. when you import following line as hosts:
but if you import it as
and so on. That means the same snippet can produce different hierarchies.
Ok, that would be plugins without structural limitations, i.e. plugins that handle arbitrary semi-structured data.
When someone wants to upload (with export) his/her configuration from Elektra, it is important that a later download (with import) does not destroy anything (produces the exact same tree).
If every edit from a snippet rechecks that the round-trip still works, there should be no trouble. Then the user is always in a safe toolchain: local kdb upload/download and the edit functionality of the REST service.
No, it was always possible that plugins with different configuration have different contracts. To discuss the querying of every configuration that changes contract I opened #1006.
Elektra tries to avoid special cases whenever possible. Only fundamentally different things are described in the plugin's contract. So you should never have checks for specific plugins in code but always only cases for different contracts.
Yes, every plugin is equal in the sense that they might not be able to parse a configuration file (fail transform it to a KeySet). But they are different in the sense that only some plugins are not be able to generate a configuration file (with any KeySet as input). I am not sure if you need to consider it in the code or the API but users certainly need to be aware of it (see my example above how the same export can be different if the import was done differently).
It might be a good idea to support the mount-syntax (
I would rather work with suggestions/ordering/"greying out"/"putting to expert mode" than disabling something completely. It is possible that a round-trip only fails because of a bug. The user should be able to reproduce the issue (and hopefully report it g).
Yes, I also do not think that large changes are needed.
What do you mean here, in my sentences the words "import" or "export" did not occur? I was only asking what your question "Should I simply offer a format, even though I do not yet know if the snippet can be represented by it?" meant. |
Even with trimming a round-trip will (in most cases) not work for imports. For example think of comments in a snippet. Adding support for removal of things such as whitespace, comments, etc. is way too hard and problematic. I'll stick with my approach here and check for an empty keyset (not allowed, as it is no snippet). Quite possible that there will still be cases where only parts can be parsed, but no way we can change that if the users choice of the format/plugin was bad.
Sure, I got that. And storing the import plugin/format to provide a better output seems a good approach, but doing anything more will be hard. It is - again - the users choice how to export. He sees all the results (at least in the web gui), so he can choose himself. But for import itself, it does not change anything. The import expects a snippet and a format. Doesn't matter where these come from, as we can't control that anyway.
Same problem as for import (basically the same function), see above.
Sure, but handling douzens of contracts isn't the best option either. I just want to avoid that.
Depending on the result of #1006, it could be an option.
So you think I should still send a snippet that failed the round-trip (export) to the user, but flag it as potentially broken? I can do so for the snippets that succeeded the export, but not the others. So we would have three groups: failed (not sent), failed round-trip (sent and flagged) & succeeded (sent).
Re-read above quote please. You said that I should limit the format-dropdown to formats that have been tested with the snippet, but I can't test snippets until they get uploaded (I won't stress the API with pre-flight conversion tests in the background, no way). So this makes no sense (from a workflow perspective). |
You should at least give a warning/notice (and log it for us to evaluate the problem) if the stored content is not equal to what was uploaded. And if the difference is only whitespace imho it would not be necessary to show a warning (whitespaces are not even handled in our latest comments proposal. It is only fully handled by augeas plugin).
Yes, sounds useful. Otherwise there could be a really bad surprise (someone thought the snippet was uploaded and after download all comments are gone) and we do not want to lose customers, won't we?
I do not think that this was said anywhere before but now it is clear what you mean. So a notice after upload that the snippet might be broken and a way to immediately reupload it differently should make good usability possible without "pre-flight conversion tests". |
After the snippet was created, the user is redirected to the details page where he can see the result. If he is not satisfied, he can use the edit function. This way I don't have to implement transaction logic in the frontend (which is not available in the backend anyway) and it is quite easy to understand as well. A warning is a good compromise, though. |
Can I add a PR with the discussed changes?
Does the change of |
Agreed.
Agreed, you can create this PR.
Changes would be required (e.g. also in cmake) and it is somehow a weird hack. So I think we should go for one of the alternatives:
Seems like 1. is the best option after all? |
Looking into cmake, option "0." (your proposal with infos/provides: add format/ for plugins) could be viable, if we (additionally) simply cut off "*/" from every provider. But in libtools we have the problem that both variants make sense (you want to mount |
I don't like option 2 because the whole contract is based on something like tags, just not tags with variable content. It is not that I think variable tags wouldn't be useful, they definitely are, but as you said, it seems arbitrary. Option 3 would be ok if there wasn't the multi-format issue. To know that there are multiple formats, we would need a comprehensive list of formats to compare which tags are meant to be formats. An implicit best-practice like "all tags before So from the first post, I would also go for option 1.
So in the readme we would only document |
That would be useful for compatibility because if you currently specify One potential issue is the massive overload of
What do you mean here? I thought the proposal 0. is about documenting the format only in
Mostly implementation or compatibility issues. If we do not support the old ways of |
Don't get me wrong, I like your backwards-compatibility suggestion. It just seems that our current discussion is between adding the format twice manually (
Yes, I thought about this already too. As
Sorry, you are right, the third option has no duplication (but too much implicit assumption through the ordering, what seems hard to document/understand to me [think about pitfalls for new users]). Documenting the format as |
I agree it is minor (code impact is low) but I would not call it convenience issue. If we duplicate
Yes, Anyway, do you dislike a vote for separators in Elektra?
Yes, I agree here. |
A vote for separators seems fine to me. |
I think I have a solution that should satisfy all requirements we talked about:
Further I suggest that we merge the "concepts" What do you think? |
I think that sounds like a good way to go about it! |
Can you create an implementation task and close this issue please? |
So your suggestion is that we'll use |
Yes, because the plugins are already known as storage-plugins. And "storage"-plugins that do not provide a configuration file format (but only output fixed values) will be renamed to "info". Together with limited/readonly/writeonly (see #666) we should describe everything you need for your snippet service? (or are you missing something?) |
No, I'm not missing anything, I just wasn't totally sure that I understood it correctly. Doing the implementation task just now! Edit: Maybe I miss something. How can we emphasize that |
You are right, it is not emphasized. |
Ok, in this case the combination of |
Yes, |
Idea
Retrieve plugins via
libtools
that can be used to convert configuration snippets. In order to do so, it is required to know which configuration format (ini, xml, json, csv, ...) each plugin supports.Problem
Currently a lot of plugins are in the
storage
group, but do actually not support/offer a proper configuration format (e.g. constants, desktop). (They sometimes don't even support bothget
andset
.) This makes the automatic lookup of such plugins impossible. Also the configuration format offered/consumed by other storage plugins is not always known (e.g.ni
plugin forini
).Requirements
Suggestions
First option: A new keyword for the
provides
description field of plugins could be invented, used to specify whether a plugin consumes/produces configurations of an actual widely used configuration format like xml, json or ini:constants
andini
.Second option: A whole new description field could be invented to specify the configuration format as well as the functionality offered by a plugin. This field would require a certain format, e.g.
infos/offers = array object numeric format:json
if the plugin can handle arrays, objects and numeric values, while staying within the json syntax.constants
andini
.If possible, having nested keys for this option would be even better:
Discussion
The text was updated successfully, but these errors were encountered: