diff --git a/.travis.yml b/.travis.yml index 7ccfdcf53..019815f7b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: shell os: linux # using latest Ubuntu (not the travis-ci default) to get latest tool versions in Travis environment -#dist: bionic dist: focal cache: false @@ -19,25 +18,33 @@ git: services: - docker -install: ./test.bash travis +stages: + - BATS and Shellcheck tests + - openHABian installation tests + +install: + - ./test.bash travis jobs: fast_finish: true allow_failures: - - name: BATS and Shellcheck tests on virtual RPi4 + - stage: BATS and Shellcheck tests include: - - name: BATS and Shellcheck tests on virtual RPi4 + - stage: BATS and Shellcheck tests + name: BATS and Shellcheck tests on virtual RPi4 env: HW=rpi4 arch: arm64 script: # BATS tests on a 64bit rpi4 virtual platform, running in a 64bit OS on Travis Arm64 HW - docker build -t openhabian/bats-openhabian -f Dockerfile.raspberrypi4-64 . - echo -e "\n\e[36mopenHABian BATS tests running on a\e[31m 64bit OS\e[36m running in a virtual ${HW}...\e[0m\n" + - docker run --name "development-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "development-." .' - docker run --name "unit-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "unit-." .' - docker run --name "installation-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "installation-." .' - docker run --name "destructive-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "destructive-." .' - shellcheck -x -s bash openhabian-setup.sh functions/*.bash build-image/*.bash build.bash && echo "shellcheck - OK" - - name: openHABian installation test with 64bit Azul Java 8 on native amd64 + - stage: openHABian installation tests + name: openHABian installation test with 64bit Azul Java 8 on native amd64 env: HW=amd64 arch: amd64 script: @@ -57,14 +64,14 @@ jobs: - echo -e "\n\e[36mopenHABian test installation using 32bit Azul Embedded Java 8 running on a\e[31m 32bit OS\e[36m running in a virtual ${HW}...\e[0m\n" - docker run --memory="1g" --memory-reservation="1g" --name "openhabian-${HW}" -d openhabian/${HW}-openhabian - docker exec -i "openhabian-${HW}" bash -c './build.bash local-test && mv ~/.profile ~/.bash_profile && /etc/rc.local' - - name: openHABian installation test with 32bit Azul Java 8 on virtual RPi3 + - name: openHABian installation test with 32bit Azul Java 11 on virtual RPi3 env: HW=rpi3 arch: arm64 script: - # 32bit Azul Java 8 on a 64bit ARMv8 (RPi3) virtual platform, running in a 32bit OS on Travis Arm64 HW - - sed -i 's/^java_opt=.*$/java_opt=Zulu8-32/' build-image/openhabian.conf + # 32bit Azul Java 11 on a 64bit ARMv8 (RPi3) virtual platform, running in a 32bit OS on Travis Arm64 HW + - sed -i 's/^java_opt=.*$/java_opt=Zulu11-32/' build-image/openhabian.conf - docker build -t openhabian/${HW}-openhabian -f Dockerfile.raspberrypi3 . - - echo -e "\n\e[36mopenHABian test installation using 32bit Azul Embedded Java 8 running on a\e[31m 32bit OS\e[36m running in a virtual ${HW}...\e[0m\n" + - echo -e "\n\e[36mopenHABian test installation using 32bit Azul Embedded Java 11 running on a\e[31m 32bit OS\e[36m running in a virtual ${HW}...\e[0m\n" - docker run --memory="1g" --memory-reservation="1g" --name "openhabian-${HW}" -d openhabian/${HW}-openhabian; - docker exec -i "openhabian-${HW}" bash -c './build.bash local-test && mv ~/.profile ~/.bash_profile && /etc/rc.local' - name: openHABian installation test with 64bit Azul Java 8 on virtual RPi3 @@ -75,7 +82,7 @@ jobs: - sed -i 's/^java_opt=.*$/java_opt=Zulu8-64/' build-image/openhabian.conf - docker build -t openhabian/${HW}-openhabian -f Dockerfile.raspberrypi3-64 . - echo -e "\n\e[36mopenHABian test installation using 64bit Azul Embedded Java 8 running on a\e[31m 64bit OS\e[36m running in a virtual ${HW}...\e[0m\n" - - docker run --memory="2G" --memory-reservation="2G" --name "openhabian-${HW}" -d openhabian/${HW}-openhabian; + - docker run --memory="2g" --memory-reservation="2g" --name "openhabian-${HW}" -d openhabian/${HW}-openhabian; - docker exec -i "openhabian-${HW}" bash -c './build.bash local-test && mv ~/.profile ~/.bash_profile && /etc/rc.local' - name: openHABian installation test with AdoptOpenJDK Java 11 on virtual RPi2 env: HW=rpi2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0b8122986..85eb44999 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,52 +1,68 @@ -## Contribution Guidelines +# Contribution Guidelines -### Pull Requests are Always Welcome +## Pull requests are always welcome -We are always thrilled to receive pull requests, and do our best to process them as fast as possible. -Not sure if that typo is worth a pull request? Do it! We will appreciate it. +We are always thrilled to receive pull requests, and do our best to +process them as fast as possible. Not sure if that typo is worth a pull +request? Do it! We will appreciate it. If your pull request is not accepted on the first try, don't be discouraged! -If there's a problem with the implementation, you will receive feedback on what to improve. +If there's a problem with the implementation, you will receive feedback on what +to improve. -We might decide against incorporating a new feature that does not match the scope of this project. -Get in contact early in the development to propose your idea. +We might decide against incorporating a new feature that does not match the +scope of this project. Get in contact early in the development to propose your +idea. -### Making Workflow Changes +## Conventions -Fork the repository and make changes on your fork in a feature branch. +Fork the repo and make changes on your fork in a feature branch. Then be sure to +update the documentation when creating or modifying features. Test your changes +for clarity, concision, and correctness, as well as a clean documentation build. -Update the documentation when creating or modifying features. -Test your changes for clarity, concision, and correctness, as well as a clean documentation build. +Always write clean, modular and testable code. We have a simple +[code-style](#codestyle) which in combination with the static linter +[Shellcheck](https://www.shellcheck.net/) works as our coding guidelines. -Write clean, modular and testable code. -We have a codestyle which in combination with the static linter Shellcheck works as guidelines. - -Pull requests descriptions should be as clear as possible and include a reference to all the issues that they address. +Pull requests descriptions should be as clear as possible and include a +reference to all the issues that they address. Pull requests must not contain commits from other users or branches. -Commit messages **must** start with a capitalized and short summary (max. 50 chars) written in the imperative, followed by an optional, more detailed explanatory text which is separated from the summary by an empty line. [See here for more details.](https://chris.beams.io/posts/git-commit) +Commit messages **must** start with a capitalized and short summary (max. 50 +chars) written in the imperative, followed by an optional, more detailed +explanatory text which is separated from the summary by an empty line. See +[here](https://chris.beams.io/posts/git-commit) for great explanation as to why. -Code review comments may be added to your pull request. -Discuss, then make the suggested modifications and push additional commits to your feature branch. -Be sure to post a comment after pushing. -The new commits will show up in the pull request automatically, but the reviewers will not be notified unless you comment. +Code review comments may be added to your pull request. Discuss, then make the +suggested modifications and push additional commits to your feature branch. Be +sure to post a comment after pushing. The new commits will show up in the pull +request automatically, but the reviewers will not be notified unless you +comment. Pull requests will be tested on the Travis CI platform which **shall** pass. -Please provide test-cases for new features. See [Test Architecture](#test-architecture) below. -Before the pull request is merged, your commits might get squashed, based on the size and style of your contribution. -Include documentation changes in the same pull request, so that a revert would remove all traces of the feature or fix. +Please provide test-cases for new features. See +[Test Architecture](#test-architecture) below. + +Commits that fix or close an issue should include a reference like `Closes #XXX` +or `Fixes #XXX`, which will automatically close the issue when merged. -Commits that fix or close a GitHub issue should include a reference like `Closes #XXX` or `Fixes #XXX`, which will automatically close the issue when merged. -### Sign-off your Work +Before the pull request is merged, your commits might get squashed, based on the +size and style of your contribution. Include documentation changes in the same +pull request, so that a revert would remove all traces of the feature or fix. -The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch. -If you can certify the below (from [developercertificate.org](https://developercertificate.org)): +### Sign your work +The sign-off is a simple line at the end of the explanation for the +patch, which certifies that you wrote it or otherwise have the right to +pass it on as an open-source patch. The rules are pretty simple: if you +can certify the below (from +[developercertificate.org](http://developercertificate.org/)): ``` -Developer Certificate of Origin Version 1.1 +Developer Certificate of Origin +Version 1.1 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 660 York Street, Suite 102, @@ -83,77 +99,64 @@ By making a contribution to this project, I certify that: this project or the open source license(s) involved. ``` -then you just add a line to the end of every git commit message: - +then you just add a line to every git commit message: ``` -Signed-off-by: Joe Smith (github: github_handle) +Signed-off-by: Joe Smith ``` -using your real name (sorry, no pseudonyms or anonymous contributions.) +using your real name (sorry, no pseudonyms or anonymous contributions.) and an +e-mail address under which you can be reached (sorry, no github noreply e-mail +addresses (such as username@users.noreply.github.com) or other non-reachable +addresses are allowed). -If your commit contains code from others as well, please ensure that they certify the DCO as well and add them with an "Also-By" line to your commit message: - -```text -Also-by: Ted Nerd (github: github_handle_ted) -Also-by: Sue Walker (github: github_handle_sue) -Signed-off-by: Joe Smith (github: github_handle_joe) -``` +#### Small patch exception -#### Small Patch Exception - -There are several exceptions to the sign-off requirement. -Currently these are: +There are several exceptions to the signing requirement. Currently these are: * Your patch fixes spelling or grammar errors. * Your patch is a single line change to documentation. -### Sign your Work using GPG +#### Sign your Work using GPG You can additionally sign your contribution using GPG. -Have a look at the [git documentation](https://git-scm.com/book/tr/v2/Git-Tools-Signing-Your-Work) for more details. -This step is optional and not needed for the acceptance of your pull request. +Have a look at the +[git documentation](https://git-scm.com/book/tr/v2/Git-Tools-Signing-Your-Work) +for more details. This step is optional and not needed for the acceptance of +your pull request. -#### Codestyle +## Codestyle Universally formatted code promotes ease of writing, reading, and maintenance. -## Community Guidelines - -We want to keep the openHAB community awesome, growing and collaborative. -We need your help to keep it that way. -To help with this we've come up with some general guidelines for the community as a whole: - -* **Be nice:** -Be courteous, respectful and polite to fellow community members: -no regional, racial, gender, or other abuse will be tolerated. -We like nice people way more than mean ones! +### Guidelines -* **Encourage diversity and participation:** -Make everyone in our community feel welcome, regardless of their background and the extent of their contributions. -Do everything possible to encourage participation in our community. - -* **Keep it legal:** -Basically, don't get us in trouble. -Share only content that you own, do not share private or sensitive information, and don't break the law. +* Use two (2) spaces when indenting code. -* **Stay on topic:** -Make sure that you are posting to the correct channel and avoid off-topic discussions. -Remember when you update an issue or respond to an email you are potentially sending notifications to a large number of people. -Please consider this before you update. -Also remember that nobody likes spam. +* `local` declarations of variables should be used when possible. Always + include declarations of variables at the beginning of functions. The only + exception allowed is for short circuit returns to avoid unnecessary checks. +* When using colored output, always use the colors defined in `helpers.bash`. + For example, `${COL_RED}`, additionally always be sure to reset to standard + color at the end of your output statement by using `${COL_DEF}`. -## Code Guidelines +* Never use absolute paths for binaries, always use the standard paths + instead. For example, `/usr/bin/apt-get` vs. `apt-get`. -* Use two (2) spaces when indenting code. +* When a function is used across many files, include it in the `helpers.bash` + file. -* `local` declarations of variables should be used when possible. +* Always refuse to allow the running of package setup scripts that require + user input in unattended mode. -* Always refuse to allow the running of package setup scripts that require user input in unattended mode. +* Wrap Markdown code at 80 columns. Links and code examples may cross 80 + columns when necessary. When editing documents in the `docs/` directory, + try to keep to one sentence per line. ### Usage of `apt-get update` command -To minimize unnecessary updates of the local apt database running `apt-get update` is only permitted in: +To minimize unnecessary updates of the local apt database running +`apt-get update` is only permitted under the following circumstances: 1) Once in the `first-boot.bash` file prior to installing the system first time. @@ -163,55 +166,133 @@ To minimize unnecessary updates of the local apt database running `apt-get updat ## Test Architecture -Testing is based on three pilars: A) *Installation of base system*, B) *Test Cases*, and C) *Static analysis using linter*. +Testing is based on three pillars: + +A) *Installation of base system* + +B) *Test Cases using [BATS](https://github.com/bats-core/bats-core)* + +C) *Static analysis using the [Shellcheck](https://www.shellcheck.net/) linter* ### Test installation -Test installations are done continuously using Docker on a Travis Virtual Machine and by testing on actual hardware, eg. Raspberry Pi. A Docker installation can be performed by three commands. Firstly a Docker image is built where the `openhabian` code is injected (see `Dockerfile.*` for details): +Test installations are done continuously using Docker on a Travis Virtual +Machine and by testing on actual hardware, eg. Raspberry Pi. A Docker +installation can be performed by three commands. Firstly a Docker image is built +where the `openhabian` code is injected (see `Dockerfile.*` for details). +To begin, first make a Docker container for your platform. An example Docker +container build for `amd64` would look like: ``` -docker build --tag openhabian/openhabian-bats . +docker build --tag openhabian/install-openhabian -f Dockerfile.amd64 . ``` -The openHABian scripts are using `systemd` for service management, to use `systemd` with Docker the container must be started first to ensure `systemd` gets pid 1. This is done by executing: +While not a problem in the final container-less deployment, with more than one +container running, all but one of them will have a `systemd` running with a PID +other than 1. That will break openHABian in a number of locations when we use +`systemctl` to start/stop/check `systemd` controlled services. +This is why we replace the `systemctl` binary in `Dockerfile.*` during Travis +testing.`systemctl.py` is a Python replacement that does not complain about +`systemd` running with an arbitrary PID. + +This is done by executing: ``` -docker run --name "install-test" --privileged -d openhabian/openhabian-bats +docker run --name "install-test" --privileged -d openhabian/install-openhabian ``` + Lastly the installation is invoked by executing: ``` -docker exec -it install-test bash -c "./build.bash local-test && mv ~/.profile ~/.bash_profile && /etc/rc.local" +docker exec -i "install-test" bash -c "./build.bash local-test && mv ~/.profile ~/.bash_profile && /etc/rc.local" +``` + +Be sure to cleanup the tests after you are finished by executing: +``` +docker stop install-test +docker rm install-test ``` -Notice that the "Docker system" mimics a hardware SD-card installation with the command `./build.bash local-test`. + +Notice that the "Docker system" mimics a hardware SD-card installation with the +command `./build.bash local-test`. ### Test Cases -The test cases are further divided into four categories and can be individually invoked by the BATS framework. The tests categories can be identified in the naming of the test. The tests' code are held in a corresponding file to the code itself, i.e. code: `helpers.bash` and tests `helpers.bats`. The categories are as follows: +The test cases are further divided into three categories and can be individually +invoked by the [BATS](https://github.com/bats-core/bats-core) framework. The +tests' categories can be identified in the naming of the test. The tests' code +are held in a corresponding file to the code itself. +For example, code would reside in `helpers.bash` with tests in `helpers.bats`. + +To begin, first make a Docker container for your platform. An example Docker +container build for `amd64` would look like: +``` +docker build --tag openhabian/bats-openhabian -f Dockerfile.amd64 . +``` -#### Development Tests `dev-` -These tests may alter the host system. Use dev- tests to test new features under development. They are the first to be started in a test run and first to finish so you can see as early as possible if your feature works fine. Testing will not proceed beyond the `dev` stage if there are errors. +Now that we have a functioning Docker container, the categories are as follows: #### Unit Tests `unit-` -These tests do not alter the host system, the test is executed and is isolated to a specific function. These tests are not required on a installed base system of openHABian. +These tests do not alter the host system, the test is executed and is isolated +to a specific function. These tests are not required on a installed base system +of openHABian. ``` -docker run -it openhabian/openhabian-bats bash -c 'bats -r -f "unit-." .' +docker run --rm --name "unit-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "unit-." .' ``` #### Installation Verification `installation-` This is a suite of tests designed to verify a normal installation. -These tests **shall** not alter the system. +These tests **shall** not alter the base openHABian system. ``` -docker exec -it install-test bash -c 'bats -r -f "installation-." .' +docker run --rm --name "installation-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "installation-." .' ``` - -#### Destructive Verification Tests `destruct-` -These tests install new functionality and are therefore destructive for the current system. Typical use-cases are testing of optional packages or a specific configuration of a baseline package. +#### Destructive Verification Tests `destructive-` +These tests install new functionality and are therefore destructive to the +openHABian base system. Typical use-cases are testing of optional +packages or a specific configuration of a baseline package. ``` -docker exec -it install-test bash -c 'bats -r -f "destructive-." .' +docker run --rm --name "destructive-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "destructive-." .' ``` ### Linter +The [Shellcheck](https://www.shellcheck.net/) linter can be run by using the +following three commands: +``` +shellcheck -x -s bash openhabian-setup.sh +shellcheck -x -s bash functions/*.bash +shellcheck -x -s bash build-image/*.bash +``` + +### Test Script +The above tests can all be run as a single script. To run the installation and +and [BATS](https://github.com/bats-core/bats-core) tests run: +``` +./test.bash docker-full +``` +To run the [Shellcheck](https://www.shellcheck.net/) tests run: ``` -shellcheck -s bash openhabian-setup.sh -shellcheck -s bash functions/*.bash -shellcheck -s bash build-image/*.bash +./test.bash docker-full ``` + +## Community Guidelines + +We want to keep the openHAB community awesome, growing and collaborative. We +need your help to keep it that way. To help with this we've come up with some +general guidelines for the community as a whole: + +* Be nice: Be courteous, respectful and polite to fellow community members: no + regional, racial, gender, or other abuse will be tolerated. We like nice + people way better than mean ones! + +* Encourage diversity and participation: Make everyone in our community + feel welcome, regardless of their background and the extent of their + contributions, and do everything possible to encourage participation in + our community. + +* Keep it legal: Basically, don't get us in trouble. Share only content that + you own, do not share private or sensitive information, and don't break the + law. + +* Stay on topic: Make sure that you are posting to the correct channel + and avoid off-topic discussions. Remember when you update an issue or + respond to an email you are potentially sending to a large number of + people. Please consider this before you update. Also remember that + nobody likes spam. diff --git a/NEWS.md b/NEWS.md index a7fe9917d..8b5ee05f7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,21 +1,25 @@ -This is the new announcement page that will pop up whenever you start `openhabian-config` and the developers have -significant news they would like to share with you. +This is the new announcement page that will pop up whenever you start +`openhabian-config` and the developers have significant news they would like to +share with you. -Hit tab to unselect the buttons and scroll through the text using UP/DOWN or PGUP/PGDN. +Hit tab to unselect the buttons and scroll through the text using UP/DOWN or +PGUP/PGDN. -All announcements will be stored in /opt/openhabian/docs/NEWSLOG for you to lookup. +All announcements will be stored in /opt/openhabian/docs/NEWSLOG for you to +lookup. ## June 10, 2020 ### New parameters in `openhabian.conf` -See `/etc/openhabian.conf` for a number of new parameters such as the useful `debugmode`, a fake hardware mode, -options to disable ipv6 and the ability to update from a custom repository other than the defaults of `master` and -`stable`. +See `/etc/openhabian.conf` for a number of new parameters such as the useful +`debugmode`, a fake hardware mode, the option to disable ipv6 and the ability to +update from a custom repository other than the `master` and `stable` branches. In case you are not aware, there is a Debug Guide in the `docs/` directory. ### New Java options -Preparing for openHAB 3, new options for the JDK that runs openHAB are now available: +Preparing for openHAB 3, new options for the JDK that runs openHAB are now +available: - Java Zulu 8 32-Bit OpenJDK (default on ARM based platforms) - Java Zulu 8 64-Bit OpenJDK (default on x86 based platforms) @@ -23,36 +27,44 @@ Preparing for openHAB 3, new options for the JDK that runs openHAB are now avail - Java Zulu 11 64-Bit OpenJDK - AdoptOpenJDK 11 OpenJDK (potential replacement for Zulu) -openHAB 3 will be Java 11 only. 2.5.X is supposed to work on both, Java 8 and Java 11. -Running the current openHAB 2.X on Java 11 however has not been tested on a wide scale. -Please be aware that there is a small number of known issues in this: v1 bindings may or may not work. +openHAB 3 will be Java 11 only. 2.5.X is supposed to work on both, Java 8 and +Java 11. Running the current openHAB 2.X on Java 11 however has not been tested +on a wide scale. Please be aware that there is a small number of known issues in +this: v1 bindings may or may not work. -Please participate in beta testing to help create a smooth transition user experience for all of us. -See [announcement thread](https://community.openhab.org/t/Java-testdrive/99827) on the community forum. +Please participate in beta testing to help create a smooth transition user +experience for all of us. + +See [announcement thread](https://community.openhab.org/t/Java-testdrive/99827) +on the community forum. ## May 31, 2020 ### Stable branch -Introducing a new versioning scheme to openHABian. Please welcome `stable` branch. - -Similar to openHAB where there's releases and snapshots, you will from now on be using the stable branch. It's the -equivalent of an openHAB release. We will keep providing new changes to the master branch first as soon as we make -them available, just like we have been doing in the past. If you want to keep living on the edge, want to make use -of new features fast or volunteer to help a little in advancing openHABian, you can choose to switch back to the -master branch. Anybody else will benefit from less frequent but well better tested updates to happen to the stable -branch in batches, whenever the poor daring people to use `master` have reported their trust in these changes to -work flawlessly. +Introducing a new versioning scheme to openHABian. Please welcome the `stable` +branch. + +Similar to openHAB where there's releases and snapshots, you will from now on be +using the stable branch. It's the equivalent of an openHAB release. We will keep +providing new changes to the master branch first as soon as we make them +available, just like we have been doing in the past. If you want to keep living +on the edge, want to make use of new features fast or volunteer to help a little +in advancing openHABian, you can choose to switch back to the master branch. +Anybody else will benefit from less frequent but well better tested updates to +happen to the stable branch in batches, whenever the poor daring people to use +`master` have reported their trust in these changes to work flawlessly. You can switch branches at any time using the menu option 01. ### ZRAM per default Swap, logs and persistence files are now put into ZRAM per default. -See [ZRAM status thread](https://community.openhab.org/t/zram-status/80996) for more information. +See [ZRAM status thread](https://community.openhab.org/t/zram-status/80996) for +more information. ### Supported hardware and Operating Systems -openHABian now fully supports all Raspberry Pi SBCs with our fast-start image. As an add-on package, it is supposed -to run on all Debian based OSs. +openHABian now fully supports all Raspberry Pi SBCs with our fast-start image. +As an add-on package, it is supposed to run on all Debian based OSs. -Check the [README](README.md) to see what "supported" actually means and what you can do if you want to run on -other HW or OS. +Check the [README](README.md) to see what "supported" actually means and what +you can do if you want to run on other HW or OS. diff --git a/README.md b/README.md index f4800743e..62369e081 100644 --- a/README.md +++ b/README.md @@ -1,94 +1,165 @@ -As an **openHABian end user**, please check out the official openHAB documentation: +As an **openHABian end user**, please check out the official openHAB +documentation: - # openHABian - Hassle-free openHAB Setup [![build](https://travis-ci.org/openhab/openhabian.svg?branch=master)](https://travis-ci.com/github/openhab/openhabian) ![shellcheck](https://github.com/openhab/openhabian/workflows/shellcheck/badge.svg?branch=master) -Setting up a fully working Linux system with all needed packages and openHAB recommendations is a **boring task** taking quite some time and **Linux newcomers** shouldn't worry about these technical details. +Setting up a fully working Linux system with all needed packages and openHAB +recommendations is a **boring task** taking quite some time and +**Linux newcomers** shouldn't worry about these technical details. ***A home automation enthusiast doesn't have to be a Linux enthusiast!*** -openHABian aims to provide a **self-configuring** Linux system setup specific to the needs of every openHAB user. +openHABian aims to provide a **self-configuring** Linux system setup specific +to the needs of every openHAB user. + The project provides two things: -* a set of scripts to set up openHAB on any Debian based system (Raspberry Pi OS, Ubuntu) -* a complete **SD-card image pre-configured with openHAB** and many other openHAB- and Hardware-specific preparations for all *Raspberry Pi* models. +* a set of scripts to set up openHAB on any Debian based system + (Raspberry Pi OS, Ubuntu) +* a complete **SD-card image pre-configured with openHAB** and many other + openHAB- and Hardware-specific preparations for all *Raspberry Pi* models. ## Hardware and OS support -As of openHABian version 1.5 of the image, all Raspberry Pi models are supported as hardware. -Anything x86 based may work or not. Anything else ARM based such as ODroids, OrangePis and the like may work or not. -NAS servers such as QNAP and Synology boxes will not work. Support for PINEA64 was also dropped in this current release. -We strongly recommend that users choose Raspberry Pi 2, 3 or 4 systems to have 1GB of RAM or more. RPi 1 and 0/0W only have a single CPU core and 512MB. This can be sufficient to run a smallish openHAB setup, but it will not be enough to run a full-blown system with many bindings and memory consuming openHABian features/components such as ZRAM, InfluxDB or Grafana. -We do not actively prohibit installation on any hardware - including unsupported systems -, but we might skip or deny to install specific extensions such as those memory hungry features named above. -Supporting hardware means testing every single patch and every release. There are simply too many SBC and HW combinations that maintainers do not have available, or, even if they did, the time to spend on the testing efforts that is required to make openHABian a reliable system. -Let's make sure you understand the implications of these statements: it means that to run hardware other than RPi 2/3/4 or x86 is **not** *fully* supported. +As of openHABian version 1.5 of the image, all Raspberry Pi models are supported +as hardware. Anything x86 based may work or not. Anything else ARM based such as +ODroids, OrangePis and the like may work or not. NAS servers such as QNAP and +Synology boxes will not work. Support for PINEA64 was also dropped in this +current release. We strongly recommend that users choose Raspberry Pi 2, 3 or 4 +systems to have 1GB of RAM or more. RPi 1 and 0/0W only have a single CPU core +and 512MB. This can be sufficient to run a smallish openHAB setup, but it will +not be enough to run a full-blown system with many bindings and memory consuming +openHABian features/components such as ZRAM, InfluxDB or Grafana. + +We do not actively prohibit installation on any hardware, including unsupported +systems, but we might skip or deny to install specific extensions such as those +memory hungry features named above. + +Supporting hardware means testing every single patch and every release. There +are simply too many SBC and HW combinations that maintainers do not have +available, or, even if they did, the time to spend on the testing efforts that +is required to make openHABian a reliable system. Let's make sure you understand +the implications of these statements: it means that to run hardware other than +RPi 2/3/4 or x86 is **not** *fully* supported. + For ARM hardware that we don't support, check out the [fake hardware parameters](openhabian.md/#fake-hardware-mode). -There's a good chance it'll work out for you. If that still doesn't work for you, give [Ubuntu](https://ubuntu.com/download/iot) or [ARMbian](https://www.armbian.com/) a try. -But remember if you hit any problem related to memory or hardware, you'll be on your own. You are expected **not** to raise these problems as issues on the community forum or on GitHub, please. Feel encouraged to report any success stories, though. +There's a good chance it'll work out for you. If that still doesn't work for +you, give [Ubuntu](https://ubuntu.com/download/iot) or [ARMbian](https://www.armbian.com/) +a try. But remember if you hit any problem related to memory or hardware, you'll +be on your own. You are expected **not** to raise these problems as issues on +the community forum or on GitHub, please. Feel encouraged to report any success +stories, though. + +Going beyond what the RPi image provides, as a manually installed set of +scripts, there's a fair chance that openHABian will work on all Debian like +Linux distributions such as Ubuntu, on either ARM or x86 hardware, but remember +this is not *supported*. -Going beyond what the RPi image provides, as a manually installed set of scripts, there's a fair chance that openHABian will work on all Debian like Linux distributions such as Ubuntu, on either ARM or x86 hardware, but remember this is not *supported*. +Our recommendation is to install Raspberry Pi OS lite (ARM) or generic +Debian (x86). This is what we support and test openHABian against. -Our recommendation is to install Raspberry Pi OS lite (ARM) or generic Debian (x86). This is what we support and test openHABian against. +If you choose not to use the image, we expect you to use the stable distribution +that openHABian testing is based on, 'buster' for Raspberry Pi OS (ARM) and +Debian (x86) that is. -If you choose not to use the image, we expect you to use the stable distribution that openHABian testing is based on, 'buster' for Raspberry Pi OS (ARM) and Debian (x86) that is. -To install openHABian on anything older or newer may work or not. If you encounter issues, you may need to upgrade first or to live with the consequences of running an OS on the edge of software development. +To install openHABian on anything older or newer may work or not. If you +encounter issues, you may need to upgrade first or to live with the consequences +of running an OS on the edge of software development. -Either way, please note that you're on your own when it comes to configuring and installing the HW with the proper OS yourself. +Either way, please note that you're on your own when it comes to configuring and +installing the HW with the proper OS yourself. ### 64 bit ? Although RPi3 and 4 have a 64 bit processor, you cannot run openHAB in 64 bit. -The Azul Java Virtual Machine we currently use is incompatible with the aarch64 ARM architecture. -In general you should be aware that to run in 64 bit has a major drawback, increased memory usage, that is not a good idea on a heavily memory constrained platform like a RPi. -Also remember openHABian makes use of Raspberry Pi OS which today still is a 32 bit OS. +The Azul Java Virtual Machine we currently use is incompatible with the aarch64 +ARM architecture. In general you should be aware that to run in 64 bit has a +major drawback, increased memory usage, that is not a good idea on a heavily +memory constrained platform like a RPi. Also remember openHABian makes use of +Raspberry Pi OS which today still is a 32 bit OS. -We are closely observing development and will adapt openHABian once it will reliably work on 64 bit. -So things may change in the future, but for the time being, you should not manually enforce to install a 64 bit JVM. +We are closely observing development and will adapt openHABian once it will +reliably work on 64 bit. So things may change in the future, but for the time +being, you should not manually enforce to install a 64 bit JVM. On x86 hardware, 64 bit is the standard. ## Installation and Setup -Please check the [official documentation article](https://www.openhab.org/docs/installation/openhabian.html) to learn about openHABian and please visit and subscribe to our very active [community forum thread](https://community.openhab.org/t/13379). +Please check the [official documentation article](https://www.openhab.org/docs/installation/openhabian.html) +to learn about openHABian and please visit and subscribe to our very active +[community forum thread](https://community.openhab.org/t/13379). -If you want to install openHABian on non-supported hardware, you can actually fake it to make openHABian treat your box as if it was one of the supported ones. Needless to say that that may work out or not, but it's worth a try. -See [openhabian](openhabian.md) how to edit openhabian.conf before booting. Set the hw, hwarch and release parameters to match your system best. +If you want to install openHABian on non-supported hardware, you can actually +fake it to make openHABian treat your box as if it was one of the supported +ones. Needless to say that that may work out or not, but it's worth a try. See +[openhabian](openhabian.md) for how to edit openhabian.conf before booting. Set +the hw, hwarch and release parameters to match your system best. ## Development -openHABian is foremost a collection of `bash` scripts versioned and deployed using git. In the current state the scripts can only be invoked through the terminal menu system [whiptail](https://en.wikibooks.org/wiki/Bash_Shell_Scripting/Whiptail). There is a longterm need to better separate the UI part from the script code. A work has started to define conventions and further explain the code base in the document [CONTRIBUTING](CONTRIBUTING.md) along with development guidelines in general. +openHABian is foremost a collection of `bash` scripts versioned and deployed +using git. In the current state the scripts can only be invoked through the +terminal menu system [whiptail](https://en.wikibooks.org/wiki/Bash_Shell_Scripting/Whiptail). +There is a longterm need to better separate the UI part from the script code. A +work has started to define conventions and further explain the code base in the +document [CONTRIBUTING](CONTRIBUTING.md) along with development guidelines in +general. -A good place to look at to start to understand the code is the file `openhabian-setup.sh`. +A good place to look at to start to understand the code is the file +`openhabian-setup.sh`. ### Building Hardware Images Take a look at the `build.bash` script to get an idea of the process. -Simply explained run the code below with `platform` being either `rpi` or `pine64`. The RPi image is based on the [Raspberry Pi OS Lite](https://www.raspberrypi.org/downloads/raspberry-pi-os/) (previously called Raspbian) standard image while the Pine64 image is based on [build-pine64-image](https://github.com/longsleep/build-pine64-image). +Simply explained run the code below with `platform` being either `rpi` or +`pine64`. The RPi image is based on the [Raspberry Pi OS Lite](https://www.raspberrypi.org/downloads/raspberry-pi-os/) +(previously called Raspbian) standard image while the Pine64 image is based on +[build-pine64-image](https://github.com/longsleep/build-pine64-image). ``` -$ sudo bash ./build.bash platform +sudo bash ./build.bash platform ``` -As the script uses `openhab/openhabian` git repository during installation it must sometimes be changed to test code from other repositories, like a new feature in a fork. There are two commands for replacing the git repo with a custom one. The first command uses the current checked-out repository used in the filesystem: + +As the script uses `openhab/openhabian` git repository during installation it +must sometimes be changed to test code from other repositories, like a new +feature in a fork. There are two commands for replacing the git repo with a +custom one. The first command uses the current checked-out repository used in +the filesystem: ``` -$ sudo bash build.bash platform dev-git +sudo bash build.bash platform dev-git ``` The second command uses a fully customizable repository: ``` -$ sudo bash build.bash platform dev-url branch url +sudo bash build.bash platform dev-url branch url ``` ### Testing -Testing is done continuously with Travis using the test framework [Bats](https://github.com/bats-core/bats-core) and the linter [Shellcheck](https://www.shellcheck.net/). As the tests focus on installing software, a docker solution is used for easy build-up and teardown. To run the test suite execute the commands below or `"$ ./test.bash docker-full"`. Docker and Shellcheck need to be installed. For more details regarding the tests see [Test Architecture](https://github.com/openhab/openhabian/blob/master/CONTRIBUTING.md#test-architecture) in CONTRIBUTING. +Testing is done continuously with Travis-CI using the test framework +[BATS](https://github.com/bats-core/bats-core) and the linter +[Shellcheck](https://www.shellcheck.net/). As the tests focus on installing +software, a [Docker](https://www.docker.com/) solution is used for easy build-up +and teardown. + +To run the test suite on a `amd64` platform execute the commands below. +[Docker](https://www.docker.com/) and [Shellcheck](https://www.shellcheck.net/) +need to be installed first. For more details regarding the tests see +[Test Architecture](https://github.com/openhab/openhabian/blob/master/CONTRIBUTING.md#test-architecture) +in CONTRIBUTING.md. ``` -docker build -t openhabian/openhabian-bats . -docker run -i openhabian/openhabian-bats bash -c 'bats -r -f "unit-." .' +docker build --tag openhabian/bats-openhabian -f Dockerfile.amd64 . +docker run --rm --name "unit-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "unit-." .' +docker run --rm --name "installation-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "installation-." .' +docker run --rm --name "destructive-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "destructive-." .' -docker run --name "install-test" --privileged -d openhabian/openhabian-bats -docker exec -i install-test bash -c "./build.bash local-test && mv ~/.profile ~/.bash_profile && /etc/rc.local" -docker exec -i install-test bash -c 'bats -r -f "installation-." .' -docker exec -i install-test bash -c 'bats -r -f "destructive-." .' +docker build --tag openhabian/install-openhabian -f Dockerfile.amd64 . +docker run --name "install-test" --privileged -d openhabian/bats-openhabian +docker exec -i "install-test" bash -c "./build.bash local-test && mv ~/.profile ~/.bash_profile && /etc/rc.local" docker stop install-test docker rm install-test ``` -Run the linter by executing: + +The [Shellcheck](https://www.shellcheck.net/) linter can be run by using the +following three commands: ``` shellcheck -x -s bash openhabian-setup.sh shellcheck -x -s bash functions/*.bash diff --git a/build-image/openhabian.conf b/build-image/openhabian.conf index 5f63c73f6..757fe4e96 100644 --- a/build-image/openhabian.conf +++ b/build-image/openhabian.conf @@ -35,7 +35,7 @@ clonebranch=stable # debug verbosity mode # off, on (verbose output in log) or maximum (show every command) -debugmode=on +debugmode=off # Hardware # pi0, pi0w, pi1, cm1, pi2, pi3, cm3, pi3+, cm3+, pi4 diff --git a/docs/NEWSLOG.md b/docs/NEWSLOG.md index ece0cddc0..6613a54a9 100644 --- a/docs/NEWSLOG.md +++ b/docs/NEWSLOG.md @@ -1,14 +1,15 @@ ## June 10, 2020 ### New parameters in `openhabian.conf` -See `/etc/openhabian.conf` for a number of new parameters such as the useful `debugmode`, a fake hardware mode, -options to disable ipv6 and the ability to update from a custom repository other than the defaults of `master` and -`stable`. +See `/etc/openhabian.conf` for a number of new parameters such as the useful +`debugmode`, a fake hardware mode, the option to disable ipv6 and the ability to +update from a custom repository other than the `master` and `stable` branches. In case you are not aware, there is a Debug Guide in the `docs/` directory. ### New Java options -Preparing for openHAB 3, new options for the JDK that runs openHAB are now available: +Preparing for openHAB 3, new options for the JDK that runs openHAB are now +available: - Java Zulu 8 32-Bit OpenJDK (default on ARM based platforms) - Java Zulu 8 64-Bit OpenJDK (default on x86 based platforms) @@ -16,36 +17,44 @@ Preparing for openHAB 3, new options for the JDK that runs openHAB are now avail - Java Zulu 11 64-Bit OpenJDK - AdoptOpenJDK 11 OpenJDK (potential replacement for Zulu) -openHAB 3 will be Java 11 only. 2.5.X is supposed to work on both, Java 8 and Java 11. -Running the current openHAB 2.X on Java 11 however has not been tested on a wide scale. -Please be aware that there is a small number of known issues in this: v1 bindings may or may not work. +openHAB 3 will be Java 11 only. 2.5.X is supposed to work on both, Java 8 and +Java 11. Running the current openHAB 2.X on Java 11 however has not been tested +on a wide scale. Please be aware that there is a small number of known issues in +this: v1 bindings may or may not work. -Please participate in beta testing to help create a smooth transition user experience for all of us. -See [announcement thread](https://community.openhab.org/t/Java-testdrive/99827) on the community forum. +Please participate in beta testing to help create a smooth transition user +experience for all of us. + +See [announcement thread](https://community.openhab.org/t/Java-testdrive/99827) +on the community forum. ## May 31, 2020 ### Stable branch -Introducing a new versioning scheme to openHABian. Please welcome `stable` branch. - -Similar to openHAB where there's releases and snapshots, you will from now on be using the stable branch. It's the -equivalent of an openHAB release. We will keep providing new changes to the master branch first as soon as we make -them available, just like we have been doing in the past. If you want to keep living on the edge, want to make use -of new features fast or volunteer to help a little in advancing openHABian, you can choose to switch back to the -master branch. Anybody else will benefit from less frequent but well better tested updates to happen to the stable -branch in batches, whenever the poor daring people to use `master` have reported their trust in these changes to -work flawlessly. +Introducing a new versioning scheme to openHABian. Please welcome the `stable` +branch. + +Similar to openHAB where there's releases and snapshots, you will from now on be +using the stable branch. It's the equivalent of an openHAB release. We will keep +providing new changes to the master branch first as soon as we make them +available, just like we have been doing in the past. If you want to keep living +on the edge, want to make use of new features fast or volunteer to help a little +in advancing openHABian, you can choose to switch back to the master branch. +Anybody else will benefit from less frequent but well better tested updates to +happen to the stable branch in batches, whenever the poor daring people to use +`master` have reported their trust in these changes to work flawlessly. You can switch branches at any time using the menu option 01. ### ZRAM per default Swap, logs and persistence files are now put into ZRAM per default. -See [ZRAM status thread](https://community.openhab.org/t/zram-status/80996) for more information. +See [ZRAM status thread](https://community.openhab.org/t/zram-status/80996) for +more information. ### Supported hardware and Operating Systems -openHABian now fully supports all Raspberry Pi SBCs with our fast-start image. As an add-on package, it is supposed -to run on all Debian based OSs. +openHABian now fully supports all Raspberry Pi SBCs with our fast-start image. +As an add-on package, it is supposed to run on all Debian based OSs. -Check the [README](README.md) to see what "supported" actually means and what you can do if you want to run on -other HW or OS. +Check the [README](README.md) to see what "supported" actually means and what +you can do if you want to run on other HW or OS. diff --git a/docs/openhabian-amanda.md b/docs/openhabian-amanda.md index 778c2004d..653dd95b8 100644 --- a/docs/openhabian-amanda.md +++ b/docs/openhabian-amanda.md @@ -72,7 +72,7 @@ that's something you have to accomplish on your own. Read and understand the Ama * It's helpful to know that Amanda was originally built to use magnetic tape changer libraries as backup storage in professional data center installations. It can operate multiple tape drives in parallel, and the tapes used to be commonly stored in what's called a 'slot' inside the tape library cabinet. -* The default dumpcycle for a openHABian install is 2 weeks. Amanda will run a 'level 0' dump (that means to backup EVERYTHING) +* The default dumpcycle for an openHABian installation is 2 weeks. Amanda will run a 'level 0' dump (that means to backup EVERYTHING) once in a dumpcycle and will run 'level 1' dumps for the rest of the time (that means to only backup files that have CHANGED since the last level 0 dump was done, also called an 'incremental' backup). Amanda will combine level 0 of some devices with level 1 or 2 of others, aiming to have the more or less same amount of data diff --git a/functions/helpers.bash b/functions/helpers.bash index 5c00392ab..8aafd310d 100644 --- a/functions/helpers.bash +++ b/functions/helpers.bash @@ -47,7 +47,7 @@ cond_echo() { add_keys() { local repoKey - repoKey="$(mktemp "${TEMP:-/tmp}"/openhabian.XXXXX)" + repoKey="$(mktemp "${TMPDIR:-/tmp}"/openhabian.XXXXX)" echo -n "$(timestamp) [openHABian] Adding required keys to apt... " cond_redirect wget -qO "$repoKey" "$1" diff --git a/functions/java-jre.bash b/functions/java-jre.bash index 431fd2470..4acf92cea 100644 --- a/functions/java-jre.bash +++ b/functions/java-jre.bash @@ -33,7 +33,7 @@ java_install_or_update() { if [ "$1" == "Zulu8-64" ]; then if cond_redirect java_zulu_update_available "Zulu8-64"; then echo -n "$(timestamp) [openHABian] Installing Java Zulu 8 64-Bit OpenJDK... " - cond_redirect java_zulu_prerequsite "Zulu8-64" + cond_redirect java_zulu_prerequisite "Zulu8-64" if ! [ -x "$(command -v java)" ] && [ -d /opt/jdk/* ]; then cond_redirect java_zulu_install "Zulu8-64" elif [ "$branch" == "stable" ] && [ -z "$UNATTENDED" ]; then @@ -46,7 +46,7 @@ java_install_or_update() { elif [ "$1" == "Zulu11-64" ]; then if cond_redirect java_zulu_update_available "Zulu11-64"; then echo -n "$(timestamp) [openHABian] Installing Java Zulu 11 64-Bit OpenJDK... " - cond_redirect java_zulu_prerequsite "Zulu11-64" + cond_redirect java_zulu_prerequisite "Zulu11-64" if ! [ -x "$(command -v java)" ] && [ -d /opt/jdk/* ]; then cond_redirect java_zulu_install "Zulu11-64" elif [ "$branch" == "stable" ] && [ -z "$UNATTENDED" ]; then @@ -65,7 +65,7 @@ java_install_or_update() { echo "$(timestamp) [openHABian] Zulu OpenJDK 64-bit: this option does not currently work on your platform. Defaulting to Java Zulu 8 32-bit installation." if cond_redirect java_zulu_update_available "Zulu8-32"; then echo -n "$(timestamp) [openHABian] Installing Java Zulu 8 32-Bit OpenJDK... " - cond_redirect java_zulu_prerequsite "Zulu8-32" + cond_redirect java_zulu_prerequisite "Zulu8-32" if ! [ -x "$(command -v java)" ] && [ -d /opt/jdk/* ]; then cond_redirect java_zulu_install "Zulu8-32" elif [ "$branch" == "stable" ] && [ -z "$UNATTENDED" ]; then @@ -81,7 +81,7 @@ java_install_or_update() { if [ "$1" == "Zulu11-32" ]; then if cond_redirect java_zulu_update_available "Zulu11-32"; then echo -n "$(timestamp) [openHABian] Installing Java Zulu 11 32-Bit OpenJDK... " - cond_redirect java_zulu_prerequsite "Zulu11-32" + cond_redirect java_zulu_prerequisite "Zulu11-32" if ! [ -x "$(command -v java)" ] && [ -d /opt/jdk/* ]; then cond_redirect java_zulu_install "Zulu11-32" elif [ "$branch" == "stable" ] && [ -z "$UNATTENDED" ]; then @@ -93,7 +93,7 @@ java_install_or_update() { fi elif cond_redirect java_zulu_update_available "Zulu8-32"; then echo -n "$(timestamp) [openHABian] Installing Java Zulu 8 32-Bit OpenJDK... " - cond_redirect java_zulu_prerequsite "Zulu8-32" + cond_redirect java_zulu_prerequisite "Zulu8-32" if ! [ -x "$(command -v java)" ] && [ -d /opt/jdk/* ]; then cond_redirect java_zulu_install "Zulu8-32" elif [ "$branch" == "stable" ] && [ -z "$UNATTENDED" ]; then @@ -109,33 +109,33 @@ java_install_or_update() { cond_redirect java -version } -## Install Java Zulu prerequsite libc +## Install Java Zulu prerequisite libc ## Valid arguments: "Zulu8-32", "Zulu8-64", "Zulu11-32", or "Zulu11-64" ## -## java_zulu_prerequsite(String arch) +## java_zulu_prerequisite(String arch) ## -java_zulu_prerequsite() { - echo -n "$(timestamp) [openHABian] Installing Java Zulu prerequsites (libc)... " +java_zulu_prerequisite() { + echo -n "$(timestamp) [openHABian] Installing Java Zulu prerequisites (libc)... " if [ "$1" == "Zulu8-64" ] || [ "$1" == "Zulu11-64" ]; then if is_aarch64 && [ "$(getconf LONG_BIT)" == "64" ]; then - if (dpkg -s 'libc6:arm64' > /dev/null 2>&1) && (dpkg -s 'libncurses5:arm64' > /dev/null 2>&1) && (dpkg -s 'libstdc++6:arm64' > /dev/null 2>&1); then echo "OK"; return 0; fi + if dpkg -s 'libc6:arm64' 'libncurses5:arm64' 'libstdc++6:arm64' > /dev/null 2>&1; then echo "OK"; return 0; fi dpkg --add-architecture arm64 if ! cond_redirect apt-get update; then echo "FAILED (update apt lists)"; return 1; fi if cond_redirect apt-get install --yes libc6:arm64 libncurses5:arm64 libstdc++6:arm64; then echo "OK"; else echo "FAILED"; return 1; fi elif is_x86_64 && [ "$(getconf LONG_BIT)" == "64" ]; then - if (dpkg -s 'libc6:amd64' > /dev/null 2>&1) && (dpkg -s 'libncurses5:amd64' > /dev/null 2>&1) && (dpkg -s 'libstdc++6:amd64' > /dev/null 2>&1); then echo "OK"; return 0; fi + if dpkg -s 'libc6:amd64' 'libncurses5:amd64' 'libstdc++6:amd64' > /dev/null 2>&1; then echo "OK"; return 0; fi dpkg --add-architecture amd64 if ! cond_redirect apt-get update; then echo "FAILED (update apt lists)"; return 1; fi if cond_redirect apt-get install --yes libc6:amd64 libncurses5:amd64 libstdc++6:amd64; then echo "OK"; else echo "FAILED"; return 1; fi fi else if is_arm; then - if (dpkg -s 'libc6:armhf' > /dev/null 2>&1) && (dpkg -s 'libncurses5:armhf' > /dev/null 2>&1) && (dpkg -s 'libstdc++6:armhf' > /dev/null 2>&1); then echo "OK"; return 0; fi + if dpkg -s 'libc6:armhf' 'libncurses5:armhf' 'libstdc++6:armhf' > /dev/null 2>&1; then echo "OK"; return 0; fi dpkg --add-architecture armhf if ! cond_redirect apt-get update; then echo "FAILED (update apt lists)"; return 1; fi if cond_redirect apt-get install --yes libc6:armhf libncurses5:armhf libstdc++6:armhf; then echo "OK"; else echo "FAILED"; return 1; fi else - if (dpkg -s 'libc6:i386' > /dev/null 2>&1) && (dpkg -s 'libncurses5:i386' > /dev/null 2>&1) && (dpkg -s 'libstdc++6:i386' > /dev/null 2>&1); then echo "OK"; return 0; fi + if dpkg -s 'libc6:i386' 'libncurses5:i386' 'libstdc++6:i386' > /dev/null 2>&1; then echo "OK"; return 0; fi dpkg --add-architecture i386 if ! cond_redirect apt-get update; then echo "FAILED (update apt lists)"; return 1; fi if cond_redirect apt-get install --yes libc6:i386 libncurses5:i386 libstdc++6:i386; then echo "OK"; else echo "FAILED"; return 1; fi @@ -285,7 +285,7 @@ java_zulu_update_available() { local requestedArch if ! [ -x "$(command -v jq)" ]; then - echo -n "$(timestamp) [openHABian] Installing Java Zulu prerequsites (jq)... " + echo -n "$(timestamp) [openHABian] Installing Java Zulu prerequisites (jq)... " if cond_redirect apt-get install --yes jq; then echo "OK"; else echo "FAILED"; return 1; fi fi @@ -380,7 +380,7 @@ java_zulu_install_crypto_extension() { local policyTempLocation jdkSecurity="$(dirname "$(readlink -f "$(command -v java)")")/../lib/security" - policyTempLocation="$(mktemp -d "${TEMP:-/tmp}"/openhabian.XXXXX)" + policyTempLocation="$(mktemp -d "${TMPDIR:-/tmp}"/openhabian.XXXXX)" echo -n "$(timestamp) [openHABian] Installing Java Zulu Cryptography Extension Kit to enable cryptos using more then 128 bits... " mkdir -p "$jdkSecurity" @@ -395,7 +395,7 @@ java_zulu_install_crypto_extension() { ## adoptopenjdk_fetch_apt() { if ! dpkg -s 'software-properties-common' > /dev/null 2>&1; then - if ! cond_redirect apt-get install --yes software-properties-common; then echo "FAILED (AdoptOpenJDK prerequsites)"; return 1; fi + if ! cond_redirect apt-get install --yes software-properties-common; then echo "FAILED (AdoptOpenJDK prerequisites)"; return 1; fi fi if ! add_keys "https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public"; then return 1; fi diff --git a/functions/java-jre.bats b/functions/java-jre.bats index cd6fb3080..e1c8f2968 100644 --- a/functions/java-jre.bats +++ b/functions/java-jre.bats @@ -9,7 +9,7 @@ load helpers.bash aarch64|arm64|x86_64|amd64) ;; *) skip ;; esac - run java_zulu_prerequsite "Zulu8-64" 3>&- + run java_zulu_prerequisite "Zulu8-64" 3>&- if [ "$status" -ne 0 ]; then echo "$output" >&3; fi [ "$status" -eq 0 ] run java_zulu_fetch "Zulu8-64" 3>&- @@ -27,7 +27,7 @@ load helpers.bash aarch64|arm64|x86_64|amd64) ;; *) skip ;; esac - run java_zulu_prerequsite "Zulu11-64" 3>&- + run java_zulu_prerequisite "Zulu11-64" 3>&- if [ "$status" -ne 0 ]; then echo "$output" >&3; fi [ "$status" -eq 0 ] run java_zulu_fetch "Zulu11-64" 3>&- @@ -41,7 +41,7 @@ load helpers.bash @test "destructive-install_zulu8-32bit" { echo -e "# ${COL_CYAN}$(timestamp) [openHABian] Zulu 8 32-bit Java installation is being (test-)installed...${COL_DEF}" >&3 - run java_zulu_prerequsite "Zulu8-32" 3>&- + run java_zulu_prerequisite "Zulu8-32" 3>&- if [ "$status" -ne 0 ]; then echo "$output" >&3; fi [ "$status" -eq 0 ] run java_zulu_fetch "Zulu8-32" 3>&- @@ -55,7 +55,7 @@ load helpers.bash @test "destructive-install_zulu11-32bit" { echo -e "# ${COL_CYAN}$(timestamp) [openHABian] Zulu 11 32-bit Java installation is being (test-)installed...${COL_DEF}" >&3 - run java_zulu_prerequsite "Zulu11-32" 3>&- + run java_zulu_prerequisite "Zulu11-32" 3>&- if [ "$status" -ne 0 ]; then echo "$output" >&3; fi [ "$status" -eq 0 ] run java_zulu_fetch "Zulu11-32" 3>&- diff --git a/functions/menu.bash b/functions/menu.bash index ea7ff5cd9..755334c4f 100644 --- a/functions/menu.bash +++ b/functions/menu.bash @@ -95,7 +95,7 @@ show_main_menu() { "27 | knxd" "KNX specific, the KNX router/gateway daemon knxd" \ "28 | 1wire" "1wire specific, owserver and related packages" \ "29 | FIND" "Framework for Internal Navigation and Discovery" \ - "2A | Tellstick core" "Driver and daemon for Tellstick usb devices" \ + "2A | Telldus Core" "Telldus Core service for Tellstick USB devices" \ "2C | Mail Transfer Agent" "Install Exim4 as MTA to relay mails via public services" \ 3>&1 1>&2 2>&3) if [ $? -eq 1 ] || [ $? -eq 255 ]; then return 0; fi @@ -110,7 +110,7 @@ show_main_menu() { 27\ *) knxd_setup ;; 28\ *) 1wire_setup ;; 29\ *) find_setup ;; - 2A\ *) tellstick_core_setup ;; + 2A\ *) telldus_core_setup ;; 2C\ *) exim_setup ;; "") return 0 ;; *) whiptail --msgbox "A not supported option was selected (probably a programming error):\\n \"$choice2\"" 8 80 ;; diff --git a/functions/nodejs-apps.bash b/functions/nodejs-apps.bash index 058ef8bee..3ca583c6d 100644 --- a/functions/nodejs-apps.bash +++ b/functions/nodejs-apps.bash @@ -79,7 +79,7 @@ nodered_setup() { if cond_redirect apt-get install --yes build-essential; then echo "OK"; else echo "FAILED"; return 1; fi fi - temp="$(mktemp "${TEMP:-/tmp}"/openhabian.XXXXX)" + temp="$(mktemp "${TMPDIR:-/tmp}"/openhabian.XXXXX)" echo "$(timestamp) [openHABian] Beginning setup of Node-RED... " @@ -104,8 +104,8 @@ nodered_setup() { if cond_redirect npm update -g node-red-contrib-bigtimer; then echo "OK"; else echo "FAILED (update bigtimer addon)"; return 1; fi echo -n "$(timestamp) [openHABian] Setting up Node-RED service... " - if ! systemctl enable nodered.service; then echo "FAILED (enable service)"; return 1; fi - if systemctl restart nodered.service; then echo "OK"; else echo "FAILED (restart service)"; return 1; fi + if ! cond_redirect systemctl enable nodered.service; then echo "FAILED (enable service)"; return 1; fi + if cond_redirect systemctl restart nodered.service; then echo "OK"; else echo "FAILED (restart service)"; return 1; fi if [ -z "$BATS_TEST_NAME" ]; then dashboard_add_tile nodered diff --git a/functions/openhabian.bash b/functions/openhabian.bash index 124b4c5a3..2a74e14e7 100644 --- a/functions/openhabian.bash +++ b/functions/openhabian.bash @@ -10,20 +10,16 @@ get_git_revision() { } apt_update() { - apt-get -q update >/dev/null 2>&1 & + apt-get -q update > /dev/null 2>&1 & PID_APT=$! } wait_for_apt_to_finish_update() { - echo "$(timestamp) [openHABian] Updating Linux package information ... " - if [ ! -v PID_APT ]; then + echo -n "$(timestamp) [openHABian] Updating Linux package information ... " + if [ -z "$PID_APT" ]; then apt_update fi - if wait -f ${PID_APT} 2>/dev/null ; then - echo FAILED - else - echo OK - fi + if timeout 60 tail --pid=$PID_APT -f /dev/null; then echo "OK"; else echo "FAILED"; fi } install_cleanup() { diff --git a/functions/packages.bash b/functions/packages.bash index 83f6c6284..a173928d3 100644 --- a/functions/packages.bash +++ b/functions/packages.bash @@ -1,8 +1,13 @@ #!/usr/bin/env bash +## Function for installing samba for remote access of folders. +## This function can be invoked either INTERACTIVE with userinterface or UNATTENDED. +## +## samba_setup() +## samba_setup() { - echo -n "$(timestamp) [openHABian] Installing Samba... " if ! [ -x "$(command -v samba)" ]; then + echo -n "$(timestamp) [openHABian] Installing Samba... " if cond_redirect apt-get install --yes samba; then echo "OK"; else echo "FAILED"; return 1; fi fi @@ -20,13 +25,20 @@ samba_setup() { if cond_redirect systemctl restart smbd.service; then echo "OK"; else echo "FAILED (restart service)"; return 1; fi } +## Function for installing FireMotD which displays the system overview on login. +## This function can be invoked either INTERACTIVE with userinterface or UNATTENDED. +## +## firemotd_setup() +## firemotd_setup() { local temp - temp="$(mktemp "${TEMP:-/tmp}"/openhabian.XXXXX)" + temp="$(mktemp "${TMPDIR:-/tmp}"/openhabian.XXXXX)" - echo -n "$(timestamp) [openHABian] Installing FireMotD required packages... " - if cond_redirect apt-get install --yes bc sysstat jq moreutils; then echo "OK"; else echo "FAILED"; return 1; fi + if ! dpkg -s 'bc' 'sysstat' 'jq' 'moreutils' > /dev/null 2>&1; then + echo -n "$(timestamp) [openHABian] Installing FireMotD required packages... " + if cond_redirect apt-get install --yes bc sysstat jq moreutils; then echo "OK"; else echo "FAILED"; return 1; fi + fi echo -n "$(timestamp) [openHABian] Downloading FireMotD... " if cond_redirect wget -qO "$temp" https://raw.githubusercontent.com/OutsideIT/FireMotD/master/FireMotD; then @@ -59,23 +71,18 @@ firemotd_setup() { if cond_redirect FireMotD -S; then echo "OK"; else echo "FAILED"; return 1; fi } +## Function for installing and configuring Exim4 as MTA to relay mails via public services. +## This function can only be invoked in INTERACTIVE with userinterface. +## +## exim_setup() +## exim_setup() { - echo -n "$(timestamp) [openHABian] Installing MTA required packages... " - if cond_redirect apt-get install --yes exim4 dnsutils mailutils; then - echo "OK" - create_mta_config - else - echo "FAILED" - return 1 - fi -} - -create_mta_config() { if [ -z "$INTERACTIVE" ]; then echo "$(timestamp) [openHABian] MTA setup must be run in interactive mode! Canceling MTA setup!" echo "CANCELED" return 0 fi + local eximConfig local interfaces local introtext1 @@ -85,36 +92,35 @@ create_mta_config() { local smartHost local temp + if ! dpkg -s 'mailutils' 'exim4' 'dnsutils' > /dev/null 2>&1; then + echo -n "$(timestamp) [openHABian] Installing MTA required packages... " + if cond_redirect apt-get install --yes exim4 dnsutils mailutils; then echo "OK"; else echo "FAILED"; return 1; fi + fi + eximConfig="/etc/exim4/passwd.client" interfaces="$(dig +short "$HOSTNAME" | tr '\n' ';');127.0.0.1;::1" introtext1="We will guide you through the install of exim4 as the mail transfer agent on your system and configure it to relay mails through a public service such as Google gmail.\\n\\nPlease enter the data shown in the next window when being asked for. You will be able to repeat the whole installation if required by selecting the openHABian menu for MTA again." introtext2="Mail server type: mail sent by smarthost (received via SMTP or fetchmail)\\n\\nSystem mail name: FQDN (your full hostname including the domain part)\\n\\nIPs that should be allowed by the server: $interfaces\\n\\nOther destinations for which mail is accepted: $HOSTNAME\\n\\nMachines to relay mail for: Leave empty\\n\\nIP address or host name of outgoing smarthost: smtp.gmail.com::587\\n\\nHide local mail name in outgoing mail: No\\n\\nKeep number of DNS-queries minimal: No\\n\\nDelivery method: Select: Maildir format in home directory\\n\\nMinimize number of DNS queries: No\\n\\nSplit configuration into small files: Yes" - temp="$(mktemp "${TEMP:-/tmp}"/openhabian.XXXXX)" + temp="$(mktemp "${TMPDIR:-/tmp}"/openhabian.XXXXX)" - if ! (whiptail --title "Mail Transfer Agent installation" --yes-button "Begin" --no-button "Cancel" --yesno "$introtext1" 13 80); then echo "CANCELED"; return 0; fi - if ! (whiptail --title "Mail Transfer Agent installation" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext2" 27 80); then echo "CANCELED"; return 0; fi + echo -n "$(timestamp) [openHABian] Beginning Mail Transfer Agent install and setup... " + if ! (whiptail --title "Mail Transfer Agent installation" --yes-button "Begin" --no-button "Cancel" --yesno "$introtext1" 13 80); then echo "CANCELED"; return 1; fi + if (whiptail --title "Mail Transfer Agent installation" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext2" 27 80); then echo "OK"; else echo "CANCELED"; return 1; fi echo "$(timestamp) [openHABian] Reconfiguring exim4-config... " - if cond_redirect dpkg-reconfigure exim4-config; then echo "OK"; else echo "FAILED"; return 1; fi + whiptail --title "exim4 Configuration" --msgbox "exim4-config is about to ask for information, please fill out each line." 7 80 3>&1 1>&2 2>&3 + if dpkg-reconfigure exim4-config; then echo "OK"; else echo "CANCELED"; return 1; fi if ! smartHost=$(whiptail --title "Enter public mail service smarthost to relay your mails to" --inputbox "\\nEnter the list of smarthost(s) to use your account for" 9 80 "*.google.com" 3>&1 1>&2 2>&3); then echo "CANCELED"; return 0; fi if ! relayUser=$(whiptail --title "Enter your public service mail user" --inputbox "\\nEnter the mail username of the public service to relay all outgoing mail to $smartHost" 9 80 "yourname@gmail.com" 3>&1 1>&2 2>&3); then echo "CANCELED"; return 0; fi if ! relayPass=$(whiptail --title "Enter your public service mail password" --passwordbox "\\nEnter the password used to relay mail as ${relayUser}@${smartHost}" 9 80 3>&1 1>&2 2>&3); then echo "CANCELED"; return 0; fi echo "$(timestamp) [openHABian] Creating MTA config... " - if { - grep '^#' "$eximConfig" > "$temp" - echo "${smartHost}:${relayUser}:${relayPass}" >> "$temp" - cp "$temp" "$eximConfig" - chmod o-rwx "$eximConfig" - }; then - echo "OK" - else - echo "FAILED" - rm -f "$temp" - return 1 - fi + if ! grep '^#' "$eximConfig" > "$temp"; then echo "FAILED (configuration)"; rm -f "$temp"; return 1; fi + if ! echo "${smartHost}:${relayUser}:${relayPass}" >> "$temp"; then echo "FAILED (configuration)"; rm -f "$temp"; return 1; fi + if ! cp "$temp" "$eximConfig"; then echo "FAILED (copy)"; rm -f "$temp"; return 1; fi rm -f "$temp" + if chmod o-rwx "$eximConfig"; then echo "OK"; echo "FAILED (permissions)"; return 1; fi echo "$(timestamp) [openHABian] Adding to $relayUser email to system accounts... " if { @@ -123,23 +129,28 @@ create_mta_config() { } >> /etc/email-addresses; then echo "OK"; else echo "FAILED"; return 1; fi } +## Function for installing etckeeper, a git based /etc backup. +## This function can be invoked either INTERACTIVE with userinterface or UNATTENDED. +## +## etckeeper_setup() +## etckeeper_setup() { - echo -n "$(timestamp) [openHABian] Installing etckeeper (git based /etc backup)... " - if cond_redirect apt-get install --yes etckeeper; then echo "OK"; else echo "FAILED"; return 1; fi + if ! [ -x "$(command -v etckeeper)" ]; then + echo -n "$(timestamp) [openHABian] Installing etckeeper (git based /etc backup)... " + if cond_redirect apt-get install --yes etckeeper; then echo "OK"; else echo "FAILED"; return 1; fi + fi echo -n "$(timestamp) [openHABian] Configuring etckeeper (git based /etc backup)... " - if { - sed -i 's/VCS="bzr"/\#VCS="bzr"/g' /etc/etckeeper/etckeeper.conf - sed -i 's/\#VCS="git"/VCS="git"/g' /etc/etckeeper/etckeeper.conf - bash -c "cd /etc && etckeeper init && git config user.email 'etckeeper@localhost' && git config user.name 'openhabian' && git commit -m 'initial checkin' && git gc" - }; then - echo "OK" - else - echo "FAILED" - return 1 - fi + if ! cond_redirect sed -i 's/VCS="bzr"/\#VCS="bzr"/g' /etc/etckeeper/etckeeper.conf; then echo "FAILED"; return 1; fi + if ! cond_redirect sed -i 's/\#VCS="git"/VCS="git"/g' /etc/etckeeper/etckeeper.conf; then echo "FAILED"; return 1; fi + if cond_redirect bash -c "cd /etc && etckeeper init && git config user.email 'etckeeper@localhost' && git config user.name 'openhabian' && git commit -m 'initial checkin' && git gc"; then echo "OK"; else echo "FAILED"; return 1; fi } +## Function for installing Homegear, the Homematic CCU2 emulation software. +## This function can be invoked either INTERACTIVE with userinterface or UNATTENDED. +## +## homegear_setup() +## homegear_setup() { local introtext local myOS @@ -165,7 +176,7 @@ homegear_setup() { return 1 fi if [ -n "$INTERACTIVE" ]; then - if ! (whiptail --title "Homegear installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 8 80); then echo "CANCELED"; return 0; fi + if (whiptail --title "Homegear installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 8 80); then echo "OK"; else echo "CANCELED"; return 0; fi fi if ! add_keys "https://apt.homegear.eu/Release.key"; then return 1; fi @@ -190,6 +201,11 @@ homegear_setup() { fi } +## Function for installing MQTT Eclipse Mosquitto through the official repository. +## This function can be invoked either INTERACTIVE with userinterface or UNATTENDED. +## +## mqtt_setup() +## mqtt_setup() { local introtext local mqttpasswd @@ -204,11 +220,13 @@ mqtt_setup() { echo -n "$(timestamp) [openHABian] Beginning the MQTT broker Eclipse Mosquitto installation... " if [ -n "$INTERACTIVE" ]; then - if ! (whiptail --title "MQTT installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 14 80); then echo "CANCELED"; return 0; fi + if (whiptail --title "MQTT installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 14 80); then echo "OK"; else echo "CANCELED"; return 0; fi fi - echo -n "$(timestamp) [openHABian] Installing MQTT... " - if cond_redirect apt-get install --yes mosquitto mosquitto-clients; then echo "OK"; else echo "FAILED"; return 1; fi + if ! dpkg -s 'mosquitto' 'mosquitto-clients' > /dev/null 2>&1; then + echo -n "$(timestamp) [openHABian] Installing MQTT... " + if cond_redirect apt-get install --yes mosquitto mosquitto-clients; then echo "OK"; else echo "FAILED"; return 1; fi + fi echo -n "$(timestamp) [openHABian] Configuring MQTT... " if [ -n "$INTERACTIVE" ]; then @@ -235,6 +253,11 @@ mqtt_setup() { fi } +## Function for installing FIND to allow for indoor localization of WiFi devices. +## This function can only be invoked in INTERACTIVE with userinterface. +## +## find_setup() +## find_setup() { if [ -z "$INTERACTIVE" ]; then echo "$(timestamp) [openHABian] FIND setup must be run in interactive mode! Canceling FIND setup!" @@ -259,8 +282,10 @@ find_setup() { local successtext local temp - echo -n "$(timestamp) [openHABian] Installing FIND required packages... " - if cond_redirect apt-get install --yes libsvm-tools; then echo "OK"; else echo "FAILED"; return 1; fi + if ! dpkg -s 'libsvm-tools' > /dev/null 2>&1; then + echo -n "$(timestamp) [openHABian] Installing FIND required packages... " + if cond_redirect apt-get install --yes libsvm-tools; then echo "OK"; else echo "FAILED"; return 1; fi + fi brokertext="You've chosen to work with an external MQTT broker.\\n\\nPlease be aware that you might need to add authentication credentials. You can do so after the installation.\\n\\nConsult with the FIND documentation or the openHAB community for details." if is_arm; then @@ -275,15 +300,15 @@ find_setup() { mqttmissingtext="FIND requires an MQTT broker to run, but Mosquitto could not be found on this system.\\n\\nYou can configure FIND to use any existing MQTT broker (in the next step) or you can go back and install Mosquitto from the openHABian menu.\\n\\nDo you want to continue with the FIND installation?" mqttpasswd="/etc/mosquitto/passwd" successtext="FIND setup was successful.\\n\\nSettings can be configured in '/etc/default/findserver'. Be sure to restart the service after.\\n\\nYou can obtain the FIND app for Android through the Play Store. There is no iOS app available, for more information see: https://www.internalpositioning.com/faq/#can-i-use-an-iphone\\n\\nCheck out your FIND server's dashboard at: http://${HOSTNAME}:8003\\n\\nFor further information: https://www.internalpositioning.com" - temp="$(mktemp -d "${TEMP:-/tmp}"/openhabian.XXXXX)" + temp="$(mktemp -d "${TMPDIR:-/tmp}"/openhabian.XXXXX)" - echo -n "$(timestamp) [openHABian] Beginning setup of FIND, the Framework for Internal Navigation and Discovery... " + echo "$(timestamp) [openHABian] Beginning setup of FIND, the Framework for Internal Navigation and Discovery... " if [ ! -f "/etc/mosquitto/mosquitto.conf" ]; then if ! (whiptail --defaultno --title "Mosquitto not installed, continue?" --yes-button "Continue" --no-button "Cancel" --yesno "$mqttmissingtext" 13 80); then echo "CANCELED"; return 0; fi fi - if ! (whiptail --title "FIND installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 14 80); then echo "CANCELED"; return 0; fi + if (whiptail --title "FIND installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 14 80); then echo "OK"; else echo "CANCELED"; return 0; fi echo -n "$(timestamp) [openHABian] Configuring FIND... " if ! MQTTSERVER=$(whiptail --title "FIND Setup" --inputbox "\\nPlease enter the hostname of the device your MQTT broker is running on:" 9 80 localhost 3>&1 1>&2 2>&3); then echo "CANCELED"; return 0; fi @@ -311,7 +336,7 @@ find_setup() { if ! cond_redirect mkdir -p "$findDist"; then echo "FAILED (create directory)"; return 1; fi if ! cond_redirect wget -qO "${temp}/find.zip" "$findRelease"; then echo "FAILED (fetch FIND)"; return 1; fi if ! cond_redirect wget -qO "${temp}/client.zip" "$findClient"; then echo "FAILED (fetch client)"; return 1; fi - if ! cond_redirect unzip -qo "${temp}/find.zip" "$findDist"; then echo "FAILED (unzip FIND)"; return 1; fi + if ! cond_redirect unzip -qo "${temp}/find.zip" -d "$findDist"; then echo "FAILED (unzip FIND)"; return 1; fi if ! cond_redirect unzip -qo "${temp}/client.zip" fingerprint -d "$findDist"; then echo "FAILED (unzip client)"; return 1; fi if ! cond_redirect ln -sf "$findDist"/findserver /usr/sbin/findserver; then echo "FAILED (link findserver)"; return 1; fi if ! cond_redirect ln -sf "$findDist"/fingerprint /usr/sbin/fingerprint; then echo "FAILED (link fingerprint)"; return 1; fi @@ -330,6 +355,11 @@ find_setup() { fi } +## Function for installing kndx as your EIB/KNX IP gateway and router to support your KNX bus system. +## This function can be invoked either INTERACTIVE with userinterface or UNATTENDED. +## +## knxd_setup() +## knxd_setup() { local introtext local successtext @@ -337,24 +367,29 @@ knxd_setup() { introtext="This will install and setup kndx (successor to eibd) as your EIB/KNX IP gateway and router to support your KNX bus system.\\n\\nThis routine was provided by 'Michels Tech Blog': https://bit.ly/3dzeoKh" successtext="Setup was successful.\\n\\nPlease edit '/etc/default/knxd' to meet your interface requirements. For further information on knxd options, please type 'knxd --help'\\n\\nFurther details can be found under: https://bit.ly/3dzeoKh\\n\\nIntegration into openHAB 2 is described here: https://github.com/openhab/openhab/wiki/KNX-Binding" - temp="$(mktemp -d "${TEMP:-/tmp}"/openhabian.XXXXX)" + temp="$(mktemp "${TMPDIR:-/tmp}"/openhabian.XXXXX)" echo -n "$(timestamp) [openHABian] Beginning setup of EIB/KNX IP Gateway and Router with knxd (https://bit.ly/3dzeoKh)... " if [ -n "$INTERACTIVE" ]; then - if ! (whiptail --title "knxd installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 10 80); then echo "CANCELED"; return 0; fi + if (whiptail --title "knxd installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 10 80); then echo "OK"; else echo "CANCELED"; return 0; fi fi echo -n "$(timestamp) [openHABian] Installing knxd... " # TODO: serve file from the repository if ! cond_redirect wget -qO "$temp" https://michlstechblog.info/blog/download/electronic/install_knxd_systemd.sh; then echo "FAILED (fetch installer)"; return 1; fi # NOTE: install_knxd_systemd.sh currently does not give proper exit status for errors, so installer claims success... - if cond_redirect bash "$temp"; then echo "OK. Please restart your system now..."; else echo "FAILED (install)"; fi + if cond_redirect bash "$temp"; then rm -f "$temp"; echo "OK. Please restart your system now..."; else echo "FAILED (install)"; fi if [ -n "$INTERACTIVE" ]; then whiptail --title "Operation Successful!" --msgbox "$successtext" 15 80 fi } +## Function for installing owserver to support 1wire functionality. +## This function can be invoked either INTERACTIVE with userinterface or UNATTENDED. +## +## 1wire_setup() +## 1wire_setup() { local introtext local successtext @@ -364,24 +399,33 @@ knxd_setup() { echo -n "$(timestamp) [openHABian] Beginning setup of owserver (1wire)... " if [ -n "$INTERACTIVE" ]; then - if ! (whiptail --title "1wire installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 12 80); then echo "CANCELED"; return 0; fi + if (whiptail --title "1wire installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 12 80); then echo "OK"; else echo "CANCELED"; return 0; fi fi - echo -n "$(timestamp) [openHABian] Installing owserver (1wire)... " - if cond_redirect apt-get install --yes owserver ow-shell usbutils; then echo "OK"; else echo "FAILED"; return 1; fi + if ! dpkg -s 'owserver' 'ow-shell' 'usbutils' > /dev/null 2>&1; then + echo -n "$(timestamp) [openHABian] Installing owserver (1wire)... " + if cond_redirect apt-get install --yes owserver ow-shell usbutils; then echo "OK"; else echo "FAILED"; return 1; fi + fi if [ -n "$INTERACTIVE" ]; then whiptail --title "Operation Successful!" --msgbox "$successtext" 17 80 fi } +## Function for installing miflora-mqtt-daemon - The Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon. +## This function can be invoked either INTERACTIVE with userinterface or UNATTENDED. +## +## miflora_setup() +## miflora_setup() { local introtext local mifloraDir local successtext - echo -n "$(timestamp) [openHABian] Installing miflora-mqtt-daemon required packages... " - if cond_redirect apt-get install --yes git python3 python3-pip bluetooth bluez; then echo "OK"; else echo "FAILED"; return 1; fi + if ! dpkg -s 'git' 'python3' 'python3-pip' 'bluetooth' 'bluez' > /dev/null 2>&1; then + echo -n "$(timestamp) [openHABian] Installing miflora-mqtt-daemon required packages... " + if cond_redirect apt-get install --yes git python3 python3-pip bluetooth bluez; then echo "OK"; else echo "FAILED"; return 1; fi + fi introtext="[CURRENTLY BROKEN] This will install or update miflora-mqtt-daemon - The Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon.\\n\\nFor further details see:\\nhttps://github.com/ThomDietrich/miflora-mqtt-daemon" mifloraDir="/opt/miflora-mqtt-daemon" @@ -389,22 +433,23 @@ miflora_setup() { echo -n "$(timestamp) [openHABian] Beginning setup of miflora-mqtt-daemon... " if [ -n "$INTERACTIVE" ]; then - if ! (whiptail --title "miflora-mqtt-daemon installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 11 80); then echo "CANCELED"; return 0; fi + if (whiptail --title "miflora-mqtt-daemon installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 11 80); then echo "OK"; else echo "CANCELED"; return 0; fi fi echo -n "$(timestamp) [openHABian] Setting up miflora-mqtt-daemon... " if ! [ -d "$mifloraDir" ]; then - cond_echo "Fresh Installation... " + cond_echo "\nFresh Installation... " if ! cond_redirect git clone https://github.com/ThomDietrich/miflora-mqtt-daemon.git $mifloraDir; then echo "FAILED (git clone)"; return 1; fi - if ! cond_redirect cp "$mifloraDir"/config.{ini.dist,ini}; then echo "FAILED (copy files)"; return 1; fi + if cond_redirect cp "$mifloraDir"/config.{ini.dist,ini}; then echo "OK"; else echo "FAILED (copy files)"; return 1; fi else - cond_echo "Update... " - if ! cond_redirect git -C "$mifloraDir" pull --quiet origin; then echo "FAILED (git pull)"; return 1; fi + cond_echo "\nUpdate... " + if cond_redirect git -C "$mifloraDir" pull --quiet origin; then echo "OK"; else echo "FAILED (git pull)"; return 1; fi fi - if ! { - cond_redirect chown -R "openhab:${username:-openhabian}" "$mifloraDir" - cond_redirect chmod -R ug+wX "$mifloraDir" - }; then echo "FAILED (permissons)"; fi + + cond_echo "Filesystem permissions corrections... " + if ! cond_redirect chown -R "openhab:${username:-openhabian}" "$mifloraDir"; then echo "FAILED (permissons)"; fi + if ! cond_redirect chmod -R ug+wX "$mifloraDir"; then echo "FAILED (permissons)"; fi + cond_echo "Installing required python packages" if ! cond_redirect pip3 install -r "$mifloraDir"/requirements.txt; then echo "OK"; else echo "FAILED (python packages)"; return 1; fi @@ -422,6 +467,11 @@ miflora_setup() { fi } +## Function for installing Nginx to allow for secure interaction with openHAB over the network. +## This function can only be invoked in INTERACTIVE with userinterface. +## +## nginx_setup() +## nginx_setup() { if [ -z "$INTERACTIVE" ]; then echo "$(timestamp) [openHABian] Nginx setup must be run in interactive mode! Canceling Nginx setup!" @@ -464,8 +514,8 @@ nginx_setup() { if ! sed -e "/$1/s/^$1//g" -i "$2"; then echo "FAILED (uncomment)"; fi } - echo "$(timestamp) [openHABian] Beginning setup of Nginx as reverse proxy with authentication... " - if ! (whiptail --title "Nginx installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 9 80); then echo "CANCELED"; return 0; fi + echo -n "$(timestamp) [openHABian] Beginning setup of Nginx as reverse proxy with authentication... " + if (whiptail --title "Nginx installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 9 80); then echo "OK"; else echo "CANCELED"; return 0; fi echo "$(timestamp) [openHABian] Configuring Nginx authentication options... " if (whiptail --title "Authentication Setup" --yesno "Would you like to secure your openHAB interface with username and password?" 7 80); then @@ -540,19 +590,17 @@ nginx_setup() { confirmtext="The following settings have been chosen:\\n\\n- $authtext\\n- $httpstext\\n- Domain: $domain (Public IP Address: $pubIP)\\n\\nYou will be able to connect to openHAB on the default $protocol port.\\n\\n${portwarning}Do you wish to continue and setup an Nginx server now?" if ! (whiptail --title "Confirmation" --yesno "$confirmtext" 20 80); then echo "CANCELED"; return 0; fi - echo -n "$(timestamp) [openHABian] Installing Nginx..." - if cond_redirect apt-get install --yes install nginx; then echo "OK"; else echo "FAILED"; return 1; fi + echo -n "$(timestamp) [openHABian] Installing Nginx... " + if cond_redirect apt-get install --yes nginx; then echo "OK"; else echo "FAILED"; return 1; fi - echo -n "$(timestamp) [openHABian] Setting up Nginx configuration..." - if { - rm -rf /etc/nginx/sites-enabled/default - cp "$BASEDIR"/includes/nginx.conf /etc/nginx/sites-enabled/openhab - sed -i "s/DOMAINNAME/${domain}/g" /etc/nginx/sites-enabled/openhab - }; then echo "OK"; else echo "FAILED"; fi + echo -n "$(timestamp) [openHABian] Setting up Nginx configuration... " + if ! rm -rf /etc/nginx/sites-enabled/default; then echo "FAILED (remove default)"; return 1; fi + if ! cp "$BASEDIR"/includes/nginx.conf /etc/nginx/sites-enabled/openhab; then echo "FAILED (copy configuration)"; return 1; fi + if sed -i "s/DOMAINNAME/${domain}/g" /etc/nginx/sites-enabled/openhab; then echo "OK"; else echo "FAILED (set domain name)"; fi if [ "$auth" == "true" ]; then cond_echo "Setting up Nginx password options..." - echo -n "$(timestamp) [openHABian] Installing Nginx password utilities..." + echo -n "$(timestamp) [openHABian] Installing Nginx password utilities... " if cond_redirect apt-get install --yes install apache2-utils; then echo "OK"; else echo "FAILED"; return 1; fi if cond_redirect htpasswd -b -c /etc/nginx/.htpasswd "$nginxUsername" "$nginxPass"; then echo "OK"; else echo "FAILED (password file)"; return 1; fi uncomment "#AUTH" /etc/nginx/sites-enabled/openhab @@ -561,7 +609,7 @@ nginx_setup() { if [ "$secure" == "true" ]; then cond_echo "Setting up Nginx security options..." if [ "$validDomain" == "true" ]; then - echo -n "$(timestamp) [openHABian] Installing certbot..." + echo -n "$(timestamp) [openHABian] Installing certbot... " if is_ubuntu; then if ! dpkg -s 'software-properties-common' > /dev/null 2>&1; then if ! cond_redirect apt-get install --yes software-properties-common; then echo "FAILED (Ubuntu prerequsites)"; return 1; fi @@ -572,18 +620,16 @@ nginx_setup() { fi if cond_redirect apt-get install --yes certbot python3-certbot-nginx; then echo "OK"; else echo "FAILED"; return 1; fi - echo -n "$(timestamp) [openHABian] Configuring certbot..." + echo -n "$(timestamp) [openHABian] Configuring certbot... " mkdir -p /var/www/"$domain" uncomment "#WEBROOT" /etc/nginx/sites-enabled/openhab - if ! { - nginx -t - systemctl reload nginx - }; then echo "FAILED (Nginx reload)"; fi + if ! nginx -t; then echo "FAILED (Nginx configuration test)"; fi + if ! cond_redirect systemctl reload nginx; then echo "FAILED (Nginx reload)"; fi if cond_redirect certbot certonly --webroot -w /var/www/"$domain" -d "$domain"; then echo "OK"; else echo "FAILED"; return 1; fi certpath="/etc/letsencrypt/live/${domain}/fullchain.pem" keypath="/etc/letsencrypt/live/${domain}/privkey.pem" else - echo -n "$(timestamp) [openHABian] Configuring openSSL..." + echo -n "$(timestamp) [openHABian] Configuring openSSL... " mkdir -p /etc/ssl/certs certpath="/etc/ssl/certs/openhab.crt" keypath="/etc/ssl/certs/openhab.key" @@ -598,10 +644,8 @@ nginx_setup() { uncomment "#SSL" /etc/nginx/sites-enabled/openhab fi - if ! { - nginx -t - systemctl restart nginx.service - }; then echo "FAILED (Nginx service)"; fi + if ! nginx -t; then echo "FAILED (Nginx configuration test)"; fi + if ! cond_redirect systemctl restart nginx; then echo "FAILED (Nginx restart)"; fi whiptail --title "Operation Successful!" --msgbox "Setup successful. Please try entering $protocol://$domain in a browser to test your settings." 8 80 } @@ -614,13 +658,15 @@ nginx_setup() { telldus_core_setup() { local introtext local successtext + local telldusDir introtext="This will install Telldus Core services to enable support for USB devices connected Tellstick and Tellstick duo." successtext="Success, please reboot your system to complete the installation.\\n\\nNext, add your devices in /etc/tellstick.conf.\\n\\nTo detect device IDs issue the command:\\n- tdtool-improved --event\\n\\nWhen devices are added, restart telldusd.service by rebooting the system or using:\\n- sudo systemctl restart telldusd.service" + telldusDir="/opt/tdtool-improved" echo -n "$(timestamp) [openHABian] Beginning setup of Telldus Core... " if [ -n "$INTERACTIVE" ]; then - if ! (whiptail --title "Telldus Core installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 8 80); then echo "CANCELED"; return 0; fi + if (whiptail --title "Telldus Core installation?" --yes-button "Continue" --no-button "Cancel" --yesno "$introtext" 8 80); then echo "OK"; else echo "CANCELED"; return 0; fi fi if is_aarch64 ; then @@ -628,16 +674,18 @@ telldus_core_setup() { fi # Maybe add new repository to be able to install libconfuse1 - echo -n "$(timestamp) [openHABian] Adding libconfuse1 repository to apt... " # libconfuse1 is only available from old stretch repos, but currently still needed - if is_buster ; then + if is_buster; then + echo -n "$(timestamp) [openHABian] Adding libconfuse1 repository to apt... " echo 'APT::Default-Release "buster";' > /etc/apt/apt.conf.d/01release if is_raspbian ; then echo "deb http://raspbian.raspberrypi.org/raspbian/ stretch main" > /etc/apt/sources.list.d/raspbian-stretch.list else echo "deb http://deb.debian.org/debian stretch main" > /etc/apt/sources.list.d/debian-stretch.list fi + echo "OK" fi + echo -n "$(timestamp) [openHABian] Installing libconfuse1... " if ! cond_redirect apt-get update; then echo "FAILED (update apt lists)"; return 1; fi if cond_redirect apt-get install --yes --target-release "stretch" libconfuse1; then echo "OK"; else echo "FAILED"; fi @@ -652,13 +700,19 @@ telldus_core_setup() { echo -n "$(timestamp) [openHABian] Setting up telldus-core service... " cp "$BASEDIR"/includes/telldusd.service /lib/systemd/system/telldusd.service - if ! systemctl enable telldusd.service; then echo "FAILED (enable service)"; return 1; fi - if systemctl restart telldusd.service; then echo "OK"; else echo "FAILED (restart service)"; return 1; fi + if ! cond_redirect systemctl enable telldusd.service; then echo "FAILED (enable service)"; return 1; fi + if cond_redirect systemctl restart telldusd.service; then echo "OK"; else echo "FAILED (restart service)"; return 1; fi echo -n "$(timestamp) [openHABian] Setting up tdtool-improved... " - if ! cond_redirect git clone https://github.com/EliasGabrielsson/tdtool-improved.py.git /opt/tdtool-improved; then echo "FAILED (clone)"; fi + if ! [ -d "$telldusDir" ]; then + cond_echo "\nFresh Installation... " + if ! cond_redirect git clone https://github.com/EliasGabrielsson/tdtool-improved.py.git $telldusDir; then echo "FAILED (git clone)"; return 1; fi + else + cond_echo "\nUpdate... " + if ! cond_redirect git -C "$telldusDir" pull --quiet origin; then echo "FAILED (git pull)"; return 1; fi + fi chmod +x /opt/tdtool-improved/tdtool-improved.py - if ! cond_redirect ln -sf /opt/tdtool-improved/tdtool-improved.py /usr/bin/tdtool-improved; then echo "OK"; else echo "FAILED (link)"; fi + if cond_redirect ln -sf /opt/tdtool-improved/tdtool-improved.py /usr/bin/tdtool-improved; then echo "OK"; else echo "FAILED (link)"; return 1; fi if [ -n "$INTERACTIVE" ]; then whiptail --title "Operation Successful!" --msgbox "$successtext" 16 80 diff --git a/test.bash b/test.bash index 2e877a47e..d55e28c85 100755 --- a/test.bash +++ b/test.bash @@ -8,7 +8,7 @@ set -e # Log with timestamp timestamp() { date +"%F_%T_%Z"; } -## This function format log messages +## This function formats log messages ## ## echo_process(String message) ## @@ -30,21 +30,25 @@ cond_redirect() { # What test case should be run? if [ "$1" == "docker-full" ]; then - echo_process "Starting Docker based test..." + echo_process "Starting Docker installation test for amd64..." cond_redirect docker stop install-test || true cond_redirect docker rm install-test || true - cond_redirect docker build --tag openhabian/openhabian-bats . - cond_redirect docker run -it openhabian/openhabian-bats bash -c 'bats -r -f "unit-." .' - cond_redirect docker run --name "install-test" --privileged -d openhabian/openhabian-bats - cond_redirect docker exec -it install-test bash -c "./build.bash local-test && mv ~/.profile ~/.bash_profile && /etc/rc.local" - cond_redirect docker exec -it install-test bash -c 'bats -r -f "installation-." .' - cond_redirect docker exec -it install-test bash -c 'bats -r -f "destructive-." .' + cond_redirect docker build --tag openhabian/install-openhabian -f Dockerfile.amd64 . + cond_redirect docker run --name "install-test" --privileged -d openhabian/install-openhabian + cond_redirect docker exec -i "install-test" bash -c "./build.bash local-test && mv ~/.profile ~/.bash_profile && /etc/rc.local" echo_process "Test complete, please review result in terminal. Access tested container by executing: \"docker exec -it install-test bash\"" + + echo_process "Starting Docker BATS tests for amd64..." + cond_redirect docker build --tag openhabian/bats-openhabian -f Dockerfile.amd64 . + cond_redirect docker run --rm --name "unit-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "unit-." .' + cond_redirect docker run --rm --name "installation-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "installation-." .' + cond_redirect docker run --rm --name "destructive-tests" -i openhabian/bats-openhabian bash -c 'bats --tap --recursive --filter "destructive-." .' + cond_redirect echo_process "Test complete, please review result in terminal." exit 0 elif [ "$1" == "shellcheck" ]; then - shellcheck -s bash openhabian-setup.sh - shellcheck -s bash functions/*.bash - shellcheck -s bash build-image/*.bash + shellcheck -x -s bash openhabian-setup.sh + shellcheck -x -s bash functions/*.bash + shellcheck -x -s bash build-image/*.bash elif [ "$1" == "travis" ]; then # prepare configuration for tests, select debug level here: sed -i 's#debugmode=.*$#debugmode=on#' build-image/openhabian.conf