Im trying to get the versions of all my running docker containers within openhab so i can display them and write a update list on my MainUI.
Its very easy to get the latest github versions available but i stuck on get the local informations but i guess im close, just dont know how to finish it with openhab.
What I tried so far:
enable the docker unix socket to access docker with curl (added â/var/run/docker.sock:/var/run/docker.sockâ to volumes)
did some tests with command line and am able to receive a very long json string with e.g.
First Iâll say that OH doesnât really do well with lists of data. Itâs going to take a bit of work to actually display this information in a meanginful manner. Itâs not impossible but it is going to be a good bit of work. In the long run youâll almost certainly be happier with a special purpose tool for monitoring your IT infrastructure.
Beyond that, since itâs JSON you can probably just use a JSONPATH thransform chained to a REGEX.
I see. Didnât expected that. Because within zigbee2mqtt things the json path is common.
So with this variant itâs best to use exec binding or better executeCommandLine or even JavaScript? Saw many options online but I hate these as I had always trouble with them.
Alternatively I have portainer which can be used over http. I was not able to set it up so far but looks much easier than the command line option. Just the access token is only valid for 8 hours but even receive a new one should be possible with a ruleâŠ
By special purpose tool I mean something like Watchtower, Zabbix, Portainer, etc. OH really isnât designed to be an IT monitoring system and therefore it does a relatively poor job of it. A service special built for IT monitoring is almost always going to be less work and work better than OH for this task.
The issue isnât extracting the data from the JSON or getting the data into OH. Thatâs easy and I provided the transformation you need above to get it straight from Docker using that curl command.
Displaying it in MainUI in a meaningful way is going to take a good bit of work though. Thatâs where the work is going to come in.
Ah, now I understand what you mean. In the first step I dont want something fancy. Ah list of running and available versions would be great.
Next step I would write a java script which checks the version numbers, should also be not too heavy as soon as I have the required informations. Then its easy to visualize an switch item which tells me the container is up to date or not. When i group the switch items of all countainers I have an counter which tells me how many updates are available.
So after the portainer api is too complex for me to use i went back to my good old âfriendâ exec binding.
I tried to copy the example from the documentation without input argument to keep it simple. The command is executing but I get an empty response. I already added the command to the whitelist and i see no errors in the log.
Any hint what IÂŽm missing?
rule "begin your execution"
when
Item DebugSwitch received command
then
// Separately triggering RUN allows subsequent executions with unchanged parameter %2
// which autorun does not.
if (yourcommand_Run.state != ON) {
yourcommand_Run.sendCommand(ON)
// the Run indicator state will go ON shortly, and return OFF when script finished
}else{
logInfo("Your command exec", "Script already in use, skipping execution.")
}
end
rule "script complete"
when
Item yourcommand_Run changed from ON to OFF
then
// Logging of ending
logInfo("Your command exec", "Script has completed.")
// Caution : openHAB bus is asynchronous
// there is no guarantee the output Item will get updated before the run channel triggers rules
end
rule "process your results"
when
Item yourcommand_Out received update
then
// Logging of raw command line result
logInfo("Your command exec", "Raw result:" + yourcommand_Out.state )
// If the returned string is just a number it can be parsed
// If not, a regex or another transformation could be used
YourText.postUpdate(yourcommand_Out.state.toString)
end
Output in log:
[INFO ] [.core.model.script.Your command exec] - Script has completed.
[INFO ] [.core.model.script.Your command exec] - Raw result:
there shoul be a big block of json code coming out of the command like when I execute direct in the terminal.
You are outside of OH at that point. If the script is returning nothing then thatâs what OH is going to get and process. You need to debug why the script is returning nothing. curl is probably throwing an error and because it has the silent flag itâs not returning anything.
The exit Channel has the return code from the ran script. If thatâs not 0 that will tell you that the command is failing.
Donât forget that the commands are running as user openhab so itâs that user that needs permissions on all the resources used by the script.
Ok so i added the exit code and removed the silent flag and the error is âcould not connect to serverâ. Thats the point where i hate to use exec binding as I dont understand the further steps. User is already openhab which i tested with command âwhoamiâ also with the exec binding.
Anyway i found that its not recommended to expose the docker socket as it contains some risk
@binderth thats awesome! i run node-red anyway for mqtt usage of my bambu lab printer within openhab. I found 2 tokens for portainer, one to be configured within the web interface and one that can be requested by terminal but has to be refreshed every 8 hours. Which one is used with your node-red?
If the openhab user doesnât have permission to read the socket itâs never going to work. Usually you can add the openhab user to the docker group but youâll have to check the permissions on the socket file to know for sure.
the 8hours (configurable) refer to how long the session cookie lives. If you follow the API documentation, you create a API Access token, which lives âforeverâ so to say:
I never worked with node-red myself so far but I was able to make your flow going to work. Only issue that i found was that i have some containers without health check value. In result of that i changed the node function which grabs this to not cause an error (else all other values form this node are missing ether):
// ensure values are available
let state = (msg.payload && msg.payload.State) ? msg.payload.State : {};
let health = (state && state.Health) ? state.Health : {};
let config = (msg.payload && msg.payload.Config) ? msg.payload.Config : {};
// return result if available
return [
{ payload: state.Running || "N/A" },
{ payload: state.Status || "N/A" },
{ payload: health.Status || "N/A" },
{ payload: state.StartedAt || "N/A" },
{ payload: config.Image || "N/A" }
];
A question how to proceed. As I want to extract all containers versions i could start a different http request with the containers name. I already was able to get the version of that container but this is very static.
But as you loop all available containers anyway i guess its possible to expose a dynamic list of containers and their version. Could you give me a rough idea how to do this?
EDIT:
I managed to extract a list of running containers but the question is how i can send http requests for all of them and process the result to extract the version number.
@rlkoshak you are right, from the containers terminal i get root as active user so i would have to figure out how to make the exec command work but I hope i can go with the node-red variant because it looks like much more versatile and dynamic then my anyway not recommended docker socket variant. But anyway great thanks for your fast support!
That way I do get the âONâ-state for all ârunningâ containers and can display them along with the statuses just like that.
If youâd like to compare versions, youâll have to include those information in the node-red node also. the version is always here: [i].Labels.['com.docker.compose.version']. You wonât need another call for that.
I practiced a bit with node-exporter and finally got this solution where i get name, state and version over mqtt. If someone is interested i can figure out how to export the required data.
I let your stuff inside in case i need further informations for copy&paste but for now i cut all after the first http request as i dont need the other data at the moment