Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

Reliable way to lookup plugins providing certain functionality #994

Closed
4 of 7 tasks
Namoshek opened this issue Sep 30, 2016 · 30 comments
Closed
4 of 7 tasks

Reliable way to lookup plugins providing certain functionality #994

Namoshek opened this issue Sep 30, 2016 · 30 comments

Comments

@Namoshek
Copy link
Contributor

Namoshek commented Sep 30, 2016

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 both get and set.) 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 for ini).

Requirements

  • Know the configuration format (ini, json, xml, ...) handled by a plugin.
  • Know whether a plugin is capable of handling a certain configuration snippet (because of constructs used within the snippet, e.g. arrays).

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:

  • Would make it possible to distinguish between plugins like constants and ini.
  • If also used to determine whether a plugin is capable of handling most configuration constructs offered by Elektra, it could be a hassle whether to put a plugin into this category or not ("how much functionality is sufficient?"). To solve this issue, another keyword could be invented.
  • Does not solve the issue, how to determine the configuration format offered by a plugin and would therefore require some additional solution for that.

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.

  • Solves the configuration format issue.
  • Solves implicitely the problem to distinguish between plugins like constants and ini.
  • Allows to check whether a plugin is capable of representing a configuration as snippet or not.
  • Some edge cases not supported by plugins could be a hassle (e.g. recursive objects not supported).

If possible, having nested keys for this option would be even better:

infos/offers/format = json
infos/offers/functions = array object numeric

Discussion

  • Do we really need such a feature or are the requirements resolvable with current information?
  • Does one of above suggestions cover all issues/requirements?
  • Other suggestions / ideas / requirements?
@Namoshek Namoshek changed the title Reliable way to lookup plugins suitable for REST service Reliable way to lookup plugins providing certain functionality Sep 30, 2016
@markus2330
Copy link
Contributor

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:

proper configuration format (e.g. constants, desktop).

Yes, we can change them from storage -> info?

They sometimes don't even support both get and set

That would be "unfinished" in infos/status, too. (Except for "info" plugins, they are by design only get)

is not always known (e.g. ni plugin for ini).

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.

actual widely used configuration format like xml, json or ini

What about crontab or hosts? They are very widely used, but also very limited.

Do we really need such a feature or are the requirements resolvable with current information?

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"?

Does one of above suggestions cover all issues/requirements?

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?

@Namoshek
Copy link
Contributor Author

Namoshek commented Sep 30, 2016

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)

Ok, probably my examples were terribly bad, sorry. I'm actually talking about exactly what you mentioned some lines below:

What about crontab or hosts? They are very widely used, but also very limited.

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).

Third: How does option 1 and "infos/offers/format" differ?

I wasn't really talking about adding the actual format to the provides field (how to know which of the provide values is the format?), but rather to use another word instead of storage. But your suggestion to move "not actual storage plugins" to another keyword seems fine as well.

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.

That's another sub-topic that could be discussed: make transparent (through the infos contract) whether meta data will be handled by a plugin or not. In the long run it would be awesome if this could be adjusted at runtime for each plugin (through a well defined interface maybe?).

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"?

I actually tried something like this already, but with format:ini, which caused errors (I guess because of the :?!). If format/ini works, I'm totally fine with that! Currently it just seems to be impossible to know which provides field is the format, because it is not a good idea to rely on the fact that most storage plugins only have two provide values, right?

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...

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.

@markus2330
Copy link
Contributor

Know whether a plugin is capable of handling a certain configuration snippet

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?

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)

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?

Currently it just seems to be impossible to know which provides field is the format

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.

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 1, 2016

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.

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.

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?

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.

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").

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.

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?

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.

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.

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.

@markus2330
Copy link
Contributor

Currently I'm primarily talking about export,

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.

as import depends too on the behavior of current plugins anyway (e.g. do they fail if they could not parse the config?)

Yes they fail, what should a XML parser do with an INI or JSON file?

In the first place I want to get a list of formats for the user

For this we can specify formats in the contract.

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.

What do you mean here? Generic in which way?

because the export/import worked or not

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?

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.

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.

And other plugins have similar limitations, but it would still be hard to find a generic way to detect these problems I guess.

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.

but it would still be hard to find a generic way to detect these problems I guess.

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 config/needs/struct).

Concededly, both points are currently more an idea than fully realized.

Well, that's a very good point. I've no idea where to put xml currently,

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.

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?).

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

One method to detect whether a format can handle a snippet could be to export, import and compare.

Yes, that round-tripping works is essential, you really should do that test, see above. Great idea!

@sanssecours
Copy link
Member

@sanssecours Can you also share your thoughts?

I do not think that I have much to add to the discussion:

  • Prefixing the format inside infos/provides sounds like a good idea. We could also use language instead of format (e.g language/ini). Though to me, neither one of these tags seems to be superior to the other.
  • Exporting, importing and comparing seems like a good way to determine if a plugin supports all the needed functionality to store a snippet. I especially like this solution, since it seems less complex, than to determine the functionality according to a set of plugin tags.

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 2, 2016

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.

That doesn't tell you whether the import made sense or not.

Yes they fail, what should a XML parser do with an INI or JSON file?

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.

What do you mean here? Generic in which way?

Again you answered your own question. ^^

In its current incarnation the XML plugin is quite useless for your purposes. It is only designed to import/export Elektra config.

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.

But that means it is no "language" (as @sanssecours called it), so I would not offer it within the scope of the service anyway?!

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 config/needs/struct).

struct is set as recommendation, but I get your point and that is basically what I'm talking about.

Yes, that round-tripping works is essential, you really should do that test, see above. Great idea!

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:

  • Can I put the snippets consumed/created by the hosts plugin side-by-side with snippets created by, lets say, the ini plugin? I mean, is hosts considered an actual "format/language" and should therefore be offered by the API?
    • If yes and I import a hosts file, how to handle export? I doubt I can offer all formats?! (Not offering all formats leads to design conflicts btw.)
  • Should I simply offer a format, even though I do not yet know if the snippet can be represented by it?

@markus2330
Copy link
Contributor

markus2330 commented Oct 3, 2016

That doesn't tell you whether the import made sense or not.

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
2.) Someone uploads a part of an Elektra hierarchy and sees the content as something to import later

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.

That would be a severe bug, please report it. I cannot reproduce it, I always get error 110 (Start tag expected, '<' not found).

What do you mean here? Generic in which way?
Again you answered your own question. ^^

It is still unclear to me what you mean. You were the first in this thread who used the term "generic".

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 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.

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.

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.

Can I put the snippets consumed/created by the hosts plugin side-by-side with snippets created by, lets say, the ini plugin? I mean, is hosts considered an actual "format/language" and should therefore be offered by the API?

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?

If yes and I import a hosts file, how to handle export? I doubt I can offer all formats?! (Not offering all formats leads to design conflicts btw.)

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 infos/status = limited. And by definition plugins with status limited are only compatible if they provide the same format.

Is this something you can work with?

Should I simply offer a format, even though I do not yet know if the snippet can be represented by it?

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).

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 3, 2016

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.

I don't think you can always know, but checking for success of the plugin and non-empty result set is a good start.

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
2.) Someone uploads a part of an Elektra hierarchy and sees the content as something to import later

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.

It is still unclear to me what you mean. You were the first in this thread who used the term "generic".

Not based on (special behavior introduced by) Elektra, but able to handle anything.

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.

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.

Till then we can only tag plugins with "format" that preserve content well enough

Agree.

(taking augeas into account, this are still dozens of formats)

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)

For such plugins (like "ini". "yajl" or "hosts") we could simply ignore whitespaces for comparing after roundtrip.

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).

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?

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.

So we somehow should systematically describe which formats are limited. That could be part of infos/status = limited. And by definition plugins with status limited are only compatible if they provide the same format.

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).

I am missing context: where and when do you want to offer what?

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.

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).

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)...

@markus2330
Copy link
Contributor

I don't think you can always know, but checking for success of the plugin and non-empty result set is a good start.

What do you mean? A successful round-trip verifies that it will work (at least for this input).

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.

The difference is important when you export with something else than you imported. E.g. when you import following line as hosts:
127.0.0.1 localhost
you will get following ini after export:

[ipv4]
localhost = 127.0.0.1

but if you import it as line, you will get:

#0 = localhost 127.0.0.1

and so on. That means the same snippet can produce different hierarchies.

generic plugins

Ok, that would be plugins without structural limitations, i.e. plugins that handle arbitrary semi-structured data.

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.

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). infos/status = compatible guarantees that a later version of a plugin does not produce any differences in the hierarchy. At the moment unfortunately there are not many plugins having this status but obviously it is essential for Elektra that this number grows. (@sanssecours work)

Also the user could try to change the exported snippet by hand and cause additional trouble.

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.

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)

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.

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).

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.

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.

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).

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).

It might be a good idea to support the mount-syntax (plugin1 pluginconf1=pluginval1 ,..). It is already implemented in src/libs/tools/include/backendparser.hpp parseArguments.

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. 😄

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).

Maybe the change isn't really necessary.

Yes, I also do not think that large changes are needed.

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 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.

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 5, 2016

What do you mean? A successful round-trip verifies that it will work (at least for this input).

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.

The difference is important when you export with something else than you imported.
That means the same snippet can produce different hierarchies.

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.

If every edit from a snippet rechecks that the round-trip still works, there should be no trouble.

Same problem as for import (basically the same function), see above.

So you should never have checks for specific plugins in code but always only cases for different contracts.

Sure, but handling douzens of contracts isn't the best option either. I just want to avoid that.

It might be a good idea to support the mount-syntax (plugin1 pluginconf1=pluginval1 ,..). It is already implemented in src/libs/tools/include/backendparser.hpp parseArguments.

Depending on the result of #1006, it could be an option.

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).

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).

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.

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).

@markus2330
Copy link
Contributor

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.

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).

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).

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?

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).

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".

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 5, 2016

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.

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 6, 2016

Can I add a PR with the discussed changes?

  • infos/provides: add format/<format> for plugins with proper support
  • infos/status: add limited for plugins like hosts
  • add some decision notes

Does the change of infos/provides require a change of libtools too?

@markus2330
Copy link
Contributor

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.

Agreed.

infos/status: add limited for plugins like hosts

Agreed, you can create this PR.

infos/provides: add format/ for plugins with proper support
Does the change of infos/provides require a change of libtools too?

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:

  1. a new clause in the contract, e.g. infos/format
    • needs duplication of format to infos/provides (but we could warn in kdb check)
    • would be an optional clause (not every plugin has a format)
  2. use a tag interface: infos/tags = format=<format> or infos/tags = format/<format>
    • disadvantage: needs duplication of format to infos/provides (but we could warn in kdb check)
    • It is somehow arbitrary what a tag and what a new clause in the contract is (infos/stacking could have been a tag, too).
  3. have the format by convention in the beginning of infos/provides, i.e. before storage. (e.g. infos/provides = ini storage)
    • info plugins simply would lose their "storage" status.
    • how to handle plugins that parse multiple formats? -> maybe simple allow multiple formats (e.g. infos/provides = yaml json storage)
    • how to hande storage plugins that have some other functionality integrated (e.g. storage+resolver in one plugin)? -> would be very confusing (not work): (e.g. infos/provides = ini storage resolver vs. infos/provides = resolver ini storage)

Seems like 1. is the best option after all?

@markus2330
Copy link
Contributor

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 ini and not format/ini, but at other places (like in format detection) we obviously need "format/". Did you already have a solution for this issue in mind?

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 7, 2016

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 storage are formats" doesn't seem good either.

So from the first post, I would also go for option 1.

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 ini and not format/ini, but at other places (like in format detection) we obviously need "format/". Did you already have a solution for this issue in mind?

So in the readme we would only document format/ini, but cmake would create additionally ini from it? Even if we did not do that, we only had the same issue as with all other options: the format is documented twice. If infos/provides can handle values with a slash in them, I don't get why this option causes issues?

@markus2330
Copy link
Contributor

markus2330 commented Oct 7, 2016

So in the readme we would only document format/ini, but cmake would create additionally ini from it?

That would be useful for compatibility because if you currently specify PLUGINS=INI all ini plugins were added. But you are right, people could also live with PLUGINS=FORMAT/INI or kdb mount /file.ini /mp format/ini. It even has an advantage: For mount there is currently a (small) issue that if plugin name and provider name are equal and the plugin with this name has the lower score in infos/status, the plugin is preferred even though there are better options.

One potential issue is the massive overload of / (when you look at kdb mount). Maybe we should have a vote about separator characters in Elektra. (If we want to change namespace to : it might be not a good idea to change the provider-separator to :, too).

Even if we did not do that, we only had the same issue as with all other options: the format is documented twice.

What do you mean here? I thought the proposal 0. is about documenting the format only in infos/provides = format/ini storage and ini does not need to be mentioned anywhere else? In 3. we also have no duplication.

If infos/provides can handle values with a slash in them, I don't get why this option causes issues?

Mostly implementation or compatibility issues. If we do not support the old ways of mount file.json /mp json it should be straight forward.

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 7, 2016

That would be useful for compatibility because if you currently specify PLUGINS=INI all ini plugins were added.

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 (... format/ini ini...) or letting cmake create the latter from format/ini. I think that is only a minor convenience issue right now.

One potential issue is the massive overload of / (when you look at kdb mount). Maybe we should have a vote about separator characters in Elektra. (If we want to change namespace to : it might be not a good idea to change the provider-separator to :, too).

Yes, I thought about this already too. As format/ini is basically what you suggested as configurable tag above, I would personally prefer = as separator (this one seems the most obvious and most transparent to me). But maybe this is an issue if we use = already as separator for key/value?

What do you mean here? I thought the proposal 0. is about documenting the format only in infos/provides = format/ini storage and ini does not need to be mentioned anywhere else? In 3. we also have no duplication.

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 format/ini does not prevent us from providing the format in other words again though. It would only allow us to lookup certain provide keys by searching for the prefix format/. Of course this yields a small redundancy, but in my eyes it is only a minor convenience issue as mentioned above.

@markus2330
Copy link
Contributor

I think that is only a minor convenience issue right now.

I agree it is minor (code impact is low) but I would not call it convenience issue. If we duplicate format=ini and ini it is a (small) maintenance issue if we do not duplicate it, its a usability change (not necessarily an issue, hard to say if format/ini or ini fulfils user expectations better. Especially with auto-completion a prefix such as format might be even better).

I would personally prefer = as separator

Yes, = also makes sense here. But it would create a parsing problem for mounting. (Currently tokens that contain "=" are expected to be plugin-configuration.). : (your initial suggestion) is used for namespaces but it seems to be without conflicts (namespaces are only allowed for mountpoint, which has a fixed (different) argument position for kdb mount.

Anyway, do you dislike a vote for separators in Elektra?

too much implicit assumption through the ordering

Yes, I agree here.

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 7, 2016

A vote for separators seems fine to me.

@markus2330 markus2330 mentioned this issue Oct 7, 2016
@markus2330
Copy link
Contributor

markus2330 commented Oct 8, 2016

I think I have a solution that should satisfy all requirements we talked about:
We simply yield every combination of separated providers (for both cmake and libtools).
So e.g. format/ini would yield format/ini format ini. (/ is still open for discussion, see #1010)

  • This should work for mounting nicely, so people can still mount ini and json
  • In the case of ambiguity for mounting you can use format/ini to choose any plugin, and ini to choose exactly the ini plugin
  • For cmake you can add every plugin that supports a format FORMAT, but also INI.

Further I suggest that we merge the "concepts" storage and format, there is no real difference here. Instead we should add readonly and writeonly to infos/status.

What do you think?

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 8, 2016

I think that sounds like a good way to go about it!

@markus2330
Copy link
Contributor

Can you create an implementation task and close this issue please?

@Namoshek
Copy link
Contributor Author

Further I suggest that we merge the "concepts" storage and format

So your suggestion is that we'll use storage/ini instead of format/ini?

@markus2330
Copy link
Contributor

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?)

@Namoshek
Copy link
Contributor Author

Namoshek commented Oct 13, 2016

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 augeas has multi-format support / can generate configurations (upcoming)?

@markus2330
Copy link
Contributor

How can we emphasize that augeas has multi-format support / can generate configurations (upcoming)?

You are right, it is not emphasized. infos/status = configurable goes in this direction. Without further tags you can only detect it by looking if the symbol genconf (or some manual configuration for the plugin) is present. The question is if there really is a fundamental difference between other configurable storage plugins, e.g. simpleini (where you can specify the format via configuration, too).

@Namoshek
Copy link
Contributor Author

Ok, in this case the combination of configurable and genconf should be sufficient, thank you.

@markus2330
Copy link
Contributor

Yes, genconf and system/elektra/plugins/variants tells you everything. This is not the case for kdbGet/kdbSet, because e.g. kdbGet needs to be present for the contract alone, thus readonly/writeonly is needed

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants