Merge pull request #13 from hassio-addons/repository-restructure

Repository restructure
This commit is contained in:
Franck Nijhof 2017-08-20 15:09:59 +02:00 committed by GitHub
commit 59e4a1c3ca
35 changed files with 65 additions and 3107 deletions

View file

@ -1,3 +1,9 @@
**NOTE**
This is the main repository. If you have problems with one of our add-ons,
then _PLEASE DO NOT_ create an issue in this GitHub project. Instead,
create an issue in the project that goes with the specific addon.
## Problem/Motivation
> (Why the issue was filed)

View file

@ -1,4 +1,4 @@
# Third party Hass.io add-ons for Home Assistant
# Community Hass.io add-ons for Home Assistant
![Project Stage][project-stage-shield]
![Maintenance][maintenance-shield]
@ -25,7 +25,7 @@ https://github.com/hassio-addons/repository
## Add-ons provided by this repository
### ✓ [Homebridge](homebridge)
### ✓ [Homebridge][addon-homebridge]
![Latest Version][homebridge-version-shield]
![Supports armhf Architecture][homebridge-armhf-shield]
@ -37,9 +37,9 @@ https://github.com/hassio-addons/repository
Homebridge is a server that emulates the iOS HomeKit API, allowing you to
control your Home Assistant through via Apple devices (including Siri).
[:books: Homebridge add-on documentation](homebridge)
[:books: Homebridge add-on documentation][addon-homebridge]
### ✓ [SSH - Secure Shell](ssh)
### ✓ [SSH - Secure Shell][addon-ssh]
![Latest Version][ssh-version-shield]
![Supports armhf Architecture][ssh-armhf-shield]
@ -50,11 +50,11 @@ control your Home Assistant through via Apple devices (including Siri).
Log in to your Hass.io Home Assistant instance using SSH.
This is an enhanced version of the provided SSH add-on by Home Assistant and
focusses on security, usability and flexibility.
focusses on security, usability, and flexibility.
[:books: SSH add-on documentation](ssh)
[:books: SSH add-on documentation][addon-ssh]
### ✓ [Terminal](terminal)
### ✓ [Terminal][addon-terminal]
![Latest Version][terminal-version-shield]
![Supports armhf Architecture][terminal-armhf-shield]
@ -64,15 +64,36 @@ focusses on security, usability and flexibility.
![Docker Pulls][terminal-pulls-shield]
This add-on allows you to log in to your Hass.io Home Assistant instance using
a web terminal. It is like SSH, but in your Home Assistant frontend.
a web terminal. It is like SSH but in your Home Assistant frontend.
[:books: Terminal add-on documentation](terminal)
[:books: Terminal add-on documentation][addon-terminal]
## Changelog
This add-on repository itself does not keep a change log, the individual
add-ons, however, do. The format is based on [Keep a Changelog][keepchangelog]
and these add-ons adheres to [Semantic Versioning][semver].
moreover, these add-ons adhere to [Semantic Versioning][semver].
## Support
Got questions?
You have several options to get them answered:
- The Home Assistant [Community Forums][forums], we have a
[dedicated topic][forums] on that forum regarding this repository.
- The Home Assistant [Discord Chat Server][discord] for general Home Assistant
discussions and questions.
- Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit]
You could also open an issue here on GitHub. Note, we use a separate
GitHub repository for each add-on. Please ensure you are creating the issue
on the correct GitHub repository matching the add-on.
- [Open an issue for the addon: Homebridge][homebridge-issue]
- [Open an issue for the addon: SSH - Secure Shell][ssh-issue]
- [Open an issue for the addon: Terminal][terminal-issue]
- For a general repository issues or add-on ideas [open a issue here][issue]
## Contributing
@ -84,7 +105,7 @@ We've set up a separate document for our [contribution guidelines](CONTRIBUTING.
Thank you for being involved! :heart_eyes:
We are also looking for maintainers!
Please send [Franck Nijhof][frenck] an message when you are interested in becoming one.
Please send [Franck Nijhof][frenck] a message when you are interested in becoming one.
## Authors & contributors
@ -117,30 +138,40 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
[issue]: https://github.com/hassio-addons/repository/issues
[addon-homebridge]: https://github.com/hassio-addons/addon-homebridge
[addon-ssh]: https://github.com/hassio-addons/addon-ssh
[addon-terminal]: https://github.com/hassio-addons/addon-terminal
[awesome-shield]: https://img.shields.io/badge/awesome%3F-yes-brightgreen.svg
[contributors]: https://github.com/hassio-addons/repository/graphs/contributors
[frenck]: https://github.com/frenck
[discord]: https://discord.gg/c5DvZ4e
[forums]: https://community.home-assistant.io/t/repository-community-hass-io-add-ons/24705?u=frenck
[frenck]: https://community.home-assistant.io/u/frenck/summary
[homebridge-aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg
[homebridge-amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg
[homebridge-armhf-shield]: https://img.shields.io/badge/armhf-yes-green.svg
[homebridge-i386-shield]: https://img.shields.io/badge/i386-yes-green.svg
[homebridge-issue]: https://github.com/hassio-addons/addon-homebridge/issues
[homebridge-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/homebridge-armhf.svg
[homebridge-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/homebridge-armhf.svg
[keepchangelog]: http://keepachangelog.com/en/1.0.0/
[license-shield]: https://img.shields.io/github/license/hassio-addons/repository.svg
[maintenance-shield]: https://img.shields.io/maintenance/yes/2017.svg
[project-stage-shield]: https://img.shields.io/badge/Project%20Stage-Development-yellowgreen.svg
[reddit]: https://reddit.com/r/homeassistant
[semver]: http://semver.org/spec/v2.0.0.html
[ssh-aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg
[ssh-amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg
[ssh-armhf-shield]: https://img.shields.io/badge/armhf-yes-green.svg
[ssh-i386-shield]: https://img.shields.io/badge/i386-yes-green.svg
[ssh-issue]: https://github.com/hassio-addons/addon-ssh/issues
[ssh-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/ssh-armhf.svg
[ssh-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/ssh-armhf.svg
[terminal-aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg
[terminal-amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg
[terminal-armhf-shield]: https://img.shields.io/badge/armhf-yes-green.svg
[terminal-i386-shield]: https://img.shields.io/badge/i386-yes-green.svg
[terminal-issue]: https://github.com/hassio-addons/addon-terminal/issues
[terminal-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/terminal-armhf.svg
[terminal-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/terminal-armhf.svg
[third-party-addons]: https://home-assistant.io/hassio/installing_third_party_addons/

View file

@ -1,8 +0,0 @@
#!/bin/bash
set -e
for arch in "armhf" "aarch64" "i386" "amd64"
do
./bin/create_hassio_addon.sh -a $arch "$@" &
done
wait

View file

@ -1,173 +0,0 @@
#!/bin/bash
set -e
BUILD_CONTAINER_NAME=hassio-addons-$$
DOCKER_PUSH="true"
DOCKER_CACHE="true"
DOCKER_WITH_LATEST="true"
BRANCH=master
REPOSITORY=https://github.com/hassio-addons/repository
cleanup() {
echo "[INFO] Cleanup."
# Stop docker container
echo "[INFO] Cleaning up hassio-build container."
docker stop $BUILD_CONTAINER_NAME 2> /dev/null || true
docker rm --volumes $BUILD_CONTAINER_NAME 2> /dev/null || true
if [ "$1" == "fail" ]; then
exit 1
fi
}
trap 'cleanup fail' SIGINT SIGTERM
help () {
cat << EOF
Script for hassio addon docker build
create_hassio_addon [options]
Options:
-h, --help
Display this help and exit.
-r, --repository https://.../addons
Set git repository to load addon from.
-b, --branch branch_name
Set git branch to load addon from.
-l, --local /path/to/repository
Load addon from a local folder
-s, --slug addon_slug
Name of folder/slug
-a, --arch armhf|aarch64|i386|amd64
Arch for addon build.
-t, --test
Don't upload the build to docker hub.
-n, --no-cache
Disable build from cache
EOF
}
# Parse arguments
while [[ $# -gt 0 ]]; do
key=$1
case $key in
-h|--help)
help
exit 0
;;
-r|--repository)
REPOSITORY=$2
shift
;;
-b|--branch)
BRANCH=$2
shift
;;
-l|--local)
LOCAL_REPOSITORY=$2
shift
;;
-s|--slug)
SLUG=$2
shift
;;
-a|--arch)
ARCH=$2
shift
;;
-t|--test)
DOCKER_PUSH="false"
;;
-n|--no-cache)
DOCKER_CACHE="false"
;;
*)
echo "[WARNING] $0 : Argument '$1' unknown. Ignoring."
;;
esac
shift
done
# Sanity checks
if [ "$ARCH" != 'armhf' ] && [ "$ARCH" != 'aarch64' ] && [ "$ARCH" != 'i386' ] && [ "$ARCH" != 'amd64' ]; then
echo "Error: $ARCH is not a supported platform for hassio-supervisor!"
help
exit 1
fi
if [ -z "$SLUG" ]; then
echo "[ERROR] please set a slug!"
help
exit 1
fi
# Get the absolute script location
pushd "$(dirname "$0")" > /dev/null 2>&1
SCRIPTPATH=$(pwd)
popd > /dev/null 2>&1
BASE_IMAGE="homeassistant\/$ARCH-base:latest"
BUILD_DIR=${BUILD_DIR:=$SCRIPTPATH}
WORKSPACE=${BUILD_DIR:=$SCRIPTPATH}/hassio-supervisor-$ARCH
ADDON_WORKSPACE=$WORKSPACE/$SLUG
# setup docker
echo "[INFO] cleanup old WORKSPACE"
rm -rf "$ADDON_WORKSPACE"
echo "[INFO] Setup docker for addon"
mkdir -p "$BUILD_DIR"
mkdir -p "$WORKSPACE"
if [ -z "$LOCAL_REPOSITORY" ]; then
git clone "$REPOSITORY" "$WORKSPACE"
cd "$WORKSPACE"; git checkout "$BRANCH"
if [ ! -d "$ADDON_WORKSPACE" ]; then
echo "Error: $ADDON not found inside Repo!"
exit 1
fi
else
cp -r "$LOCAL_REPOSITORY/$SLUG" "$ADDON_WORKSPACE"
fi
# Init docker
echo "[INFO] Setup dockerfile"
sed -i "s/{arch}/${ARCH}/g" "$ADDON_WORKSPACE/config.json"
DOCKER_TAG=$(jq --raw-output ".version" "$ADDON_WORKSPACE/config.json")
# If set custom image in file
DOCKER_IMAGE=$(jq --raw-output ".image // empty" "$ADDON_WORKSPACE/config.json")
# Replace hass.io vars
sed -i "s/%%BASE_IMAGE%%/${BASE_IMAGE}/g" "$ADDON_WORKSPACE/Dockerfile"
sed -i "s/#${ARCH}:FROM/FROM/g" "$ADDON_WORKSPACE/Dockerfile"
sed -i "s/%%ARCH%%/${ARCH}/g" "$ADDON_WORKSPACE/Dockerfile"
echo "LABEL io.hass.version=\"$DOCKER_TAG\" io.hass.arch=\"$ARCH\" io.hass.type=\"addon\"" >> "$ADDON_WORKSPACE/Dockerfile"
# Run build
echo "[INFO] start docker build"
docker stop $BUILD_CONTAINER_NAME 2> /dev/null || true
docker rm --volumes $BUILD_CONTAINER_NAME 2> /dev/null || true
docker run --rm \
-v "$ADDON_WORKSPACE":/docker \
-v ~/.docker:/root/.docker \
-e DOCKER_PUSH=$DOCKER_PUSH \
-e DOCKER_CACHE=$DOCKER_CACHE \
-e DOCKER_WITH_LATEST=$DOCKER_WITH_LATEST \
-e DOCKER_IMAGE="$DOCKER_IMAGE" \
-e DOCKER_TAG="$DOCKER_TAG" \
--name $BUILD_CONTAINER_NAME \
--privileged \
homeassistant/docker-build-env \
/run-docker.sh
echo "[INFO] cleanup WORKSPACE"
cd "$BUILD_DIR"
rm -rf "$WORKSPACE"
cleanup "okay"
exit 0

View file

@ -1,16 +0,0 @@
#!/bin/bash
for addon in "$@";
do
if [ -z $TRAVIS_COMMIT_RANGE ] || \
git diff --name-only $TRAVIS_COMMIT_RANGE | grep -q $addon;
then
archs=$(jq -r '.arch // ["armhf","amd64","aarch64","i386"] | .[]' ${addon}/config.json)
for arch in $archs
do
./bin/create_hassio_addon.sh -a $arch -s $addon -l .
done
else
echo "No change in commit range $TRAVIS_COMMIT_RANGE, skipping build."
fi
done

View file

@ -1,18 +0,0 @@
# Hass.io Add-on Changelog: Homebridge
All notable changes to this add-on will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## Unreleased
-
## 1.0.1 - 2017-08-15
### Fixes
- Homebridge pin generated with additional dash [#3](https://github.com/hassio-addons/repository/issues/3)
## 1.0.0 - 2017-08-14
### Added
- First version of the Homebridge Add-on
- This CHANGELOG file

View file

@ -1,29 +0,0 @@
FROM %%BASE_IMAGE%%
MAINTAINER Franck Nijhof <frenck@geekchimp.com>
# Add env
ENV LANG="C.UTF-8"
# Copy run file
COPY files/run.sh /
# Setup base
RUN apk add --no-cache jq git python make g++ libffi-dev openssl-dev openrc dbus \
avahi-compat-libdns_sd avahi-dev avahi-tools avahi-ui-tools \
nodejs-current nodejs-current-npm yarn && \
mkdir -p /var/run/dbus && \
mkdir -p /var/run/avahi-daemon && \
chown messagebus:messagebus /var/run/dbus && \
chown avahi:avahi /var/run/avahi-daemon && \
yarn global add node-gyp && \
yarn global add homebridge@0.4.22 && \
yarn global add homebridge-homeassistant && \
npm cache clean && \
yarn cache clean && \
chmod a+x /run.sh
# Copy configuration files
COPY files/avahi-daemon.conf /etc/avahi/
COPY files/homebridge-config.json /root/
CMD [ "/run.sh" ]

View file

@ -1,288 +1,7 @@
# Hass.io Add-on: Homebridge
# Community Hass.io Add-on: Homebridge
![Project Stage][project-stage-shield]
![Maintenance][maintenance-shield]
![Awesome][awesome-shield]
[![License][license-shield]](LICENSE.md)
This is just a configuration stub to make the Hass.io repository work.
The add-on itself can be found at the following URL:
This add-on provides the installation, configuration, and integration for
[Homebridge][homebridge].
Homebridge is a server that emulates the iOS HomeKit API, allowing you to
control your Home Assistant through via Apple devices (including Siri).
Since Siri supports devices added through HomeKit, this means that with
Homebridge you can ask Siri to control devices that don't have any support for
HomeKit at all. For instance, using just some of the available plugins,
you can say:
* _Siri, unlock the back door._
* _Siri, open the garage door._
* _Siri, turn on the coffee maker._
* _Siri, turn on the living room lights._
* _Siri, good morning!_
## Docker status
[![Docker Architecture][armhf-arch-shield]][armhf-dockerhub]
[![Docker Version][armhf-version-shield]][armhf-microbadger]
[![Docker Layers][armhf-layers-shield]][armhf-microbadger]
[![Docker Pulls][armhf-pulls-shield]][armhf-dockerhub]
[![Docker Architecture][aarch64-arch-shield]][aarch64-dockerhub]
[![Docker Version][aarch64-version-shield]][aarch64-microbadger]
[![Docker Layers][aarch64-layers-shield]][aarch64-microbadger]
[![Docker Pulls][aarch64-pulls-shield]][aarch64-dockerhub]
[![Docker Architecture][amd64-arch-shield]][amd64-dockerhub]
[![Docker Version][amd64-version-shield]][amd64-microbadger]
[![Docker Layers][amd64-layers-shield]][amd64-microbadger]
[![Docker Pulls][amd64-pulls-shield]][amd64-dockerhub]
[![Docker Architecture][i386-arch-shield]][i386-dockerhub]
[![Docker Version][i386-version-shield]][i386-microbadger]
[![Docker Layers][i386-layers-shield]][i386-microbadger]
[![Docker Pulls][i386-pulls-shield]][i386-dockerhub]
## Installation
The installation of this add-on is pretty straight forward and not different in
comparison to installing any other Hass.io add-on.
1. [Add our Hass.io add-ons repository][repository] to your Hass.io instance
2. Install the "Homebridge" add-on
3. Start the "Homebridge" add-on
4. Check the logs of the "Homebridge" add-on to see if everything went well and
to find the pin code needed to add your Home Assistant instance to
your iOS device
Please read the rest of this document further instructions.
## Configuration
On the first run, this add-on will create the necessary configuration files
for you. Stored in `/config/homebridge/`. You can modify the configuration
to your own liking. For documentation on configuring Homebridge, please refer
to the [Homebridge GitHub][homebridge] repository. For documentation on
configuring the Home Assistant for Homebridge plugin, please refer to the
[Home Assistant for Homebridge GitHub][homebridge-homeassistant] repository.
The add-on has a limited configuration possibility as well.
_Please remember to restart the add-on when the configuration changes._
Example add-on configuration:
```json
{
"debug": false,
"plugins": []
}
```
**Option: `debug`**
When set to `true` the addon will output more information in the logs of the
add-on. The add-on will also start all the services in debug mode, which causes
more output in the log files.
This might be useful when you're dealing with an unknown issue. It is
recommended leaving to option set to `false`, unless you are troubleshooting.
**Option: `plugins`**
This Homebridge add-on has support for installing additional Homebridge plugins.
Plugins are NodeJS modules published through NPM and tagged with the keyword
`homebridge-plugin`. They must have a name with the prefix `homebridge-`,
like `homebridge-mysmartlock`.
The `homebridge-homeassistant` plugin is already installed for you.
You can install a plugin by adding it to the add-on configuration. The add-on
will ensure the plugin is installed on start.
Example add-on configuration:
```json
{
"debug": false,
"plugins": [
"homebridge-dummy",
"homebridge-mysmartlock"
]
}
```
You can explore all available plugins at the NPM website by [searching for the
keyword `homebridge-plugin`][homebridge-plugins].
## Adding Homebridge to iOS
Using the Home app (or most other HomeKit apps), you should be able to add the
single accessory "Home Assistant", assuming that you're still running the
Homebridge add-on and you're on the same (Wifi) network. Adding this accessory
will automatically add all accessories and platforms defined in your
Home Assistant instance.
When you attempt to add the "Home Assistant" accessory, it will ask for a
"PIN code". This pin code is randomly generated when this add-on is run for
the first time. You can find the generated PIN code in the add-on logs and in
your `/config/homebridge/config.json` file (where you, of course,
can change it as well).
## Known issues and limitations
* Once your device has been added to HomeKit, you should be able to tell Siri to
control your devices. However, realize that Siri is a cloud service, and iOS may
need some time to synchronize your device information with iCloud.
* Siri will almost always prefer its default phrase handling over HomeKit
devices. For instance, if you name your Sonos device "Radio" and try saying
"Siri, turn on the Radio" then Siri will probably start playing an iTunes Radio
station on your phone. Even if you name it "Sonos" and say
"Siri, turn on the Sonos", Siri will probably just launch the Sonos app instead.
This is why, for instance, the suggested `name` for the Sonos accessory
is "Speakers".
* One installation of Homebridge can only expose 100 accessories due to a
HomeKit limit.
* Once an accessory has been added to the Home app, changing its name via
Homebridge won't be automatically reflected in iOS. You must change it via
the Home app as well.
* IPv6 support has been removed from this addon, because of known issues with
libraries used by Homebridge. If you rely solely on IPv6 in your network,
this add-on would not work.
* If you have set up SSL using a self-signed certificate, you will need to
set verify_ssl to false in your `/config/homebridge/config.json` file to allow
bypassing the Node.js certificate checks.
* Errors on startup. The following errors are experienced when starting
Homebridge and can be safely ignored.
```
*** WARNING *** The program 'nodejs' uses the Apple Bonjour compatibility layer of Avahi
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointerde/avahi-compat?s=libdns_sd&e=nodejs
*** WARNING *** The program 'nodejs' called 'DNSServiceRegister()' which is not supported (or only supported partially) in the Apple Bonjour compatibility layer of Avahi
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointerde/avahi-compat?s=libdns_sd&e=nodejs&f=DNSServiceRegister
```
## FAQ
**Homebridge cannot connect or login to Home Assistant**
Please be sure to set the `host` and `password` parameters in the
`/config/homebridge/config.json` file.
Normally `http://172.17.0.1:8123` should be a sufficient `host` to use when
running hass.io.
If a password protects your Home Assistant instance, you'll also need to
set the `password`, which is empty by default.
**My iOS App Can't Find Homebridge/Home Assistant**
Two reasons why Homebridge may not be discoverable:
1. Homebridge server thinks it's been paired with, but iOS thinks otherwise.
Fix: deleted `persist/` directory which is in your `config/homebridge` directory
and restart the add-on.
2. iOS device has gotten your Homebridge `username` (looks like a MAC address)
"stuck" somehow, where it's in the database but inactive. Fix: change your
`username` in the "bridge" section of `/config/homebridge/config.json` to be
some new value and restart the add-on.
## Support
Got questions? Got some unexpected behavior caused by this plugin?
Please [open an issue on our GitHub repository][issues] and we'll do our best
to help you out.
## Credits
A big shout out to the following people, without them this add-on wasn't possible:
- The team & community of [Home Assistant][home-assistant] for developing such an
excellent home automation toolkit
- [Nick Farina][nfarina] for developing [Homebrige][homebridge]
This add-on has been inspired by the following repositories:
- [docker-homebridge][oznu-docker-homebridge] by [Oznu][oznu]
- [homebridge-docker][ckuburlis-homebridge-docker]by [ckuburlis]
- [hassio-addons][olivierguerriat-hassio-addons] by [Olivier Guerriat][olivierguerriat]
Thank you all!
## More Hass.io add-ons
Do you like this add-on? Want some more functionality to your Hass.io Home
Assistant instance?
We've created multiple add-ons for Hass.io. For a full list, check out
our [GitHub Repository][repository].
## License
MIT License
Copyright (c) 2017 Franck Nijhof
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
[aarch64-arch-shield]: https://img.shields.io/badge/architecture-aarch64-blue.svg
[aarch64-dockerhub]: https://hub.docker.com/r/hassioaddons/homebridge-aarch64
[aarch64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/homebridge-aarch64.svg
[aarch64-microbadger]: https://microbadger.com/images/hassioaddons/homebridge-aarch64
[aarch64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/homebridge-aarch64.svg
[aarch64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/homebridge-aarch64.svg
[amd64-arch-shield]: https://img.shields.io/badge/architecture-amd64-blue.svg
[amd64-dockerhub]: https://hub.docker.com/r/hassioaddons/homebridge-amd64
[amd64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/homebridge-amd64.svg
[amd64-microbadger]: https://microbadger.com/images/hassioaddons/homebridge-amd64
[amd64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/homebridge-amd64.svg
[amd64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/homebridge-amd64.svg
[armhf-arch-shield]: https://img.shields.io/badge/architecture-armhf-blue.svg
[armhf-dockerhub]: https://hub.docker.com/r/hassioaddons/homebridge-armhf
[armhf-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/homebridge-armhf.svg
[armhf-microbadger]: https://microbadger.com/images/hassioaddons/homebridge-armhf
[armhf-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/homebridge-armhf.svg
[armhf-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/homebridge-armhf.svg
[awesome-shield]: https://img.shields.io/badge/awesome%3F-yes-brightgreen.svg
[ckuburlis-homebridge-docker]: https://github.com/ckuburlis/homebridge-docker
[ckuburlis]: https://github.com/ckuburlis
[home-assistant]: https://home-assistant.io
[homebridge-homeassistant]: https://github.com/home-assistant/homebridge-homeassistant
[homebridge-plugins]: https://www.npmjs.com/search?q=homebridge-plugin
[homebridge]: https://github.com/nfarina/homebridge
[i386-arch-shield]: https://img.shields.io/badge/architecture-i386-blue.svg
[i386-dockerhub]: https://hub.docker.com/r/hassioaddons/homebridge-i386
[i386-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/homebridge-i386.svg
[i386-microbadger]: https://microbadger.com/images/hassioaddons/homebridge-i386
[i386-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/homebridge-i386.svg
[i386-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/homebridge-i386.svg
[issues]: https://github.com/hassio-addons/repository/issues
[license-shield]: https://img.shields.io/github/license/hassio-addons/repository.svg
[maintenance-shield]: https://img.shields.io/maintenance/yes/2017.svg
[nfarina]: https://github.com/nfarina
[olivierguerriat-hassio-addons]: https://github.com/olivierguerriat/hassio-addons
[olivierguerriat]: https://github.com/olivierguerriat
[oznu-docker-homebridge]: https://github.com/oznu/docker-homebridge
[oznu]: https://github.com/oznu
[project-stage-shield]: https://img.shields.io/badge/Project%20Stage-Development-yellowgreen.svg
[repository]: https://github.com/hassio-addons/repository
https://github.com/hassio-addons/addon-homebridge

View file

@ -3,7 +3,7 @@
"version": "1.0.1",
"slug": "homebridge",
"description": "HomeKit support for your Home Assistant instance using Homebridge",
"url": "https://github.com/hassio-addons/repository/tree/master/homebridge",
"url": "https://github.com/hassio-addons/addon-homebridge",
"startup": "application",
"boot": "auto",
"host_network": true,

View file

@ -1,48 +0,0 @@
[server]
host-name=hassio
domain-name=local
#browse-domains=0pointer.de, zeroconf.org
use-ipv4=yes
use-ipv6=no
#allow-interfaces=eth0
#deny-interfaces=eth1
#check-response-ttl=no
#use-iff-running=no
enable-dbus=yes
#disallow-other-stacks=no
#allow-point-to-point=no
#cache-entries-max=4096
#clients-max=4096
#objects-per-client-max=1024
#entries-per-entry-group-max=32
ratelimit-interval-usec=1000000
ratelimit-burst=1000
[wide-area]
enable-wide-area=yes
[publish]
#disable-publishing=no
#disable-user-service-publishing=no
#add-service-cookie=no
#publish-addresses=yes
publish-hinfo=no
publish-workstation=no
#publish-domain=yes
#publish-dns-servers=192.168.50.1, 192.168.50.2
#publish-resolv-conf-dns-servers=yes
#publish-aaaa-on-ipv4=yes
#publish-a-on-ipv6=no
[reflector]
#enable-reflector=no
#reflect-ipv=no
[rlimits]
#rlimit-as=
rlimit-core=0
rlimit-data=4194304
rlimit-fsize=0
rlimit-nofile=768
rlimit-stack=4194304
#rlimit-nproc=3

View file

@ -1,34 +0,0 @@
{
"bridge": {
"name": "Home Assistant",
"username": "%%USERNAME%%",
"port": 51826,
"pin": "%%PIN%%"
},
"description": "Homebridge for Home Assistant",
"accessories": [],
"platforms": [
{
"platform": "HomeAssistant",
"name": "HomeAssistant",
"host": "http://172.17.0.1:8123",
"password": "",
"supported_types": [
"binary_sensor",
"climate",
"cover",
"device_tracker",
"fan",
"group",
"input_boolean",
"light",
"lock",
"media_player",
"scene",
"sensor",
"switch"
],
"logging": true
}
]
}

View file

@ -1,434 +0,0 @@
#!/usr/bin/env bash
# ==============================================================================
# Hass.io Add-on for Home Assistant: Homebridge
# ==============================================================================
set -o errexit # Exit script when a command exits with non-zero status
set -o nounset # Exit script on use of an undefined variable
set -o pipefail # Return exit status of the last command in the pipe that failed
# ==============================================================================
# GLOBALS
# ==============================================================================
# Exit codes
readonly EX_OK=0 # Successful termination
readonly EX_DBUS_ID_FAILED=3 # Failed to generated a unique D-Bus ID
readonly EX_PLUGIN_FAILED=4 # Homebridge plugin installation failed
readonly EX_DBUS_DAEMON=5 # Failed to start D-Bus daemon
readonly EX_PID_AVAHI=6 # Failed to remove Avahi daemon PID file
readonly EX_PID_DBUS=7 # Failed to remove D-Bus daemon PID file
readonly EX_PATCH_ERROR=8 # Failed to apply patch
readonly EX_HOMEBRIDGE_DIR=9 # Failed to create Homebridge config directory
readonly EX_HOMEBRIDGE_FILE=10 # Failed to create Homebridge config file
readonly EX_HOMEBRIDGE_USER=11 # Failed to set Homebridge user config
readonly EX_HOMEBRIDGE_PIN=12 # Failed to set Homebridge user pin
# Configuration paths
readonly CONFIG_PATH=/data/options.json
readonly HOMEBRIDGE_CONFIG_FILE=/config/homebridge/config.json
readonly HOMEBRIDGE_TEMPLATE_CONFIG_FILE=/root/homebridge-config.json
# PID Files
readonly PID_FILE_DBUS=/var/run/dbus.pid
readonly PID_FILE_AVAHI=/var/run/avahi-daemon/pid
# D-Bus System bus socket file location
readonly DBUS_SYSTEM_SOCKET=/var/run/dbus/system_bus_socket
# Debug mode?
readonly DEBUG=$(jq --raw-output ".debug" $CONFIG_PATH)
# ==============================================================================
# UTILITY
# ==============================================================================
# ------------------------------------------------------------------------------
# Displays a status message
# Globals:
# None
# Arguments:
# $* Status message to display
# Returns:
# None
# ------------------------------------------------------------------------------
display_status_message() {
local status=$*
echo "[ADD-ON] $status"
}
# ------------------------------------------------------------------------------
# Displays a debug message
# Globals:
# None
# Arguments:
# $* Status message to display
# Returns:
# None
# ------------------------------------------------------------------------------
display_debug_message() {
local status=$*
if [[ "$DEBUG" == "true" ]];
then
display_status_message "[DEBUG] $status"
fi
}
# ------------------------------------------------------------------------------
# Displays a error message and is able to terminate te script execution
# Globals:
# None
# Arguments:
# $1 Error message
# $2 Exitcode, script will continue execution when omitted
# Returns:
# None
# ------------------------------------------------------------------------------
display_error_message() {
local status=$1
local exitcode=${2:-0}
echo "[ADD-ON][ERROR] An error occured!" >&2
echo >&2
echo "!!! ERROR: $status" >&2
echo >&2
if [[ $exitcode -ne 0 ]];
then
exit "$exitcode"
fi
}
# ------------------------------------------------------------------------------
# Gets a configuration parameter form the configuration file
# Globals:
# CONFIG_PATH
# Arguments:
# $1 Key of the configuration parameter to get
# $2 'true' If the configuration value is an array, false otherwise
# Returns:
# The configuration value
# ------------------------------------------------------------------------------
get_config() {
local key=$1
local is_array=$2
if $is_array;
then
command jq --raw-output ".$key[]" $CONFIG_PATH
else
command jq --raw-output ".$key" $CONFIG_PATH
fi
}
# ------------------------------------------------------------------------------
# Finds the MAC address of the main interface
# Globals:
# None
# Arguments:
# None
# Returns:
# MAC address of the main interface (upper-cased)
# ------------------------------------------------------------------------------
get_mac_addr() {
local interface
local mac
interface=$(ip route show default | awk '/default/ {print $5}')
mac=$(cat "/sys/class/net/$interface/address")
echo "${mac^^}"
}
# ------------------------------------------------------------------------------
# Generates a random pin number for HomeKit (###-##-### format)
# Globals:
# None
# Arguments:
# None
# Returns:
# The generated random pin number
# ------------------------------------------------------------------------------
generate_homekit_pin() {
local pin
pin=$(< /dev/urandom tr -dc 0-9 | head -c3)
pin+="-"
pin+=$(< /dev/urandom tr -dc 0-9 | head -c2)
pin+="-"
pin+=$(< /dev/urandom tr -dc 0-9 | head -c3)
echo "$pin"
}
# ==============================================================================
# SCRIPT LOGIC
# ==============================================================================
# ------------------------------------------------------------------------------
# Applies temporary but necessary patch to HAP NodeJS
# Globals:
# EX_PATCH_ERROR
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
apply_hap_nodejs_ipv6_hotfix() {
local eventedhttp_file='/usr/local/share/.config/yarn/global/node_modules/hap-nodejs/lib/util/eventedhttp.js'
display_status_message 'Applying HAP NodeJS IPV6 HOTFIX'
command patch $eventedhttp_file <<PATCH
--- eventedhttp.js
+++ eventedhttp.js
@@ -57,7 +57,7 @@
inherits(EventedHTTPServer, EventEmitter);
EventedHTTPServer.prototype.listen = function(targetPort) {
- this._tcpServer.listen(targetPort);
+ this._tcpServer.listen(targetPort, '0.0.0.0');
this._tcpServer.on('listening', function() {
var port = this._tcpServer.address().port;
PATCH
# shellcheck disable=SC2181
if [[ "$?" -ne 0 ]];
then
display_error_message 'Patching HAP NodeJS failed' "$EX_PATCH_ERROR"
fi
}
# ------------------------------------------------------------------------------
# Ensures D-Bus UUID exists and has the uuid in it
# Globals:
# EX_DBUS_ID_FAILED
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
ensure_dbus_id() {
display_status_message 'Ensuring D-Bus unique ID exists'
command dbus-uuidgen --ensure || display_error_message \
'Failed to generated unique D-Bus ID' "$EX_DBUS_ID_FAILED"
# Somehow we need this sleep. Atm it is unclear why...
sleep 2
}
# ------------------------------------------------------------------------------
# Install list of user requested Homebridge Plugins
# Globals:
# EX_PLUGIN_FAILED
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
install_plugins() {
local plugins
plugins=$(get_config "plugins" true)
for plugin in $plugins;
do
display_status_message "Installing Homebridge plugin $plugin"
command yarn global add "$plugin" || display_error_message \
"Failed installing Homebridge plugin $plugin" $EX_PLUGIN_FAILED
done
}
# ------------------------------------------------------------------------------
# Removes old PID files that may be left behind from last run
# Globals:
# EX_PID_AVAHI
# EX_PID_DBUS
# PID_FILE_AVAHI
# PID_FILE_DBUS
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
remove_old_pid_files() {
display_status_message 'Ensuring old PID files are absent'
if [[ -e "$PID_FILE_AVAHI" ]];
then
display_status_message 'Removing old Avahi daemon PID file'
command rm -f "$PID_FILE_AVAHI" || display_error_message \
'Failed to removed Avahi daemon PID file' "$EX_PID_AVAHI"
fi
if [[ -e "$PID_FILE_DBUS" ]];
then
display_status_message 'Removing old D-Bus daemon PID file'
command rm -f "$PID_FILE_DBUS" || display_error_message \
'Failed to remove D-Bus daemon PID file' "$EX_PID_DBUS"
fi
}
# ------------------------------------------------------------------------------
# Start the Avahi daemon in the background
# Globals:
# DEBUG
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
start_avahi_daemon() {
display_status_message 'Starting Avahi daemon'
if [[ "$DEBUG" == "true" ]];
then
command avahi-daemon --debug &
else
command avahi-daemon &
fi
# Waiting 5 seconds to allow Avahi to register itself
sleep 5
}
# ------------------------------------------------------------------------------
# Applies temporary but necessary patch to HAP NodeJS
# Globals:
# EX_DBUS_DAEMON
# DBUS_SYSTEM_SOCKET
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
start_dbus_daemon() {
display_status_message 'Starting D-Bus daemon'
command dbus-daemon --system || display_error_message \
'Failed to start D-Bus daemon' $EX_DBUS_DAEMON
display_debug_message 'Waiting until system bus socket is ready'
until [[ -e "$DBUS_SYSTEM_SOCKET" ]];
do
display_debug_message 'Still waiting...'
sleep 1
done
}
# ------------------------------------------------------------------------------
# Starts Homebridge
# Globals:
# HOMEBRIDGE_CONFIG_FILE
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
start_homebridge() {
display_status_message 'Starting Homebridge'
if [[ "$DEBUG" == "true" ]];
then
command homebridge -D -U "$(dirname "$HOMEBRIDGE_CONFIG_FILE")"
else
command homebridge -U "$(dirname "$HOMEBRIDGE_CONFIG_FILE")"
fi
}
# ------------------------------------------------------------------------------
# Generates an initial Homebridge configuration file
# Globals:
# HOMEBRIDGE_CONFIG_FILE
# EX_HOMEBRIDGE_DIR
# EX_HOMEBRIDGE_FILE
# EX_HOMEBRIDGE_USER
# EX_HOMEBRIDGE_PIN
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
generate_homebridge_config() {
local homebridge_config_dir
display_status_message 'Generating Homebridge configuration files'
homebridge_config_dir=$(dirname "$HOMEBRIDGE_CONFIG_FILE")
if [[ ! -d "$homebridge_config_dir" ]];
then
display_debug_message 'Creating Homebridge configuration directory'
command mkdir -p "$homebridge_config_dir" || display_error_message \
'Failed to create Homebrige configuration directory' \
"$EX_HOMEBRIDGE_DIR"
fi
display_debug_message 'Copying Homebrige configuration template'
command cp "$HOMEBRIDGE_TEMPLATE_CONFIG_FILE" "$HOMEBRIDGE_CONFIG_FILE" ||
display_error_message 'Failed creating Homebridge configuration file' \
"$EX_HOMEBRIDGE_FILE"
display_debug_message 'Setting Homebridge username based on MAC address'
command sed -i "s/%%USERNAME%%/$(get_mac_addr)/g" \
"$HOMEBRIDGE_CONFIG_FILE" || display_error_message \
'Failed setting Homebridge username' "$EX_HOMEBRIDGE_USER"
display_debug_message 'Setting Homebridge HomeKit pin'
command sed -i "s/%%PIN%%/$(generate_homekit_pin)/g" \
"$HOMEBRIDGE_CONFIG_FILE" || display_error_message \
'Failed setting Homebridge pin' "$EX_HOMEBRIDGE_PIN"
}
# ------------------------------------------------------------------------------
# Cleanup function after execution is of the script is stopped. (trap)
# Globals:
# PID_FILE_AVAHI
# PID_FILE_DBUS
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
cleanup() {
command rm -f "$PID_FILE_AVAHI"
command rm -f "$PID_FILE_DBUS"
}
# ==============================================================================
# RUN LOGIC
# ------------------------------------------------------------------------------
# Globals:
# EX_OK
# HOMEBRIDGE_CONFIG_FILE
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
main() {
trap cleanup ERR
trap cleanup EXIT
install_plugins
remove_old_pid_files
ensure_dbus_id
start_dbus_daemon
start_avahi_daemon
if [[ ! -f "$HOMEBRIDGE_CONFIG_FILE" ]]; then
generate_homebridge_config
fi
apply_hap_nodejs_ipv6_hotfix
start_homebridge
exit "$EX_OK"
}
main

View file

@ -1,5 +1,5 @@
{
"name": "Third party Hass.io add-ons for Home Assistant",
"name": "Community Hass.io add-ons for Home Assistant",
"url": "https://github.com/hassio-addons/repository",
"maintainer": "Franck Nijhof <frenck@geekchimp.com>"
}

View file

@ -1,26 +0,0 @@
# Hass.io Add-on Changelog: SSH - Secure Shell
All notable changes to this add-on will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## Unreleased
-
## 1.0.3 - 2017-08-16
### Changed
- Fix issue: User with key and without password was unable to log in
This time for real ;)
## 1.0.2 - 2017-08-16
### Changed
- Fix issue: User with key and without password was unable to log in
## 1.0.1 - 2017-08-16
### Changed
- Fix issue: User with key and without password was unable to log in
## 1.0.0 - 2017-08-16
### Added
- First version of the SSH Add-on
- This CHANGELOG file

View file

@ -1,29 +0,0 @@
FROM %%BASE_IMAGE%%
MAINTAINER Franck Nijhof <frenck@geekchimp.com>
# Add env
ENV LANG="C.UTF-8" \
TERM="xterm-256color"
# Copy data
COPY files/run.sh /
COPY files/hassio /usr/bin/
COPY files/sshd_config /etc/ssh/
COPY files/motd /etc/
COPY files/.zshrc /root/
COPY files/.tmux.conf /root/
COPY files/wheel /etc/sudoers.d/
# Setup base
RUN apk add --no-cache jq openssh sudo zsh openssl libxml2-utils ncurses \
curl wget net-tools bind-tools rsync git nmap wget awake \
nano vim mosquitto-clients mariadb-client tmux && \
git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh && \
chmod a+x /run.sh /usr/bin/hassio && \
sed -i -e "s/bin\/ash/bin\/zsh/" /etc/passwd && \
touch /etc/ssh/authorized_keys && \
chmod 0644 /etc/ssh/authorized_keys && \
touch /var/log/btmp && \
chmod 0600 /var/log/btmp
CMD [ "/run.sh" ]

View file

@ -1,261 +1,7 @@
# Hass.io Add-on: SSH - Secure Shell
# Community Hass.io Add-on: SSH - Secure Shell
![Project Stage][project-stage-shield]
![Maintenance][maintenance-shield]
![Awesome][awesome-shield]
[![License][license-shield]](LICENSE.md)
This is just a configuration stub to make the Hass.io repository work.
This add-on allows you to log in to your Hass.io Home Assistant instance using
SSH. Giving you to access your Hass.io folders and also includes a
command-line tool to do things like restart, update, and check your instance.
The add-on itself can be found at the following URL:
This is an enhanced version of the provided
[SSH add-on by Home Assistant][hass-ssh] and focusses on security,
usability and flexibility.
## Docker status
[![Docker Architecture][armhf-arch-shield]][armhf-dockerhub]
[![Docker Version][armhf-version-shield]][armhf-microbadger]
[![Docker Layers][armhf-layers-shield]][armhf-microbadger]
[![Docker Pulls][armhf-pulls-shield]][armhf-dockerhub]
[![Docker Architecture][aarch64-arch-shield]][aarch64-dockerhub]
[![Docker Version][aarch64-version-shield]][aarch64-microbadger]
[![Docker Layers][aarch64-layers-shield]][aarch64-microbadger]
[![Docker Pulls][aarch64-pulls-shield]][aarch64-dockerhub]
[![Docker Architecture][amd64-arch-shield]][amd64-dockerhub]
[![Docker Version][amd64-version-shield]][amd64-microbadger]
[![Docker Layers][amd64-layers-shield]][amd64-microbadger]
[![Docker Pulls][amd64-pulls-shield]][amd64-dockerhub]
[![Docker Architecture][i386-arch-shield]][i386-dockerhub]
[![Docker Version][i386-version-shield]][i386-microbadger]
[![Docker Layers][i386-layers-shield]][i386-microbadger]
[![Docker Pulls][i386-pulls-shield]][i386-dockerhub]
## Features
This add-on, of course, provides an SSH server, based on [OpenSSH][openssh].
Additionally, it comes out of the box with the following:
- A secure default configuration of SSH:
- Only allows login by the configured user, even if more users are created.
- Only uses known secure ciphers and algorithms.
- Limits login attempts to hold of brute-force attacks better.
- Many more security tweaks, *this addon passes all [ssh-audit] checks
without warnings!*
![Result of SSH-Audit](images/ssh-audit.png)
- Port number is configurable (You could use `1982` instead of port `22`).
- SFTP support is disabled by default but is user configurable.
- Username is configurable, so `root` is no longer mandatory.
- Debug mode for allowing you to triage issues easier.
- Compatible if Hass.io was installed via the generic Linux installer.
- Have Alpine packages installed on start. This will allow you to install your
favorite tools, which will be available every single time you log in.
- Execute custom commands on start automatically, so you can customize the shell
to your likings.
- [ZSH][zsh] as its default shell. Easier to use for the beginner, more advanced
for the more experienced user. It even comes preloaded with
["Oh My ZSH"][ohmyzsh], with some plugins enabled as well.
- Contains a sensible set of tools right out of the box: curl, Wget, RSync, GIT,
Nmap, Mosquitto client, MariaDB/MySQL client, Awake (“wake on lan”), Nano, Vim,
tmux, and a bunch commonly used networking tools.
## Installation
The installation of this add-on is pretty straight forward and not different in
comparison to installing any other Hass.io add-on.
1. If you installed the "SSH server" add-on from the built-in add-on, then
that one first.
2. [Add our Hass.io add-ons repository][repository] to your Hass.io instance
3. Install the "SSH - Secure Shell" add-on from our repository
3. Start the "SSH - Secure Shell" add-on
4. Check the logs of the "SSH - Secure Shell" add-on to see if everything
went well.
Please read the rest of this document further instructions.
## Configuration
_Please remember to restart the add-on when the configuration changes._
Example add-on configuration:
```json
{
"debug": true,
"port": 22,
"username": "hass",
"password": "",
"authorized_keys": [
"ssh-rsa AASDJKJKJFWJFAFLCNALCMLAK234234....."
],
"sftp": false,
"packages": [
"python",
"python-dev",
"py-pip",
"build-base"
],
"init_commands": [
"pip install virtualenv",
"pip install yamllint"
]
}
```
_*Note*: This is just an example, don't copy and past it! Create your own!_
**Option: `debug`**
When set to `true` the addon will output more information in the logs of the
add-on. The add-on will also start the SSH daemon in debug mode. While SSH is
running in daemon mode, it will be only able to accept one single connection. As
soon as this session is ended, the addon will stop running.
This might be useful when you're dealing with an unknown issue. It is
recommended leaving to option set to `false`, unless you are troubleshooting.
**Option: `port`**
The default port for SSH is `22`, some security guides actually recommend to
change the port to something else. Sometimes you'd just like to have it on
another port. Remember, if you change to port, be sure it is not in use
already!
**Option: `username`**
This option allows you to change to username the use when you log in via SSH.
It is only used for the authentication, you will be the `root` user after
you have authenticated. Using `root` as the username is possible, but not
recommended.
_*Note*: Due to limitations, you will need to set this option to `root` in
order to be able to enable the SFTP capabilities._
**Option: `password`**
Sets the password to log in with. Leaving it empty would disable the posibility
to authenticate with a password. We would highly recommend not to use this
option from a security point of view.
**Option: `authorized_keys`**
Add one or more public keys to your SSH server to use with authentication.
This is the recommended over setting a password.
Please take a look at the awesome [documentation created by GitHub][github-ssh]
about using public/private keypairs and how to create them.
**Option: `sftp`**
When set to `true` the addon will enable SFTP support on the SSH daemon.
Please only enable it when you plan to use it.
_*Note*: Due to limitations, you will need to set the username to `root` in
order to be able to enable the SFTP capabilities._
**Option: `packages`**
Allows you to specify additional [Alpine packages][alpine-packages] to be
installed in your shell environment (e.g. Python, Joe, Irssi).
_*Note*: Adding many packages will result in a longer start-up
time for the add-on._
**Option: `init_commands`**
Customize your shell environment even more with the `init_commands` option.
Add one or more shell commands to the list, and they will be executed every
single time this add-on starts.
## Known issues and limitations
- When SFTP is enabled, the username MUST be set to `root`.
## Support
Got questions? Got some unexpected behavior caused by this plugin?
Please [open an issue on our GitHub repository][issues] and we'll do our best
to help you out.
## Credits
A big shout out to the following people, without them this add-on wasn't possible:
- The team & community of [Home Assistant][home-assistant] for developing such an
excellent home automation toolkit
Thank you all!
## More Hass.io add-ons
Do you like this add-on? Want some more functionality to your Hass.io Home
Assistant instance?
We've created multiple add-ons for Hass.io. For a full list, check out
our [GitHub Repository][repository].
## License
MIT License
Copyright (c) 2017 Franck Nijhof
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
[aarch64-arch-shield]: https://img.shields.io/badge/architecture-aarch64-blue.svg
[aarch64-dockerhub]: https://hub.docker.com/r/hassioaddons/ssh-aarch64
[aarch64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/ssh-aarch64.svg
[aarch64-microbadger]: https://microbadger.com/images/hassioaddons/ssh-aarch64
[aarch64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/ssh-aarch64.svg
[aarch64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/ssh-aarch64.svg
[alpine-packages]: https://pkgs.alpinelinux.org/packages
[amd64-arch-shield]: https://img.shields.io/badge/architecture-amd64-blue.svg
[amd64-dockerhub]: https://hub.docker.com/r/hassioaddons/ssh-amd64
[amd64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/ssh-amd64.svg
[amd64-microbadger]: https://microbadger.com/images/hassioaddons/ssh-amd64
[amd64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/ssh-amd64.svg
[amd64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/ssh-amd64.svg
[armhf-arch-shield]: https://img.shields.io/badge/architecture-armhf-blue.svg
[armhf-dockerhub]: https://hub.docker.com/r/hassioaddons/ssh-armhf
[armhf-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/ssh-armhf.svg
[armhf-microbadger]: https://microbadger.com/images/hassioaddons/ssh-armhf
[armhf-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/ssh-armhf.svg
[armhf-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/ssh-armhf.svg
[awesome-shield]: https://img.shields.io/badge/awesome%3F-yes-brightgreen.svg
[github-ssh]: https://help.github.com/articles/connecting-to-github-with-ssh/
[hass-ssh]: https://home-assistant.io/addons/ssh/
[home-assistant]: https://home-assistant.io
[i386-arch-shield]: https://img.shields.io/badge/architecture-i386-blue.svg
[i386-dockerhub]: https://hub.docker.com/r/hassioaddons/ssh-i386
[i386-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/ssh-i386.svg
[i386-microbadger]: https://microbadger.com/images/hassioaddons/ssh-i386
[i386-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/ssh-i386.svg
[i386-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/ssh-i386.svg
[issues]: https://github.com/hassio-addons/repository/issues
[license-shield]: https://img.shields.io/github/license/hassio-addons/repository.svg
[maintenance-shield]: https://img.shields.io/maintenance/yes/2017.svg
[ohmyzsh]: http://ohmyz.sh/
[openssh]: https://www.openssh.com/
[project-stage-shield]: https://img.shields.io/badge/Project%20Stage-Development-yellowgreen.svg
[repository]: https://github.com/hassio-addons/repository
[ssh-audit]: https://github.com/arthepsy/ssh-audit
[zsh]: https://en.wikipedia.org/wiki/Z_shell
https://github.com/hassio-addons/addon-ssh

View file

@ -3,7 +3,7 @@
"version": "1.0.3",
"slug": "ssh",
"description": "Allows SSH connections to your Home Assistant instance",
"url": "https://github.com/hassio-addons/repository/tree/master/ssh",
"url": "https://github.com/hassio-addons/addon-ssh",
"startup": "services",
"boot": "auto",
"host_network": true,

View file

@ -1,23 +0,0 @@
set-option -g default-shell /bin/zsh
set-option -g default-terminal $TERM
set-option -g base-index 1
setw -g pane-base-index 1
setw -g window-status-format "#[fg=white]#[bg=blue] #I #[bg=blue]#[fg=white] #W "
setw -g window-status-current-format "#[bg=brightmagenta]#[fg=white] *#I #[fg=white,bold]#[bg=cyan] [#W] "
set -g pane-border-fg black
set -g pane-active-border-fg blue
set -g status-fg white
set -g status-bg blue
set -g status-left ''
set -g status-right '%a %m-%d %H:%M'
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

View file

@ -1,85 +0,0 @@
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
# Path to your oh-my-zsh installation.
export ZSH=$HOME/.oh-my-zsh
# Set name of the theme to load. Optionally, if you set this to "random"
# it'll load a random theme each time that oh-my-zsh is loaded.
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
ZSH_THEME="robbyrussell"
# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"
# Uncomment the following line to use hyphen-insensitive completion. Case
# sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"
# Uncomment the following line to disable bi-weekly auto-update checks.
DISABLE_AUTO_UPDATE="true"
# Uncomment the following line to change how often to auto-update (in days).
# export UPDATE_ZSH_DAYS=13
# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"
# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"
# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"
# Uncomment the following line to display red dots whilst waiting for completion.
COMPLETION_WAITING_DOTS="true"
# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"
# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# HIST_STAMPS="mm/dd/yyyy"
# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder
# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(extract git tmux nmap rsync)
source $ZSH/oh-my-zsh.sh
# User configuration
# export MANPATH="/usr/local/man:$MANPATH"
# You may need to manually set your language environment
# export LANG=en_US.UTF-8
# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
# export EDITOR='vim'
# else
# export EDITOR='mvim'
# fi
# Compilation flags
# export ARCHFLAGS="-arch x86_64"
# ssh
# export SSH_KEY_PATH="~/.ssh/rsa_id"
# Set personal aliases, overriding those provided by oh-my-zsh libs,
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"

View file

@ -1,101 +0,0 @@
#!/bin/bash
set -e
# helppage
if [ "$1" == "help" ] || [ "$#" -lt 2 ]; then
cat << EOF
---- Hass.IO Cli ----
HomeAssistant:
$ hassio homeassistant logs
$ hassio homeassistant restart
$ hassio homeassistant update
$ hassio homeassistant check
Host:
$ hassio host hardware
$ hassio host reboot
$ hassio host shutdown
$ hassio host update
Supervisor
$ hassio supervisor logs
$ hassio supervisor info
$ hassio supervisor reload
$ hassio supervisor update
EOF
fi
function call_api() {
get_cmd=('info' 'logs' 'hardware')
command='POST'
if [[ ${get_cmd[*]} =~ $2 ]]; then
command='GET'
fi
if ! api_ret="$(curl -s -X $command "http://hassio/$1/$2")"; then
echo "API error: $api_ret"
return 1
fi
if [ "$2" == "logs" ]; then
echo "$api_ret"
return 0
fi
result="$(echo "$api_ret" | jq --raw-output ".result")"
# On error
if [ "$result" == "error" ]; then
message="$(echo "$api_ret" | jq --raw-output ".message // empty")"
echo "Error on $1/$2:" "$message"
return 0
fi
# On success
data="$(echo "$api_ret" | jq 'if .data == {} then empty else .data end')"
if [ ! -z "$data" ]; then
echo "$data" | jq .
else
echo "Success $1/$2"
fi
return 0
}
######
# homeassistant functions
if [ "$1" == "homeassistant" ]; then
hass_cmd=('logs' 'restart' 'update' 'check')
if [[ ! ${hass_cmd[*]} =~ $2 ]]; then
echo "No homeassistant command '$2' found!"
exit 1
fi
call_api "$1" "$2"
fi
######
# host functions
if [ "$1" == "host" ]; then
hass_cmd=('reboot' 'shutdown' 'update' 'hardware')
if [[ ! ${hass_cmd[*]} =~ $2 ]]; then
echo "No host command '$2' found!"
exit 1
fi
call_api "$1" "$2"
fi
######
# supervisor functions
if [ "$1" == "supervisor" ]; then
hass_cmd=('logs' 'reload' 'update' 'info')
if [[ ! ${hass_cmd[*]} =~ $2 ]]; then
echo "No supervisor command '$2' found!"
exit 1
fi
call_api "$1" "$2"
fi

View file

@ -1,12 +0,0 @@
_ _ _____ ____
| | | | |_ _/ __ \
| |__| | __ _ ___ ___ | || | | |
| __ |/ _` / __/ __| | || | | |
| | | | (_| \__ \__ \_ _| || |__| |
|_| |_|\__,_|___/___(_)_____\____/
Our Cli:
$ hassio help

View file

@ -1,513 +0,0 @@
#!/usr/bin/env bash
# ==============================================================================
# Hass.io Add-on for Home Assistant: SSH
# ==============================================================================
set -o errexit # Exit script when a command exits with non-zero status
set -o nounset # Exit script on use of an undefined variable
set -o pipefail # Return exit status of the last command in the pipe that failed
# ==============================================================================
# GLOBALS
# ==============================================================================
# Exit codes
readonly EX_OK=0 # Successful termination
readonly EX_NO_USERNAME=3 # No username specified in configuration
readonly EX_NO_LOGIN=4 # No login data in user configuration
readonly EX_SFTP_USERNAME=5 # SFTP is only possible when username is root
readonly EX_RSA_HOST_KEY=6 # Failed to generate SSH RSA host key
readonly EX_ED25519_HOST_KEY=7 # Failed to generate SSH ED25519 host key
readonly EX_USER_ADD=8 # Failed to create user account
readonly EX_USER_PROFILE=9 # Failed to create user profile
readonly EX_COMMON_LINK=10 # Failed to link common directory
readonly EX_APK_UPDATE=11 # Alpine update failed
readonly EX_PACKAGE_FAILED=12 # Alpine package installation failed
readonly EX_INIT_COMMAND=13 # Failed executing custom init command
# Configuration paths
readonly CONFIG_PATH=/data/options.json
readonly SSH_CONFIG_PATH=/etc/ssh/sshd_config
# SSH authorized_keys files
readonly SSH_AUTHORIZED_KEYS_PATH=/etc/ssh/authorized_keys
# SSH host keys
readonly SSH_HOST_RSA_KEY=/data/ssh_host_rsa_key
readonly SSH_HOST_ED25519_KEY=/data/ssh_host_ed25519_key
# Shell history files
readonly ZSH_HISTORY_FILE=/root/.zsh_history
readonly ZSH_HISTORY_PERSISTANT_FILE=/data/.zsh_history
# Debug mode?
readonly DEBUG=$(jq --raw-output ".debug" $CONFIG_PATH)
# ==============================================================================
# UTILITY
# ==============================================================================
# ------------------------------------------------------------------------------
# Displays a status message
# Globals:
# None
# Arguments:
# $* Status message to display
# Returns:
# None
# ------------------------------------------------------------------------------
display_status_message() {
local status=$*
echo "[ADD-ON] $status"
}
# ------------------------------------------------------------------------------
# Displays a debug message
# Globals:
# None
# Arguments:
# $* Status message to display
# Returns:
# None
# ------------------------------------------------------------------------------
display_debug_message() {
local status=$*
if [[ "$DEBUG" == "true" ]];
then
display_status_message "[DEBUG] $status"
fi
}
# ------------------------------------------------------------------------------
# Displays a error message and is able to terminate te script execution
# Globals:
# None
# Arguments:
# $1 Error message
# $2 Exitcode, script will continue execution when omitted
# Returns:
# None
# ------------------------------------------------------------------------------
display_error_message() {
local status=$1
local exitcode=${2:-0}
echo "[ADD-ON][ERROR] An error occured!" >&2
echo >&2
echo "!!! ERROR: $status" >&2
echo >&2
if [[ $exitcode -ne 0 ]];
then
exit "$exitcode"
fi
}
# ------------------------------------------------------------------------------
# Gets a configuration parameter form the configuration file
# Globals:
# CONFIG_PATH
# Arguments:
# $1 Key of the configuration parameter to get
# $2 'true' If the configuration value is an array, false otherwise
# Returns:
# The configuration value
# ------------------------------------------------------------------------------
get_config() {
local key=$1
local is_array=$2
if $is_array;
then
command jq --raw-output ".$key[]" $CONFIG_PATH
else
command jq --raw-output ".$key" $CONFIG_PATH
fi
}
# ==============================================================================
# SCRIPT LOGIC
# ==============================================================================
# ------------------------------------------------------------------------------
# Ensures user configuration contains required parameters
# Globals:
# EX_NO_LOGIN
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
ensure_config_requirements() {
local authorized_keys
local password
local username
local sftp
display_status_message 'Ensuring configuration requirements are met'
username=$(get_config 'username' false)
if [[ -z "$username" ]];
then
display_error_message \
'Setting a username in the mandatory!' "$EX_NO_USERNAME"
fi
authorized_keys=$(get_config 'authorized_keys' true)
password=$(get_config 'password' false)
if [[ -z "$authorized_keys" ]] && [[ -z "$password" ]];
then
display_error_message \
'Configuring a password or authorized keys is mandatory!' \
"$EX_NO_LOGIN"
fi
sftp=$(get_config 'sftp' false)
if [[ "$sftp" == "true" ]] && [[ "$username" != "root" ]];
then
display_error_message \
'You can only enable SFTP when the username is set to "root"' \
"$EX_SFTP_USERNAME"
fi
}
# ------------------------------------------------------------------------------
# Ensures all SSH host keys exists, if not, it will create them
# Globals:
# $EX_ED25519_HOST_KEY
# $EX_RSA_HOST_KEY
# $SSH_HOST_ED25519_KEY
# $SSH_HOST_RSA_KEY
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
ensure_host_keys_exist() {
display_debug_message 'Ensuring SSH host keys exists'
if [[ ! -f "$SSH_HOST_RSA_KEY" ]];
then
display_status_message 'Generating RSA host key'
command ssh-keygen -t rsa -f "$SSH_HOST_RSA_KEY" -N "" || \
display_error_message 'Failed to generate RSA host key' \
"$EX_RSA_HOST_KEY"
fi
if [[ ! -f "$SSH_HOST_ED25519_KEY" ]];
then
display_status_message 'Generating ED25519 host key'
command ssh-keygen -t ed25519 -f "$SSH_HOST_ED25519_KEY" -N "" || \
display_error_message 'Failed to generate ED25519 host key' \
"$EX_ED25519_HOST_KEY"
fi
}
# ------------------------------------------------------------------------------
# Creates a user account that is used to log in
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
setup_user() {
local username
username=$(get_config 'username' false)
username=${username,,}
if [[ "$username" != "root" ]];
then
display_status_message "Creating user to use for login"
(command adduser -D "$username" -s "/bin/sh" && \
command adduser "$username" wheel) || \
display_error_message 'Failed creating an user account for login' \
"$EX_USER_ADD"
echo 'exec sudo su -l' > "/home/$username/.profile" || \
display_error_message 'Failed configuring user profile' \
"$EX_USER_PROFILE"
command sed -i "s/AllowUsers\ .*/AllowUsers\ $username/" \
"$SSH_CONFIG_PATH"
else
display_status_message 'WARNING! username = root, this is a bad idea!'
command sed -i "s/PermitRootLogin\ .*/PermitRootLogin\ yes/" \
"$SSH_CONFIG_PATH"
fi
}
# ------------------------------------------------------------------------------
# Sets up the authorized keys
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
setup_authorized_keys() {
local authorized_keys
authorized_keys=$(get_config 'authorized_keys' true)
if [[ ! -z "$authorized_keys" ]];
then
display_status_message 'Setting up authorized_keys'
display_debug_message 'Adding authorized keys to file'
while read -r key;
do
display_debug_message "Adding public key: $key"
echo "$key" >> "$SSH_AUTHORIZED_KEYS_PATH"
done <<< "$authorized_keys"
else
display_status_message 'Login using public/private keypair is disabled.'
fi
}
# ------------------------------------------------------------------------------
# Sets up password authentication
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
setup_password_authentication() {
local password
local username
password=$(get_config 'password' false)
username=$(get_config 'username' false)
if [[ ! -z "$password" ]]; then
display_status_message 'Setting up and enabling password login'
echo "$username:$password" | chpasswd 2&> /dev/null
command sed -i "s/PasswordAuthentication.*/PasswordAuthentication\ yes/" \
"$SSH_CONFIG_PATH"
else
echo "$username:$username" | chpasswd 2&> /dev/null
display_status_message 'Login using a password is disabled'
fi
}
# ------------------------------------------------------------------------------
# Configures the SSHd port
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
configure_port() {
local port
port=$(get_config 'port' false)
if [[ ! -z "$port" ]];
then
display_status_message "Setting SSH port to: $port"
command sed -i "s/Port\ .*/Port\ $port/" "$SSH_CONFIG_PATH"
else
display_status_message 'Setting SSH port to: 22'
command sed -i "s/Port\ .*/Port\ 22/" "$SSH_CONFIG_PATH"
fi
}
# ------------------------------------------------------------------------------
# Configures SFTP access
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
configure_sftp() {
local sftp
sftp=$(get_config 'sftp' false)
if [[ "$sftp" == "true" ]];
then
display_status_message "SFTP access is enabled"
else
display_status_message "SFTP access is disabled"
command sed -i '/Subsystem sftp/s/^/#/g' "$SSH_CONFIG_PATH"
fi
}
# ------------------------------------------------------------------------------
# Link a set of common used directories in the home folder
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
link_common_directories() {
local directories
display_status_message 'Linking common directories into the home folder'
directories="addons backup config share ssl"
for dir in $directories;
do
display_debug_message "Linking common directory $dir"
command ln -s "/$dir" "$HOME/$dir" || display_error_message \
"Failed linking common directory: $dir" "$EX_COMMON_LINK"
done;
}
# ------------------------------------------------------------------------------
# Persist all shell history in the permanent data storage directory
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
persist_shell_history() {
display_status_message 'Configuring shell to persist history'
command touch "$ZSH_HISTORY_PERSISTANT_FILE"
command chmod 600 "$ZSH_HISTORY_PERSISTANT_FILE"
command ln -s -f "$ZSH_HISTORY_PERSISTANT_FILE" "$ZSH_HISTORY_FILE"
}
# ------------------------------------------------------------------------------
# Install list of user requested Alpine packages
# Globals:
# EX_PACKAGE_FAILED
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
install_packages() {
local packages
packages=$(get_config 'packages' true)
if [[ ! -z "$packages" ]];
then
display_status_message 'Installing user requested Alpine packages'
display_status_message 'Updating Alpine packages repository indexes'
command apk update || display_error_message \
'Failed updating Alpine packages repository indexes' "$EX_APK_UPDATE"
for package in $packages;
do
display_status_message "Installing Alpine package: $package"
command apk add "$package" || display_error_message \
"Failed installing package $package" $EX_PACKAGE_FAILED
done
fi
}
# ------------------------------------------------------------------------------
# Runs configured custom commands on startup of the add-on
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
run_init_commands() {
local commands
commands=$(get_config 'init_commands' true)
if [[ ! -z "$commands" ]];
then
display_status_message 'Running custom init commands'
while read -r cmd;
do
display_debug_message "Running command: $cmd"
eval "$cmd" || display_error_message \
"Failed executing init command: $cmd" "$EX_INIT_COMMAND"
done <<< "$commands"
else
display_debug_message 'No custom init commands configured'
fi
}
# ------------------------------------------------------------------------------
# Starts the SSH daemon
# Globals:
# $DEBUG
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
start_ssh_server() {
display_status_message 'Starting SSH daemon'
if [[ "$DEBUG" == "true" ]];
then
command /usr/sbin/sshd -D -d -e < /dev/null
else
command /usr/sbin/sshd -D -e < /dev/null
fi
}
# ------------------------------------------------------------------------------
# Cleanup function after execution is of the script is stopped. (trap)
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
cleanup() {
true
}
# ==============================================================================
# RUN LOGIC
# ------------------------------------------------------------------------------
# Globals:
# EX_OK
# HOMEBRIDGE_CONFIG_FILE
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
main() {
trap cleanup ERR
trap cleanup EXIT
ensure_config_requirements
ensure_host_keys_exist
setup_user
setup_authorized_keys
setup_password_authentication
configure_port
configure_sftp
link_common_directories
persist_shell_history
install_packages
run_init_commands
start_ssh_server
exit "$EX_OK"
}
main

View file

@ -1,71 +0,0 @@
# Basics
# ===================
Port 22
AddressFamily any
TCPKeepAlive no
ClientAliveInterval 600
ClientAliveCountMax 3
UseDNS yes
# Loggin
# ===================
SyslogFacility AUTH
LogLevel VERBOSE
# Security
# ===================
Protocol 2
StrictModes yes
HostKey /data/ssh_host_rsa_key
HostKey /data/ssh_host_ed25519_key
# Cryptography
# ===================
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
# Authentication
# ===================
LoginGraceTime 120
MaxAuthTries 6
MaxSessions 10
MaxStartups 10:30:100
PermitRootLogin no
AllowUsers root
PubkeyAuthentication yes
IgnoreRhosts yes
HostbasedAuthentication no
IgnoreUserKnownHosts no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
PasswordAuthentication no
AuthorizedKeysFile /etc/ssh/authorized_keys
# Environment
# ===================
PermitUserEnvironment no
# Forwarding / Tunnel
# ===================
X11Forwarding no
X11DisplayOffset 10
X11UseLocalhost yes
PermitTunnel no
AllowTcpForwarding no
AllowAgentForwarding no
GatewayPorts no
# Messages
# ===================
Banner none
PrintMotd yes
# SFTP
=====================
Subsystem sftp /usr/lib/ssh/sftp-server
# Misc
# ===================
AcceptEnv LANG LC_*

View file

@ -1 +0,0 @@
%wheel ALL=(ALL) NOPASSWD: ALL

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

View file

@ -1,14 +0,0 @@
# Hass.io Add-on Changelog: Terminal
All notable changes to this add-on will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## Unreleased
-
## 1.0.0 - 2017-08-16
### Added
- First version of the Terminal Add-on
- This CHANGELOG file

View file

@ -1,21 +0,0 @@
FROM %%BASE_IMAGE%%
MAINTAINER Franck Nijhof <frenck@geekchimp.com>
# Add env
ENV LANG="C.UTF-8" \
TERM="xterm-256color"
# Copy data
COPY files/run.sh /
COPY files/hassio /usr/bin/
COPY files/motd /etc/
COPY files/.zshrc /root/
COPY files/.tmux.conf /root/
# Setup base
RUN apk add --no-cache jq openssh-client sudo zsh openssl libxml2-utils \
ncurses curl wget net-tools bind-tools rsync git nmap wget awake \
nano vim mosquitto-clients mariadb-client tmux ttyd && \
git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh && \
chmod a+x /run.sh /usr/bin/hassio
CMD [ "/run.sh" ]

View file

@ -1,248 +1,7 @@
# Hass.io Add-on: Terminal
# Community Hass.io Add-on: Terminal
![Project Stage][project-stage-shield]
![Maintenance][maintenance-shield]
![Awesome][awesome-shield]
[![License][license-shield]](LICENSE.md)
This is just a configuration stub to make the Hass.io repository work.
This add-on allows you to log in to your Hass.io Home Assistant instance using
a web terminal. Giving you to access your Hass.io folders and also includes a
command-line tool to do things like restart, update, and check your instance.
The add-on itself can be found at the following URL:
![Terminal in the Home Assistant Frontend](images/screenshot.png)
## Docker status
[![Docker Architecture][armhf-arch-shield]][armhf-dockerhub]
[![Docker Version][armhf-version-shield]][armhf-microbadger]
[![Docker Layers][armhf-layers-shield]][armhf-microbadger]
[![Docker Pulls][armhf-pulls-shield]][armhf-dockerhub]
[![Docker Architecture][aarch64-arch-shield]][aarch64-dockerhub]
[![Docker Version][aarch64-version-shield]][aarch64-microbadger]
[![Docker Layers][aarch64-layers-shield]][aarch64-microbadger]
[![Docker Pulls][aarch64-pulls-shield]][aarch64-dockerhub]
[![Docker Architecture][amd64-arch-shield]][amd64-dockerhub]
[![Docker Version][amd64-version-shield]][amd64-microbadger]
[![Docker Layers][amd64-layers-shield]][amd64-microbadger]
[![Docker Pulls][amd64-pulls-shield]][amd64-dockerhub]
[![Docker Architecture][i386-arch-shield]][i386-dockerhub]
[![Docker Version][i386-version-shield]][i386-microbadger]
[![Docker Layers][i386-layers-shield]][i386-microbadger]
[![Docker Pulls][i386-pulls-shield]][i386-dockerhub]
## Features
- Access your terminal right from the web!
- Add-able to your Home Assistant interface.
- Debug mode for allowing you to triage issues easier.
- Compatible if Hass.io was installed via the generic Linux installer.
- Have Alpine packages installed on start. This will allow you to install your
favorite tools, which will be available every single time you log in.
- Execute custom commands on start automatically, so you can customize the shell
to your likings.
- [ZSH][zsh] as its default shell. Easier to use for the beginner, more advanced
for the more experienced user. It even comes preloaded with
["Oh My ZSH"][ohmyzsh], with some plugins enabled as well.
- Contains a sensible set of tools right out of the box: curl, Wget, RSync, GIT,
Nmap, Mosquitto client, MariaDB/MySQL client, Awake (“wake on lan”), Nano, Vim,
tmux, and a bunch commonly used networking tools.
## Installation
The installation of this add-on is pretty straight forward and not different in
comparison to installing any other Hass.io add-on.
1. [Add our Hass.io add-ons repository][repository] to your Hass.io instance
2. Install the "Terminal" add-on from our repository
3. Start the "Terminal" add-on
4. Check the logs of the "Terminal" add-on to see if everything
went well.
5. Surf to your Hass.io instance and use port `7681` (e.g.
`http://hassio.local:7681`).
Please read the rest of this document further instructions.
## Configuration
_Please remember to restart the add-on when the configuration changes._
Example add-on configuration:
```json
{
"debug": false,
"username": "hass",
"password": "changeme",
"ssl": true,
"certfile": "fullchain.pem",
"keyfile": "privkey.pem",
"packages": [
"python",
"python-dev",
"py-pip",
"build-base"
],
"init_commands": [
"pip install virtualenv",
"pip install yamllint"
]
}
```
_*Note*: This is just an example, don't copy and past it! Create your own!_
**Option: `debug`**
When set to `true` the addon will output more information in the logs of the
add-on. The add-on will also start the terminal server in debug mode.
This might be useful when you're dealing with an unknown issue. It is
recommended leaving to option set to `false`, unless you are troubleshooting.
**Option: `username`**
This option allows you to enable authentication on accessing the terminal.
It is only used for the authentication; you will be the `root` user after
you have authenticated. Using `root` as the username is possible, but not
recommended. Leaving it empty would disable the possibility to authentication
completely.
_*Note*: If you set an `username`, `password` becomes mandatory as well._
**Option: `password`**
Sets the password to authenticate with. Leaving it empty would disable the
possibility to authenticate completely.
_*Note*: If you set a `password`, `username` becomes mandatory as well._
**Option: `ssl`**
Enables/Disables SSL (HTTPS) on the web terminal. Set it `true` to enable it,
`false` otherwise.
**Option: `certfile`**
The certificate file to use for SSL.
_*Note*: The file MUST be stored in `/ssl/`, which is default for Hass.io_
**Option: `keyfile`**
The private key file to use for SSL.
_*Note*: The file MUST be stored in `/ssl/`, which is default for Hass.io_
**Option: `packages`**
Allows you to specify additional [Alpine packages][alpine-packages] to be
installed in your shell environment (e.g. Python, Joe, Irssi).
_*Note*: Adding many packages will result in a longer start-up
time for the add-on._
**Option: `init_commands`**
Customize your terminal environment even more with the `init_commands` option.
Add one or more shell commands to the list, and they will be executed every
single time this add-on starts.
## Embedding into Home Assistant
It is possible to embed the terminal directly into Home Assistant, allowing
you to access your terminal through the Home Assistant frontend.
Home Assistant provides the `panel_iframe` component, for these purposes.
Example configuration:
```yaml
panel_iframe:
terminal:
title: Terminal
icon: mdi:console
url: https://addres.to.your.hass.io:7681
```
## Support
Got questions? Got some unexpected behavior caused by this plugin?
Please [open an issue on our GitHub repository][issues] and we'll do our best
to help you out.
## Credits
A big shout out to the following people, without them this add-on wasn't possible:
- The team & community of [Home Assistant][home-assistant] for developing such an
excellent home automation toolkit
Thank you all!
## More Hass.io add-ons
Do you like this add-on? Want some more functionality to your Hass.io Home
Assistant instance?
We've created multiple add-ons for Hass.io. For a full list, check out
our [GitHub Repository][repository].
## License
MIT License
Copyright (c) 2017 Franck Nijhof
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
[aarch64-arch-shield]: https://img.shields.io/badge/architecture-aarch64-blue.svg
[aarch64-dockerhub]: https://hub.docker.com/r/hassioaddons/terminal-aarch64
[aarch64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/terminal-aarch64.svg
[aarch64-microbadger]: https://microbadger.com/images/hassioaddons/terminal-aarch64
[aarch64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/terminal-aarch64.svg
[aarch64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/terminal-aarch64.svg
[alpine-packages]: https://pkgs.alpinelinux.org/packages
[amd64-arch-shield]: https://img.shields.io/badge/architecture-amd64-blue.svg
[amd64-dockerhub]: https://hub.docker.com/r/hassioaddons/terminal-amd64
[amd64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/terminal-amd64.svg
[amd64-microbadger]: https://microbadger.com/images/hassioaddons/terminal-amd64
[amd64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/terminal-amd64.svg
[amd64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/terminal-amd64.svg
[armhf-arch-shield]: https://img.shields.io/badge/architecture-armhf-blue.svg
[armhf-dockerhub]: https://hub.docker.com/r/hassioaddons/terminal-armhf
[armhf-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/terminal-armhf.svg
[armhf-microbadger]: https://microbadger.com/images/hassioaddons/terminal-armhf
[armhf-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/terminal-armhf.svg
[armhf-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/terminal-armhf.svg
[awesome-shield]: https://img.shields.io/badge/awesome%3F-yes-brightgreen.svg
[home-assistant]: https://home-assistant.io
[i386-arch-shield]: https://img.shields.io/badge/architecture-i386-blue.svg
[i386-dockerhub]: https://hub.docker.com/r/hassioaddons/terminal-i386
[i386-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/terminal-i386.svg
[i386-microbadger]: https://microbadger.com/images/hassioaddons/terminal-i386
[i386-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/terminal-i386.svg
[i386-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/terminal-i386.svg
[issues]: https://github.com/hassio-addons/repository/issues
[license-shield]: https://img.shields.io/github/license/hassio-addons/repository.svg
[maintenance-shield]: https://img.shields.io/maintenance/yes/2017.svg
[ohmyzsh]: http://ohmyz.sh/
[project-stage-shield]: https://img.shields.io/badge/Project%20Stage-Development-yellowgreen.svg
[repository]: https://github.com/hassio-addons/repository
[zsh]: https://en.wikipedia.org/wiki/Z_shell
https://github.com/hassio-addons/addon-terminal

View file

@ -3,7 +3,7 @@
"version": "1.0.0",
"slug": "terminal",
"description": "Terminal access to your Home Assistant instance via the web",
"url": "https://github.com/hassio-addons/repository/tree/master/terminal",
"url": "https://github.com/hassio-addons/addon-terminal",
"webui": "http://[HOST]:[PORT:7681]",
"startup": "services",
"boot": "auto",

View file

@ -1,23 +0,0 @@
set-option -g default-shell /bin/zsh
set-option -g default-terminal $TERM
set-option -g base-index 1
setw -g pane-base-index 1
setw -g window-status-format "#[fg=white]#[bg=blue] #I #[bg=blue]#[fg=white] #W "
setw -g window-status-current-format "#[bg=brightmagenta]#[fg=white] *#I #[fg=white,bold]#[bg=cyan] [#W] "
set -g pane-border-fg black
set -g pane-active-border-fg blue
set -g status-fg white
set -g status-bg blue
set -g status-left ''
set -g status-right '%a %m-%d %H:%M'
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

View file

@ -1,88 +0,0 @@
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
# Path to your oh-my-zsh installation.
export ZSH=$HOME/.oh-my-zsh
# Set name of the theme to load. Optionally, if you set this to "random"
# it'll load a random theme each time that oh-my-zsh is loaded.
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
ZSH_THEME="robbyrussell"
# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE="true"
# Uncomment the following line to use hyphen-insensitive completion. Case
# sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE="true"
# Uncomment the following line to disable bi-weekly auto-update checks.
DISABLE_AUTO_UPDATE="true"
# Uncomment the following line to change how often to auto-update (in days).
# export UPDATE_ZSH_DAYS=13
# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS="true"
# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE="true"
# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION="true"
# Uncomment the following line to display red dots whilst waiting for completion.
COMPLETION_WAITING_DOTS="true"
# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY="true"
# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
# HIST_STAMPS="mm/dd/yyyy"
# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder
# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(extract git tmux nmap rsync)
source $ZSH/oh-my-zsh.sh
# User configuration
# export MANPATH="/usr/local/man:$MANPATH"
# You may need to manually set your language environment
# export LANG=en_US.UTF-8
# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
# export EDITOR='vim'
# else
# export EDITOR='mvim'
# fi
# Compilation flags
# export ARCHFLAGS="-arch x86_64"
# ssh
# export SSH_KEY_PATH="~/.ssh/rsa_id"
# Set personal aliases, overriding those provided by oh-my-zsh libs,
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig="mate ~/.zshrc"
# alias ohmyzsh="mate ~/.oh-my-zsh"
# Show motd on start
cat /etc/motd

View file

@ -1,101 +0,0 @@
#!/bin/bash
set -e
# helppage
if [ "$1" == "help" ] || [ "$#" -lt 2 ]; then
cat << EOF
---- Hass.IO Cli ----
HomeAssistant:
$ hassio homeassistant logs
$ hassio homeassistant restart
$ hassio homeassistant update
$ hassio homeassistant check
Host:
$ hassio host hardware
$ hassio host reboot
$ hassio host shutdown
$ hassio host update
Supervisor
$ hassio supervisor logs
$ hassio supervisor info
$ hassio supervisor reload
$ hassio supervisor update
EOF
fi
function call_api() {
get_cmd=('info' 'logs' 'hardware')
command='POST'
if [[ ${get_cmd[*]} =~ $2 ]]; then
command='GET'
fi
if ! api_ret="$(curl -s -X $command "http://hassio/$1/$2")"; then
echo "API error: $api_ret"
return 1
fi
if [ "$2" == "logs" ]; then
echo "$api_ret"
return 0
fi
result="$(echo "$api_ret" | jq --raw-output ".result")"
# On error
if [ "$result" == "error" ]; then
message="$(echo "$api_ret" | jq --raw-output ".message // empty")"
echo "Error on $1/$2:" "$message"
return 0
fi
# On success
data="$(echo "$api_ret" | jq 'if .data == {} then empty else .data end')"
if [ ! -z "$data" ]; then
echo "$data" | jq .
else
echo "Success $1/$2"
fi
return 0
}
######
# homeassistant functions
if [ "$1" == "homeassistant" ]; then
hass_cmd=('logs' 'restart' 'update' 'check')
if [[ ! ${hass_cmd[*]} =~ $2 ]]; then
echo "No homeassistant command '$2' found!"
exit 1
fi
call_api "$1" "$2"
fi
######
# host functions
if [ "$1" == "host" ]; then
hass_cmd=('reboot' 'shutdown' 'update' 'hardware')
if [[ ! ${hass_cmd[*]} =~ $2 ]]; then
echo "No host command '$2' found!"
exit 1
fi
call_api "$1" "$2"
fi
######
# supervisor functions
if [ "$1" == "supervisor" ]; then
hass_cmd=('logs' 'reload' 'update' 'info')
if [[ ! ${hass_cmd[*]} =~ $2 ]]; then
echo "No supervisor command '$2' found!"
exit 1
fi
call_api "$1" "$2"
fi

View file

@ -1,12 +0,0 @@
_ _ _____ ____
| | | | |_ _/ __ \
| |__| | __ _ ___ ___ | || | | |
| __ |/ _` / __/ __| | || | | |
| | | | (_| \__ \__ \_ _| || |__| |
|_| |_|\__,_|___/___(_)_____\____/
Our Cli:
$ hassio help

View file

@ -1,423 +0,0 @@
#!/usr/bin/env bash
# ==============================================================================
# Hass.io Add-on for Home Assistant: Terminal
# ==============================================================================
set -o errexit # Exit script when a command exits with non-zero status
set -o nounset # Exit script on use of an undefined variable
set -o pipefail # Return exit status of the last command in the pipe that failed
# ==============================================================================
# GLOBALS
# ==============================================================================
# Exit codes
readonly EX_OK=0 # Successful termination
readonly EX_NO_USERNAME=3 # No username specified in configuration
readonly EX_NO_PASSWORD=4 # No login data in user configuration
readonly EX_NO_CERTFILE=5 # SSL enabled, but no certfile configured
readonly EX_NO_KEYFILE=6 # SSL enabled, but no keyfile configured
readonly EX_CERTFILE_NOT_FOUND=7 # Specified certfile was not found
readonly EX_KEYFILE_NOT_FOUND=8 # Specified keyfile was not found
readonly EX_COMMON_LINK=10 # Failed to link common directory
readonly EX_APK_UPDATE=11 # Alpine update failed
readonly EX_PACKAGE_FAILED=12 # Alpine package installation failed
readonly EX_INIT_COMMAND=13 # Failed executing custom init command
# Configuration paths
readonly CONFIG_PATH=/data/options.json
# Shell history files
readonly ZSH_HISTORY_FILE=/root/.zsh_history
readonly ZSH_HISTORY_PERSISTANT_FILE=/data/.zsh_history
# SSL certificates base path
readonly SSL_CERT_PATH=/ssl
# Debug mode?
readonly DEBUG=$(jq --raw-output ".debug" $CONFIG_PATH)
# Arguments to pass into ttyd
readonly TTYD_DEFAULTS='--reconnect 30 --port 7681'
readonly TTYD_COMMAND='tmux new -A -s ttyd zsh'
export TTYD_SSL=''
export TTYD_CREDENTIALS=''
# ==============================================================================
# UTILITY
# ==============================================================================
# ------------------------------------------------------------------------------
# Displays a status message
# Globals:
# None
# Arguments:
# $* Status message to display
# Returns:
# None
# ------------------------------------------------------------------------------
display_status_message() {
local status=$*
echo "[ADD-ON] $status"
}
# ------------------------------------------------------------------------------
# Displays a debug message
# Globals:
# None
# Arguments:
# $* Status message to display
# Returns:
# None
# ------------------------------------------------------------------------------
display_debug_message() {
local status=$*
if [[ "$DEBUG" == "true" ]];
then
display_status_message "[DEBUG] $status"
fi
}
# ------------------------------------------------------------------------------
# Displays a error message and is able to terminate te script execution
# Globals:
# None
# Arguments:
# $1 Error message
# $2 Exitcode, script will continue execution when omitted
# Returns:
# None
# ------------------------------------------------------------------------------
display_error_message() {
local status=$1
local exitcode=${2:-0}
echo "[ADD-ON][ERROR] An error occured!" >&2
echo >&2
echo "!!! ERROR: $status" >&2
echo >&2
if [[ $exitcode -ne 0 ]];
then
exit "$exitcode"
fi
}
# ------------------------------------------------------------------------------
# Gets a configuration parameter form the configuration file
# Globals:
# CONFIG_PATH
# Arguments:
# $1 Key of the configuration parameter to get
# $2 'true' If the configuration value is an array, false otherwise
# Returns:
# The configuration value
# ------------------------------------------------------------------------------
get_config() {
local key=$1
local is_array=$2
if $is_array;
then
command jq --raw-output ".$key[]" $CONFIG_PATH
else
command jq --raw-output ".$key" $CONFIG_PATH
fi
}
# ==============================================================================
# SCRIPT LOGIC
# ==============================================================================
# ------------------------------------------------------------------------------
# Ensures user configuration contains required parameters
# Globals:
# EX_CERTFILE_NOT_FOUND
# EX_KEYFILE_NOT_FOUND
# EX_NO_CERTFILE
# EX_NO_KEYFILE
# EX_NO_PASSWORD
# EX_NO_USERNAME
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
ensure_config_requirements() {
local password
local username
local ssl
local certfile
local keyfile
display_status_message 'Ensuring configuration requirements are met'
username=$(get_config 'username' false)
password=$(get_config 'password' false)
if [[ ! -z "$username" ]] && [[ -z "$password" ]];
then
display_error_message \
'You have set an username, but no password!' "$EX_NO_PASSWORD"
fi
if [[ -z "$username" ]] && [[ ! -z "$password" ]];
then
display_error_message \
'You have set a password, but not username!' "$EX_NO_USERNAME"
fi
ssl=$(get_config 'ssl' false)
if [[ "$ssl" == "true" ]];
then
certfile=$(get_config 'certfile' false)
if [[ -z "$certfile" ]];
then
display_error_message 'SSL is enabled, but no certfile was specified' \
"$EX_NO_CERTFILE"
fi
if [[ ! -f "$SSL_CERT_PATH/$certfile" ]];
then
display_error_message 'The configured certfile is not found' \
"$EX_CERTFILE_NOT_FOUND"
fi
keyfile=$(get_config 'keyfile' false)
if [[ -z "$keyfile" ]];
then
display_error_message 'SSL is enabled, but no keyfile was specified' \
"$EX_NO_KEYFILE"
fi
if [[ ! -f "$SSL_CERT_PATH/$keyfile" ]];
then
display_error_message 'The configured keyfile is not found' \
"$EX_KEYFILE_NOT_FOUND"
fi
fi
}
# ------------------------------------------------------------------------------
# Sets up basic HTTP authentication
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
setup_credentials() {
local password
local username
password=$(get_config 'password' false)
username=$(get_config 'username' false)
if [[ ! -z "$username" ]] && [[ ! -z "$password" ]];
then
display_status_message 'Setting up and enabling authentication'
export TTYD_CREDENTIALS="--credential $username:$password"
fi
}
# ------------------------------------------------------------------------------
# Sets up SSL connections
# Globals:
# SSL_CERT_PATH
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
setup_ssl() {
local ssl
local certfile
local keyfile
local options
ssl=$(get_config 'ssl' false)
if [[ "$ssl" == "true" ]];
then
display_status_message 'Setting up and enabling SSL'
certfile=$(get_config 'certfile' false)
keyfile=$(get_config 'keyfile' false)
options='--ssl '
options+=" --ssl-cert $SSL_CERT_PATH/$certfile"
options+=" --ssl-key $SSL_CERT_PATH/$keyfile"
export TTYD_SSL="$options"
fi
}
# ------------------------------------------------------------------------------
# Link a set of common used directories in the home folder
# Globals:
# EX_COMMON_LINK
# HOME
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
link_common_directories() {
local directories
display_status_message 'Linking common directories into the home folder'
directories="addons backup config share ssl"
for dir in $directories;
do
display_debug_message "Linking common directory $dir"
command ln -s "/$dir" "$HOME/$dir" || display_error_message \
"Failed linking common directory: $dir" "$EX_COMMON_LINK"
done;
}
# ------------------------------------------------------------------------------
# Persist all shell history in the permanent data storage directory
# Globals:
# ZSH_HISTORY_FILE
# ZSH_HISTORY_PERSISTANT_FILE
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
persist_shell_history() {
display_status_message 'Configuring shell to persist history'
command touch "$ZSH_HISTORY_PERSISTANT_FILE"
command chmod 600 "$ZSH_HISTORY_PERSISTANT_FILE"
command ln -s -f "$ZSH_HISTORY_PERSISTANT_FILE" "$ZSH_HISTORY_FILE"
}
# ------------------------------------------------------------------------------
# Install list of user requested Alpine packages
# Globals:
# EX_APK_UPDATE
# EX_PACKAGE_FAILED
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
install_packages() {
local packages
packages=$(get_config 'packages' true)
if [[ ! -z "$packages" ]];
then
display_status_message 'Installing user requested Alpine packages'
display_status_message 'Updating Alpine packages repository indexes'
command apk update || display_error_message \
'Failed updating Alpine packages repository indexes' "$EX_APK_UPDATE"
for package in $packages;
do
display_status_message "Installing Alpine package: $package"
command apk add "$package" || display_error_message \
"Failed installing package $package" $EX_PACKAGE_FAILED
done
fi
}
# ------------------------------------------------------------------------------
# Runs configured custom commands on startup of the add-on
# Globals:
# EX_INIT_COMMAND
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
run_init_commands() {
local commands
commands=$(get_config 'init_commands' true)
if [[ ! -z "$commands" ]];
then
display_status_message 'Running custom init commands'
while read -r cmd;
do
display_debug_message "Running command: $cmd"
eval "$cmd" || display_error_message \
"Failed executing init command: $cmd" "$EX_INIT_COMMAND"
done <<< "$commands"
else
display_debug_message 'No custom init commands configured'
fi
}
# ------------------------------------------------------------------------------
# Starts the SSH daemon
# Globals:
# DEBUG
# TTYD_COMMAND
# TTYD_CREDENTIALS
# TTYD_DEFAULTS
# TTYD_SSL
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
start_terminal_server() {
display_status_message 'Starting terminal server'
if [[ "$DEBUG" == "true" ]];
then
command ttyd -d 7 $TTYD_DEFAULTS $TTYD_CREDENTIALS $TTYD_SSL $TTYD_COMMAND
else
command ttyd -d 1 $TTYD_DEFAULTS $TTYD_CREDENTIALS $TTYD_SSL $TTYD_COMMAND
fi
}
# ------------------------------------------------------------------------------
# Cleanup function after execution is of the script is stopped. (trap)
# Globals:
# None
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
cleanup() {
true
}
# ==============================================================================
# RUN LOGIC
# ------------------------------------------------------------------------------
# Globals:
# EX_OK
# HOMEBRIDGE_CONFIG_FILE
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
main() {
trap cleanup ERR
trap cleanup EXIT
ensure_config_requirements
link_common_directories
persist_shell_history
install_packages
run_init_commands
setup_credentials
setup_ssl
start_terminal_server
exit "$EX_OK"
}
main

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB