Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service to suggest addons based on running processes #3904

Merged
merged 7 commits into from
Dec 16, 2023

Conversation

holgerfriedrich
Copy link
Member

This is a first draft of a new finder to suggest addons based on the software running on the OH server.
It checks the process list and tries to detect known software.

It has been mentioned in
#3868 (comment)

It will require changes in the addon.xml of the binding as well, but no change to the xsd, as the given match-property is reused. Here an example for influxdb.

       <discovery-methods>
               <discovery-method>
                       <service-type>process</service-type>
                       <match-properties>
                               <match-property>
                                       <name>command</name>
                                       <regex>.*influxd.*</regex>
                               </match-property>
                       </match-properties>
               </discovery-method>
       </discovery-methods>

@andrewfg Maybe you can have a short look if I forgot something before I try to create a full distro package to test it.
Any recommendation on how to test in a simpler way would be very welcome....

@holgerfriedrich holgerfriedrich requested a review from a team as a code owner December 8, 2023 00:53
@mherwege
Copy link
Contributor

mherwege commented Dec 8, 2023

@holgerfriedrich Nice to see a next step.

The easy way to test this is to put an xml file in the userdata/addons folder with the additional discovery content. Any xml file with valid content will be picked up from there. So there is no need to do a full build.
I am using Eclipse for development and have always been testing this functionality this way, running from Eclipse and adding an xml file with discovery criteria. If you use another IDE, you may have to replace the bundle.

A few questions and remarks I have:

  • Shouldn’t the process info be cached and refreshed at intervals? My concern is getting the processes could be slow and might result in a slow when called from the UI.
  • Would this work equally well on Windows and linux? Or would it require multiple criteria to be defined.
  • We went out of our way to be able to switch off discovery for UPnP and mDNS. I don’t think it is required here as this has lower impact. But we should all agree on it.

@kaikreuzer
Copy link
Member

We went out of our way to be able to switch off discovery for UPnP and mDNS. I don’t think it is required here as this has lower impact. But we should all agree on it.

I would prefer to have the same mechanism in place for all the discoveries. Having processes scanned in the background might not be something everybody wants.

@mherwege
Copy link
Contributor

mherwege commented Dec 8, 2023

Having processes scanned in the background

The PR is it is does not cache the running processes anywhere, so there is no background scanning. It will just make a call to get the processes when called from the suggestions REST endpoint. In the UI that means: when running the setup wizard or when opening the addon store. We can of course allow to disable that call as well. The main reason to be able to enable/disable was to avoid having all UPnP/mDNS dependencies loaded and running in the background only for addon discovery. As there is no extra dependency here, and as long as there is no scheduled scan and result caching, I don't see the point. But of course, see my concern about caching. If it is required, I think this becomes a different discussion.

@kaikreuzer
Copy link
Member

But of course, see my concern about caching.

Yes, that's why I was assuming that the logic of the PR will be changed to do some background scanning in future.

@andrewfg
Copy link
Contributor

andrewfg commented Dec 8, 2023

no change to the xsd, as the given match-property is reused.

I am glad to hear that :) the match-property model should suit most kinds of finder.

@andrewfg
Copy link
Contributor

andrewfg commented Dec 9, 2023

Any recommendation on how to test in a simpler way would be very welcome....

None really. It crosses over from addons to core so the only way to test is a full distro.

@mherwege
Copy link
Contributor

mherwege commented Dec 9, 2023

The easy way to test this is to put an xml file in the userdata/addons folder with the additional discovery content. Any xml file with valid content will be picked up from there. So there is no need to do a full build.

@andrewfg @holgerfriedrich I think this is the easy way to test without a full build. You can test in the IDE.

Signed-off-by: Holger Friedrich <[email protected]>
Signed-off-by: Holger Friedrich <[email protected]>
Signed-off-by: Holger Friedrich <[email protected]>
Signed-off-by: Holger Friedrich <[email protected]>
@holgerfriedrich
Copy link
Member Author

Thank you all for the comments.

I finally got it working for knxd.....

18:35:45.323 [TRACE] [very.addon.process.ProcessAddonFinder] - Candidate binding-knx, pattern ".*knxd"
18:35:45.324 [TRACE] [very.addon.process.ProcessAddonFinder] - Candidate binding-knx, pattern ".*knxd.exe$"
18:35:45.324 [DEBUG] [very.addon.process.ProcessAddonFinder] - Suggested add-on found: binding-knx

I will create a corresponding PR in addons repo. The finder allows to specify multiple patterns.
Windows and Linux can be handled using separate patterns if needed.

I did not manage yet to test without building a distro package. Still not sure how to do core development with Visual Studio Code.

For now, it is without caching and background scanning. getSuggestedAddons should finish quickly, so for now no need to extend this.

@holgerfriedrich holgerfriedrich changed the title [WIP] Service to suggest addons based on running processes Service to suggest addons based on running processes Dec 9, 2023
@holgerfriedrich
Copy link
Member Author

holgerfriedrich commented Dec 9, 2023

Both this PR and PR in addons repo ready for review.

The UI (add-on store) shows suggestions only for bindings. The wizard picks up all suggested add-ons.

@mherwege
Copy link
Contributor

The UI (add-on store) shows suggestions only for bindings.

PR openhab/openhab-webui#2213 created to solve this.

@@ -83,6 +83,12 @@
<feature dependency="true">openhab.tp-jmdns</feature>
</feature>

<feature name="openhab-core-config-discovery-addon-process" version="${project.version}">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you add this feature to openhab-runtime-base you will not need to add this finder to the constants in AddonFinderConstants.java. The feature will then automatically get installed and not through the service. The only reason to do it through the service is to allow enabling/disabling.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think someone did already ask to have enabling/disabling. ??

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me, that's conditional. If retrieving the processes is too high a load, we should. Otherwise I don't see the point. Right now, the implementation does not cache anything and does a call to retrieve the processes any time the suggestions are retrieved. If that is quick, no need to enable/disable a little piece of code. There is nothing running in the background in separate threads either.
@kaikreuzer Did not react on my feedback on it. If he feels strongly, then, of course it needs to be there, but it should also be added to the configuration parameters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mherwege I am OK with that.

Copy link
Member Author

@holgerfriedrich holgerfriedrich Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done as suggested, just did the verification - still works


private static final String COMMAND = "command";

public static final String SERVICE_TYPE = SERVICE_TYPE_PROCESS;
Copy link
Contributor

@mherwege mherwege Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can eliminate these constants from AddonFinderConstants.java and define them here instead with the same logic. Only refer to ADDON_SUGGESTION_FINDER in AddonFinderConstants.java.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...but I had to make ADDON_SUGGESTION_FINDER public...

@mherwege
Copy link
Contributor

LGTM

@andrewfg
Copy link
Contributor

@holgerfriedrich just for the avoidance of doubt: di you adapt to the new addon.xml schema?
@kaikreuzer / @mherwege I would suggest to wait until after those new addon.xml schema PRs have been merged.

@mherwege
Copy link
Contributor

mherwege commented Dec 15, 2023

@holgerfriedrich just for the avoidance of doubt: di you adapt to the new addon.xml schema? @kaikreuzer / @mherwege I would suggest to wait until after those new addon.xml schema PRs have been merged.

There is no impact of the new format for this PR. There are no discovery parameters. So no reason to wait if a maintainer agrees.

@andrewfg
Copy link
Contributor

There are no discovery parameters.

@holgerfriedrich the whole point of the revised schema is because you mis-used the match-properties as if they would be discovery-parameters. Therefore you need to change your mis-used properties to parameters instead.

@mherwege for info..

@mherwege
Copy link
Contributor

@andrewfg I think you confuse this PR with this one: #3920

The other one is the one I made the change for, and is not yet ready.

@andrewfg
Copy link
Contributor

The other one is the one I made the change for

Oops! Sorry.

Copy link
Member

@kaikreuzer kaikreuzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks!

…in/java/org/openhab/core/config/discovery/addon/process/ProcessAddonFinder.java

Signed-off-by: Kai Kreuzer <[email protected]>
@kaikreuzer kaikreuzer merged commit 4e634c6 into openhab:main Dec 16, 2023
2 of 3 checks passed
@kaikreuzer kaikreuzer added the enhancement An enhancement or new feature of the Core label Dec 16, 2023
@kaikreuzer kaikreuzer added this to the 4.1 milestone Dec 16, 2023
@holgerfriedrich holgerfriedrich deleted the pr-finder-process branch December 16, 2023 10:41
@kaikreuzer
Copy link
Member

@holgerfriedrich I just tried the latest distro snapshot (3787) and see this log during startup:

15:00:02.417 [WARN ] [ternal.xml.AddonInfoAddonsXmlProvider] - File 'openhab-addons.xml' has invalid content

Any idea why this happens?

@kaikreuzer
Copy link
Member

Hm, I have an idea: My version of the file is from Dec 10, i.e. it wasn't overwritten during the update. We will need to fix this, but it isn't relevant for the milestone release as the file didn't exist in the previous milestone.

@holgerfriedrich
Copy link
Member Author

holgerfriedrich commented Dec 17, 2023

@holgerfriedrich I just tried the latest distro snapshot (3787) and see this log during startup:

15:00:02.417 [WARN ] [ternal.xml.AddonInfoAddonsXmlProvider] - File 'openhab-addons.xml' has invalid content

Any idea why this happens?

@kaikreuzer this happened before when the schema was adapted. I think we have to improve logging in the addon info provider.

Hm, I have an idea: My version of the file is from Dec 10, i.e. it wasn't overwritten during the update. We will need to fix this, but it isn't relevant for the milestone release as the file didn't exist in the previous milestone.

This is good. In case of parser failure, all of the suggestions finders won't work.

May it be a problem for users of the daily snapshots? - then we should create a new issue....

@andrewfg
Copy link
Contributor

andrewfg commented Dec 17, 2023

Any idea why this happens?

@holgerfriedrich / @kaikreuzer / @mherwege - we changed the schema between two snapshots; so perhaps the new snapshot failed (correctly) to parse an addons.xml file from a prior snapshot based on the prior schema. Therefore I think that in the final build this will probably have all reconciled again. => But please do check before the final final release!

@andrewfg
Copy link
Contributor

andrewfg commented Dec 17, 2023

I think we have to improve logging in the addon info provider.

A few things..

  1. I did already improve the logging so that each entry has its regex validated when the individual binding entries are initialized.
  2. Your problem above is that the whole file is read in one go before the individual entries are validated, and as you say any single bad entry will kill the whole load.
  3. The good news is that -- if the new schema is on the server -- the add-ons CI build will check each add-on individually and fail specifically for that add-on.

So I think that once everything has synchronized between the build processes of openhab-core and openhab-addons then the problem should have been resolved..

@mherwege
Copy link
Contributor

Hm, I have an idea: My version of the file is from Dec 10, i.e. it wasn't overwritten during the update. We will need to fix this, but it isn't relevant for the milestone release as the file didn't exist in the previous milestone.

The file is in the userdata folder. Does it get deleted and recreated with an upgrade? If not we need to make sure this is done?

@kaikreuzer
Copy link
Member

As mentioned above: "it wasn't overwritten during the update." So yes, it is an issue for anyone using snapshot updates and it will be a problem in future for anyone else. So we need to fix this.

@mherwege
Copy link
Contributor

I don’t know how the installation and upgrades work exactly. @J-N-K can you help with this? Is it something to be done in the distro? Should the file go somewhere else to be removed and recreated in an upgrade? The code in core only takes care of reading the file that is there.

@andrewfg
Copy link
Contributor

For the avoidance of doubt..

  • If it is a clean (over-write) install then surely any pre-existing openhab-addos.xml will be overwritten by the contents of the openhab-4.1.0-SNAPSHOT.zip
  • If it is an upgrade (incremental) install via a script e.g. via openHabian then I guess the script can decide which files to overwrite and which not

What other scenarios are we dealing with than the above?

@mherwege
Copy link
Contributor

mherwege commented Dec 17, 2023

This file should always be overwritten, as it will contain the latest info when upgrading.

The issue is here: https://github.com/openhab/openhab-distro/blob/3721abe2ed8ec20134db021e33ef3fc5d6c3164d/features/distro/src/main/feature/feature.xml#L13

override should be true to force an overwrite.

I am not behind a computer now, so tough to create a PR, but it should be done to correct this.

@J-N-K
Copy link
Member

J-N-K commented Dec 17, 2023

I guess there are several solutions:

  1. Adapt the update script, so the file get's deleted on upgrade (add an additional line after l. 323 / l. 744
  2. Change the file location to userdata/etc and add it to userdata_sysfiles.lst
  3. Change the file location to userdata/cache

I would probably vote for the last one, then it SHOULD be recreated when you clear the cache (which especially for snapshots might be an issue otherwise).

@J-N-K
Copy link
Member

J-N-K commented Dec 17, 2023

Or (even better) do it like @mherwege suggests.

@andrewfg
Copy link
Contributor

andrewfg commented Jan 22, 2024

@holgerfriedrich I have a couple of (admittedly very late) questions concerning this finder resp. PR..

  1. Does it work on all Operating Systems i.e. MacOS, Windows, Linux, resp. other Unix platforms?
  2. Does it detect all types of process i.e. both regular executables and also services?
  3. Does it detect scripts being run by script processor application e.g. something like python running the script.py script?

@holgerfriedrich
Copy link
Member Author

holgerfriedrich commented Jan 22, 2024

@andrewfg I use Java to obtain a list of processes, see https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/ProcessHandle.html#allProcesses()
The output is different on Linux and Windows. getProcessCommandProcess() was introduced to harmonize the output on different OS. Windows will return empty entries for some processes. May be due to user permissions.

I tested with Linux and Windows. The trace output which dumps the process list got removed in one of the last commits.
logger.trace("Processes visible: {}", processList.toString()); - maybe you want to add it and see.

@andrewfg
Copy link
Contributor

andrewfg commented Jan 22, 2024

So to answer (some of) my own questions:

  1. At least on Linux the finder DOES identify processes that were started as a service. See log listings below. HOWEVER in such cases the command parameter is 'null', and the arguments[0] parameter can be irrelevant (the important information may be in arguments[n] where 'n' may vary from case to case). => Therefore the current version of this finder service is NOT able to suggest addons based on running services.
  2. At least on Linux the finder DOES identify processes for scripts that are being run by a script execution application (see the Python example in the list below). However the current version of this finder service is NOT able to suggest addons based on running script services.
command:null, arguments:[], commandLine:/lib/systemd/systemd-journald 
command:null, arguments:[-c, /etc/mosquitto/mosquitto.conf], commandLine:/usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf 
command:null, arguments:[-n, -iNONE], commandLine:/usr/sbin/rsyslogd -n -iNONE 
command:null, arguments:[-u, /home/openhabian/grott/grott.py], commandLine:/usr/bin/python3 -u /home/openhabian/grott/grott.py 
command:null, arguments:[/dev/serial1, bcm43xx, 3000000, flow, -], commandLine:/usr/bin/hciattach /dev/serial1 bcm43xx 3000000 flow - 
command:null, arguments:[], commandLine:/usr/libexec/bluetooth/bluetoothd 
command:null, arguments:[-w, -q], commandLine:/usr/sbin/dhcpcd -w -q 

Therefore I will shortly create a new PR to improve this finder so that it can discover addons that depend on running services and/or scripts..

@holgerfriedrich
Copy link
Member Author

@andrewfg Ok, for sure this is not working with script processors. Until now, only the main executable can be matched.

Are you going to add a new match property for arguments or do you want to extend the command to the full command line? For the latter one we would have to change existing descriptions for example from <regex>(?i).*[/\\](knxd)(\.exe)?$</regex> to <regex>(?i).*[/\\](knxd)(\.exe)?( .*)$</regex> (which might lead to false positives in case of similar directory names pointing to the executable)? Or are you thinking of a different approach?

@andrewfg
Copy link
Contributor

I am thinking of keeping the existing property command as it is. And adding a second property commandLine. That should avoid breaking anything existing.

NEVERTHELESS I note that your existing code may take arguments[0] as a fallback if command is null. However from my tests on Linux, it seems to me that arguments[-1] (which doesn’t actually exist) would be the proper fallback for command. => So can you please tell me on what platform / test case did you find that arguments[0] would be the equivalent of command?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An enhancement or new feature of the Core
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants