Problem with cont-init.d script - unable to locate package

  • Platform information:
    • Hardware:
    • OS: Linux (openmediavault)
    • openHAB version: 4.0.2 in a docker container
  • Issue of the topic:

In principle I like to install the below software. When executing these 3 lines in the terminal after accessing the openHAB docker, it works properly.

curl -sL https://deb.nodesource.com/setup_lts.x | bash -
apt-get install -y nodejs # Berechtigungen fehlen
npm install -g --prefix /openhab/conf/automation/js ical2json

At the beginning I tried to create a script and run this within openHAB by “executeCommandLine”. I didn´t find a solution to get it working as the openhab user which runs the script misses the privileges to install the packages and sudo isn´t available in docker.

While investigating I found the possibility to run a script while the docker container gets started by putting it into /etc/cont-init.d. This I got up and running in the meanwhile for executing setup_lts.x. It didn´t work by the line above as the log tolled that “bash -” is not known. But I got it working by the following lines:

#!/bin/bash
wget -O - https://deb.nodesource.com/setup_lts.x > /openhab/setup_lts.sh
bash /openhab/setup_lts.sh

But now it fails with installing nodejs when extending the script as follows:

#!/bin/bash
wget -O - https://deb.nodesource.com/setup_lts.x > /openhab/setup_lts.sh
bash /openhab/setup_lts.sh
apt-get install -y nodejs

It tells that it is unable to locate the package. I also tried running apt-get update or apt-get upgrade before, but both didn´t help.

First, why do you need to run these from inside the container? /openhab/conf should be mounted as a volume anyway so you can run the npm from the host. Then you don’t need to reinstall the library every single time you start up a new container. Nodejs is also pretty big and you don’t really need it inside the container, especially if all you need is npm. Images are intended to be lean and small as possible.

Another better approach than running a script every time the container starts would be to build your own Docker image based on the openHAB official image with nodejs and npm installed. That is the more typical and standard way to create an Image with additional software installed.

But again, you don’t need these inside the container. You can used these on the host.

I cannot explain why it didn’t work using /etc/cont-init.d. I know an apt update would be required before you can install, but you said you tried that. I also know that there could be differences between the two architectures. The is a debian based image and an alpine based image. You’ve not indicated which you are using. Debian is the default.

Dear Rich,

I already read a lot from you in other threads. I´m glad that you support me!

My actual target is visualizing calendar entries (date + text) on HABPanel. In this calendar I make entries for maintenance task, e.g. when I cleaned the ventilation outlets, replaced the filter from the cistern, oiled the parket, repainted the wall and so and and so force.

This task I could realize by importing the calendar as ical from my Nextcloud, converting it to json and reading that in Grafana. Grafana puts the entries in a table which I show on a HABPanel page.

rule "Convert the maintenance calendar from ical in json for visualization in Grafana"
    when 
        Time cron "0 0 0 * * ?" or
        Time cron "0 0 12 * * ?"
    then
        // 1. Import calendar as ical from Nextcloud
            var String ics = executeCommandLine(Duration.ofSeconds(10), "curl", "-s", "https://.../remote.php/dav/calendars/openHAB/wartung?export", "-u", "username:password")
            //logInfo ("ics-String", ics)

        // 2. Remove ";" and "=" from "VALUE=DATE" date so that it shows it properly in Grafana
            ics = ics.replace(";VALUE=DATE", "")

        // 3. Save ical in file
            var String response_speichern = executeCommandLine(Duration.ofSeconds(1), "bash", "/openhab/conf/scripts/write_to_file_ics.sh", ics)
            //logInfo ("ics-String speichern", response_speichern)
        
        // 4. Convert ical to json konvertieren  
            var String responce_ics2json = executeCommandLine(Duration.ofSeconds(1), "ical2json", "/openhab/userdata/cache/wartung.ics")
            //logInfo ("ics in json konvertieren", responce_ics2json)

        // 5. Upload file to Nextcloud, from there it gets loaded by Grafana             
            var String response_upload = executeCommandLine(Duration.ofSeconds(5), "curl", "-u", "username:password", "--upload-file", "/openhab/userdata/cache/wartung.json" ,"https://.../remote.php/dav/files/openHAB/wartung.json")
            //logInfo ("json-String upload", response_upload)
end

The above works very well for about a year and satisfies my needs. The whole thing requires the little tool ical2json which I found in the internet (GitHub - adrianlee44/ical2json: A simple node package to convert ical data to json). As stated on its GitHub page, it can be installed by “npm install -g ical2json”. However, by trying it out, it told me that npm is not available. Following to that I found “curl -sL https://deb.nodesource.com/setup_lts.x | bash -” and “apt-get install -y nodejs” to resolve this issue.

Honestly I don´t always exactly know what I´m doing. I have a target and try to resolve it in which I typically succeed sooner or later :slight_smile:.

Coming to an end with this introduction, I could solve the task by installing ical2json with following lines in the docker container:

docker exec -it openHAB3.4 bash
curl -sL https://deb.nodesource.com/setup_lts.x | bash -
apt-get install -y nodejs
cd /openhab/conf/automation/js
npm install -g ical2json

The only drawback of the whole thing is, that I have to reinstall the above packages after re-creating the docker container. Although this is not a big deal as I update openHAB only once or twice per year, I thought now about trying to automize it after I recently forgot to re-install it after upgrading to 4.0.

I hoped that I could just paste the above lines in the cont-init.d script, except of the docker exec line of course. But it already failed with installing setup_lts.x. Even more I was happy after I could resolve this challenge by the following adaptation:

wget -O - https://deb.nodesource.com/setup_lts.x > /openhab/setup_lts.sh
bash /openhab/setup_lts.sh

But as mentioned, now I struggle with installing nodejs (or npm) which I need for finally installing ical2json.

To answer your questions:

  • I pull the docker image by “openhab/openhab:latest”. Therefore I assume I have the default Debian version. I think that confirms it:
    image
  • I tried to install “npm install -g ical2json” in the folder /openhab/conf/automation/js outside docker on the base system according your recommendation. But also here I get the failure message that npm is missing.
  • How to build my own docker image I don´t know. I haven´t digged into that. I would like to keep it simple and stay with using the standard version available.
  • As stated, I tried to run apt-get update and apt-get uprade before installing nodejs. But that didn´t help. This time I was able to cache the log about it. Actually this is quite tricky. It looks to me that the script gets re-started over and over when it fails and the start of the container stucks at this position. Can this never-ending restarting of the script be somehow avoided? Especially for trouble-shooting it is a drawback as it masses up the log.
    image

By the way, I operate another container (Nextcloud) by which I simply can install additional packages by defining an ENV variable:

As far as I found, something like that is not possible with the openHAB docker, or?

That’s why I question this whole approach.

I have several npm libraries I use for rules. I installed nodejs and npm on the host, not in the container. I ran npm install from the folder that is mounted into the openHAB container to conf. I never have to touch what’s installed in the container and the files it installs lives in my conf folder so it persists even if the container changes.

Ultimately this is an XY Problem. You can fight the problem but your time and effort would be better spent solving the problem in a more standard way.

Well, yea. You need to install nodejs to the host before you’ll have npm available. But all you need to do is run those commands you have successfully run from inside the container on the host instead.

Nextcloud does what nextcloud does. What they provide is not a universal approach implemented by many, let alone all docker containers.

I did this now and run of course also the line for installing ical2json.

But it doesn´t work, neither just with ical2json nor with the absolute path:

2023-08-30 07:45:29.690 [WARN ] [rg.openhab.core.io.net.exec.ExecUtil] - Failed to execute commandLine '[ical2json, /openhab/userdata/cache/wartung.ics]'

2023-08-30 07:44:53.943 [WARN ] [rg.openhab.core.io.net.exec.ExecUtil] - Failed to execute commandLine '[/openhab/conf/automation/js/bin/ical2json, /openhab/userdata/cache/wartung.ics]'

When I run the command in the docker terminal, it tells that the command is not found when just using ical2json. When using the absolute path, it tells permission denied:

By deleting the ical2json file and reinstalling it again, I found that the files are installed in the folder /usr/bin of the host :roll_eyes:.

The ical2json files in /openhab/conf/automation/js/ were left-over from the installation in docker.

A file like this as /cont-init.d/20-install-ical2json seems to work:

#!/bin/bash

if ! which npm >/dev/null; then
    echo "Installing Node.js"
    curl -sL https://deb.nodesource.com/setup_lts.x | bash -
    apt-get install -y nodejs
else
    echo "Node.js is already installed"
fi

if [ ! -e "${OPENHAB_CONF}/automation/js/bin/ical2json" ]; then
    echo "Installing ical2json"
    su openhab -c "npm install -g --prefix ${OPENHAB_CONF}/automation/js ical2json"
else
    echo "ical2json is already installed"
fi

Something seems to be different on my side.

When I just copy and paste it 1:1, it complains about the empty line:
image

When I remove those, another error message appears:

image

Maybe try Unix line endings instead of Windows line endings? :slight_smile:

Oh my god. Thanks for pointing that out! The whole problem just because I created and adapted the file in Windows and not in the terminal. Sorry for that! I wasn´t aware that this makes a difference.

It just works fantastic now. I only had to change the line for installing ical2json so that it finally worked. I believe the folder defined with --prefix caused the issue.

su openhab -c "npm install -g --prefix ${OPENHAB_CONF}/automation/js ical2json"
npm install -g ical2json

Again, thanks a lot for both of your support Rich and Wouter!

1 Like