openHAB reference setup for macOS (installation path, privileges, autostart …)

My Goal is to build an openHAB installation on my Mac that is auto-starting, conformant with Mac best practice and secure!

  • What is the standard / best-practice directory path to place applications into on macOS systems ? (e. g. /opt/openHAB, dedicated project folder from root, e. g. /smarthome/openHAB etc.)?
  • What are the standard/best-practice security settings to operate openHAB on a Mac? Preferably I want to run openHAB with as tight security and least privileges as possible and not go with root rights or via sudo. Is it a good idea to create a dedicated user account that is reserved for running openHAB? Do I have to apply specific rights to the openHAB directory folder?
  • Instead of opening openHAB manually each time when I have booted the Mac (and leaving a terminal window open) I would like to start it automatically (as a service?).
    Discussions have started, yet not concluded to a solution:
    OpenHAB in Service Wrapper runs when ran manually, not in launchd on Mac OS X High Sierra

If in general interest, probably some of the answers to the questions above could be included in the setup documentation in the Mac section?

Thank you!

Platform information:
* Hardware: Apple Mac mini (end 2012), i7 2,6GHz, 16 GB RAM
* OS: macOS Catalina (10.15.2)
* Java Runtime Environment: openjdk version "1.8.0_192“, OpenJDK Runtime Environment (Zulu 8.33.0.1-macosx) (build 1.8.0_192-b01)
* openHAB version: 2.5 M4

The latest Testing version is Release Candidate 1. 2.5 Stable will be released on December 15.

Thank you! I actually tried RC1, but had trouble with huge CPU load on JAVA process and things (Z-WAVE) losing connection. So I reverted to M4 for now,.

Is your Java 8 up to date? Some had issues with old Java.

You best bet to answer this is on a Mac forum. It’s BSD based which shares a lot in common with Debian Linux but some quick looking showed no mention of /opt/ for BSD so I don’t know what the best place. Ultimately it probably doesn’t matter all that much. I’d use /opt out of habit.

Same as Linux. Create a system user with no shell. Obviously, the openhab users will need read/write permissions on all of it’s files.

Well, if that thread didn’t get any answers or replies I’m not sure reposting the same question is going to give you any additional information. Your best bet is to ask on a Mac forum for how to start a Java process as a service on a Mac. Only a tiny minority of OH users run OH on a Mac so there isn’t a lot of people to provide support.

There is a link at the bottom of the page that will take to straight to the page where you can make modifications and submit a PR.

1 Like

Thank you! I appreciate your help - will try that out!

Many people have found bad addon entries in addons.cfg or `addons.config1 file can cause addons to reload every minute.

Well, it was a long slog but I finally put bits and pieces together the allow running openHAB as a service on Mac Catalina (10.15.2) on my mac mini. I put this together from several posts from stackoverflow, here, and elsewhere.

This deserves a better explanation and more step-by-step instructions, but until I’m convinced there’s more than two of us trying to do this I am not going to invest the time.

There are three things I needed to do to be successful:

  1. configure the openhab folder to a good place and with the right permissions so that it can be run as a daemon on Mac
  2. Generate the install-service in openhab, and then fix the bugs in it
  3. Add user and group to the launchd openHAB.plist and launch it.

Details of the specific steps I used: (Note that steps 1-3 and step 6 are recommended, but not required. Otherwise the daemon will run as root, which is not a good practice but which will certainly work)

  1. Create an _openhab non-login user and group to run the service. This is beyond the scope of this article, but this serverfault article has a good treatment and a script you can modify to create it.
  2. Download openhab (I used 2.5.1) and extract the openhab-2 folder
  3. move the openhab-2 folder to /opt/openhab
  4. change owner of the openhab folder

sudo chown -R _openhab:_openhab /opt/openhab

  1. Run openhab in terminal

sudo /opt/openhab/start.sh

  1. When you get the openhab prompt, then type install-service to generate the service wrapper files, and then logout to stop openhab.
  2. Edit the generated /opt/openhab/runtime/bin/openHAB.plist and add these two entries near the bottom of the file, just above the </dict> line:
    <key>UserName</key>
    <string>_openhab</string>
    <key>GroupName</key>
    <string>_openhab</string>
  3. Use the commands printed by install-service to move the openHAB.plist to /Library/LaunchDaemons and update permissions as mentioned in the output from the install-service command. Don’t try to start it yet.
  4. fix the faulty output from the openhab:install-service command with the next several lines
  5. Run /usr/libexec/java_home -v1.8 and copy the resulting directory. For me it’s

/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home

  1. open /opt/openhab/runtime/bin/openhab-service in a text editor (I used BBEdit, TextEdit is not a good choice). Edit the first (non-comment) line so that it has the correct JAVA_HOME and then save the file, e.g.

JAVA_HOME="/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home"

  1. open /opt/openhab/userdata/etc/openHAB-wrapper.conf and update this line (note that there’s no quotes this time):

set.default.JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home

  1. Also in that same file, fix three references to KARAF_BASE that should be KARAF_HOME:

wrapper.java.classpath.1=%KARAF_HOME%/lib/boot/*.jar
wrapper.java.classpath.2=%KARAF_HOME%/lib/wrapper/*.jar
wrapper.java.library.path.1=%KARAF_HOME%/lib/wrapper/

  1. Make sure both files are saved
  2. you’re now done working around openhab:install-service bugs
  3. Use launchctl start openHAB to start the service and try to log in.

If you have problems try setting wrapper.console.loglevel=DEBUG in /opt/openhab/userdata/etc/openHAB-wrapper.conf and try starting it again. The /opt/openhab/userdata/logs/wrapper.log file may have useful info in it then.

Also, LaunchControl is an excellent tool for debugging, working with, and visualizing LaunchDaemons and LaunchAgents.

5 Likes

Thanks for this! Trying to do the same thing. I’m sure a lot of Mac users are interested.

I followed your guidelines, but nothing happens. No entries in wrapper.log. LaunchControl suggests it might be a permissions problem. Did you only chmod the directory /opt/openhab or also all files and subdirectory within?

Sorry, you are right. I edited the post - I left off the -R on the chown command. I suspect your openhab user doesn’t have access to the files in runtime/bin it need to launch.

1 Like

@robwbartel, I had no luck installing the service under a system user, like you did. In the end I did manage to install it under LaunchDaemons without the addition to the plist file in step 6. Openhab runs as a daemon now, as root I guess. Not ideal. Basically I followed your steps except for steps 1,2,3 and 6.

Did you report the bugs you found (steps 9-13)?

Would make optional steps 1-3 and 6 a good addition to the installation documentation?

What you did should certainly work, the reason I created the _openhab user was to avoid running the daemon process as root. You are correct that without line 6 the default is root.

The bugs in 9-13 were reported quite some time ago https://github.com/openhab/openhab-distro/issues/401, and as I read the response the openHAB team said it’s in Karaf and not easy to fix. “Run on Linux” seems to be the general feeling.

I edited the post to mention that the _openhab user is optional step.

1 Like

Thank you for your instructions. I tried to apply them on openhab-3.1.0.M2 on my macMini running Mojave.
Java 11 is installed:

$ /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home

I had do fix another line in openHAB-wrapper.conf, so that it looks as follows for me:

# Java Application
wrapper.working.dir=%KARAF_BASE%
wrapper.java.command=%JAVA_HOME%/bin/java
wrapper.java.mainclass=org.apache.karaf.wrapper.internal.service.Main
wrapper.java.classpath.1=%KARAF_HOME%/lib/boot/*.jar
wrapper.java.classpath.2=%KARAF_HOME%/lib/jdk9plus/*.jar
wrapper.java.classpath.3=%KARAF_HOME%/lib/wrapper/*.jar
wrapper.java.library.path.1=%KARAF_HOME%/lib/wrapper/

Unfortunately it does not work and I have no idea where to search for the root cause.
The launch daemon fails with following error message:

Running openHAB runtime...
wrapper  | --> Wrapper Started as Console
wrapper  | Launching a JVM...
wrapper  | JVM exited while loading the application.
jvm 1    | NOTE: Picked up JDK_JAVA_OPTIONS: --add-reads=java.xml=java.logging --add-exports=java.base/org.apache.karaf.specs.locator=java.xml,ALL-UNNAMED --patch-module java.base=lib/endorsed/org.apache.karaf.specs.locator-4.2.7.jar --patch-module java.xml=lib/endorsed/org.apache.karaf.specs.java.xml-4.2.7.jar --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.naming/javax.naming.spi=ALL-UNNAMED --add-opens java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED --add-exports=java.base/sun.net.www.protocol.http=ALL-UNNAMED --add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED --add-exports=java.base/sun.net.www.protocol.jar=ALL-UNNAMED --add-exports=jdk.xml.dom/org.w3c.dom.html=ALL-UNNAMED --add-exports=jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED
jvm 1    | Error occurred during initialization of VM
jvm 1    | Cannot specify java.base more than once to --patch-module

... repeated 4 times ...

wrapper  | There were 5 failed launches in a row, each lasting less than 300 seconds.  Giving up.
wrapper  |   There may be a configuration problem: please check the logs.
wrapper  | <-- Wrapper Stopped

Obviously some Java config seems to be broken, but the error message is chinese for me.
Any hints what to check?

When starting openhab via the start-script (start.sh), it works from the same location.
I put everything into /usr/local/opt/openhab

sudo -u _openhab /usr/local/opt/openhab/start.sh

Is there a reason why not using “karaf daemon” on macosx?
On Linux this seems to be the proposed way of running OH3 as a system daemon.

This seems to be caused by the wrapper picking up the non-wrapper JDK args - if you look in openHAB-wrapper.conf file you’ll see a line starting set.JDK_JAVA_OPTIONS=, and it looks like much (all?) of what that specifies is repeated further down in the wrapper.java.additional._n_= lines. If you look at the wrapper output you’ve quoted you can see it’s telling you it picked up the JDK_JAVA_OPTIONS, and it’s then adding on the wrapper options, the net result being that the --patch-module lines occur twice. I’ve simply commented out the JDK_JAVA_OPTIONS line from my own config and it seems to work ok, but I’ll not swear to this being the correct answer.

I have been struggling to get openHAB started automatically on MacOS. Eventually, I got the plist working. But after a few minutes the server would stop. So here is another way to achieve this - although you make “sudo sh” work without having to put in the password:

  1. Run sudo visudo to open the sudoers file
  2. Add a line %admin ALL=(ALL) NOPASSWD: /bin/sh to give all users in the admin group password-less access to sudo sh
  3. Use Applescript:
tell application "Terminal" 
do script "sudo sh /path/openhab/start.sh"
set miniaturized of window 1 to true
end tell
  1. Save as a program.
  2. Put that program as an autostart application into the settings.

That will open a terminal and start openHAB inside of it when the system starts and minimize it so it won’t be in your way.