From 5b3ae4e18e3cbefe42789675b96dd9934701394b Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Wed, 24 Apr 2019 13:39:35 +0200 Subject: [PATCH] Initial import --- README.md | 57 ++++++++++++ files/hassio-apparmor | 49 +++++++++++ files/hassio-apparmor.service | 12 +++ files/hassio-supervisor | 40 +++++++++ files/hassio-supervisor.service | 15 ++++ hassio_install | 150 ++++++++++++++++++++++++++++++++ 6 files changed, 323 insertions(+) create mode 100644 README.md create mode 100644 files/hassio-apparmor create mode 100644 files/hassio-apparmor.service create mode 100644 files/hassio-supervisor create mode 100644 files/hassio-supervisor.service create mode 100644 hassio_install diff --git a/README.md b/README.md new file mode 100644 index 0000000..673e693 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# Install Hass.io + +Beside the usage of the images it's also possible to run Hass.io on a generic system without flashing an image. + +## Requirements + +``` +docker-ce +bash +jq +curl +avahi-daemon +dbus +``` + +## Optional + +``` +apparmor-utils +network-manager +``` + +## Run + +Run as root (sudo su): + +```bash +curl -sL https://raw.githubusercontent.com/home-assistant/hassio-build/master/install/hassio_install | bash -s +``` + +### Command line arguments +| argument | default | description | +|--------------------|-------------------|--------------------------------------------------------| +| -m \| --machine | | On a special platform they need set a machine type use | +| -d \| --data-share | /usr/share/hassio | data folder for hass.io installation | + +you can set these parameters by appending ` -- ` like: + +```bash +curl -sL https://raw.githubusercontent.com/home-assistant/hassio-build/master/install/hassio_install | bash -s -- -m MY_MACHINE +``` + +## Supported Machine types + +- intel-nuc +- odroid-c2 +- odroid-xu +- orangepi-prime +- qemuarm +- qemuarm-64 +- qemux86 +- qemux86-64 +- raspberrypi +- raspberrypi2 +- raspberrypi3 +- raspberrypi3-64 +- tinker \ No newline at end of file diff --git a/files/hassio-apparmor b/files/hassio-apparmor new file mode 100644 index 0000000..55f54b4 --- /dev/null +++ b/files/hassio-apparmor @@ -0,0 +1,49 @@ +#!/bin/sh +set -e + +# Load configs +CONFIG_FILE=/etc/hassio.json + +# Read configs +DATA="$(jq --raw-output '.data // "/usr/share/hassio"' ${CONFIG_FILE})" +PROFILES_DIR=${DATA}/apparmor +CACHE_DIR="${PROFILES_DIR}/cache" +REMOVE_DIR="${PROFILES_DIR}/remove" + +# Exists AppArmor +if ! command -v apparmor_parser > /dev/null 2>&1; then + echo "[Warning]: No apparmor_parser on host system!" + exit 0 +fi + +# Check folder structure +mkdir -p ${PROFILES_DIR} +mkdir -p ${CACHE_DIR} +mkdir -p ${REMOVE_DIR} + +# Load/Update exists/new profiles +for profile in ${PROFILES_DIR}/*; do + if [ ! -f ${profile} ]; then + continue + fi + + # Load Profile + if ! apparmor_parser -r -W -L ${CACHE_DIR} ${profile}; then + echo "[Error]: Can't load profile ${profile}" + fi +done + +# Cleanup old profiles +for profile in ${REMOVE_DIR}/*; do + if [ ! -f ${profile} ]; then + continue + fi + + # Unload Profile + if apparmor_parser -R -W -L ${CACHE_DIR} ${profile}; then + if rm ${profile}; then + continue + fi + fi + echo "[Error]: Can't remove profile ${profile}" +done diff --git a/files/hassio-apparmor.service b/files/hassio-apparmor.service new file mode 100644 index 0000000..e8d8f49 --- /dev/null +++ b/files/hassio-apparmor.service @@ -0,0 +1,12 @@ +[Unit] +Description=Hass.io AppArmor +Wants=hassio-supervisor.service +Before=docker.service hassio-supervisor.service + +[Service] +Type=oneshot +RemainAfterExit=true +ExecStart=/usr/sbin/hassio-apparmor + +[Install] +WantedBy=multi-user.target diff --git a/files/hassio-supervisor b/files/hassio-supervisor new file mode 100644 index 0000000..4efc36a --- /dev/null +++ b/files/hassio-supervisor @@ -0,0 +1,40 @@ +#!/bin/sh +set -e + +# Load configs +CONFIG_FILE=/etc/hassio.json + +SUPERVISOR="$(jq --raw-output '.supervisor' ${CONFIG_FILE})" +HOMEASSISTANT="$(jq --raw-output '.homeassistant' ${CONFIG_FILE})" +DATA="$(jq --raw-output '.data // "/usr/share/hassio"' ${CONFIG_FILE})" + +# AppArmor Support +if command -v apparmor_parser > /dev/null 2>&1 && grep hassio-supervisor /sys/kernel/security/apparmor/profiles > /dev/null 2>&1; then + APPARMOR="--security-opt apparmor=hassio-supervisor" +else + APPARMOR="--security-opt apparmor:unconfined" +fi + +# Init supervisor +HASSIO_DATA=${DATA} +HASSIO_IMAGE_ID=$(docker inspect --format='{{.Id}}' ${SUPERVISOR}) +HASSIO_CONTAINER_ID=$(docker inspect --format='{{.Image}}' hassio_supervisor || echo "") + +runSupervisor() { + docker rm --force hassio_supervisor || true + docker run --name hassio_supervisor \ + --privileged \ + $APPARMOR \ + --security-opt seccomp=unconfined \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /var/run/dbus:/var/run/dbus \ + -v ${HASSIO_DATA}:/data \ + -e SUPERVISOR_SHARE=${HASSIO_DATA} \ + -e SUPERVISOR_NAME=hassio_supervisor \ + -e HOMEASSISTANT_REPOSITORY=${HOMEASSISTANT} \ + ${SUPERVISOR} +} + +# Run supervisor +mkdir -p ${HASSIO_DATA} +([ "${HASSIO_IMAGE_ID}" = "${HASSIO_CONTAINER_ID}" ] && docker start --attach hassio_supervisor) || runSupervisor diff --git a/files/hassio-supervisor.service b/files/hassio-supervisor.service new file mode 100644 index 0000000..2ebb8ac --- /dev/null +++ b/files/hassio-supervisor.service @@ -0,0 +1,15 @@ +[Unit] +Description=Hass.io supervisor +Requires=docker.service +After=docker.service dbus.socket + +[Service] +Type=simple +Restart=always +RestartSec=5s +ExecStartPre=-/usr/bin/docker stop hassio_supervisor +ExecStart=/usr/sbin/hassio-supervisor +ExecStop=-/usr/bin/docker stop hassio_supervisor + +[Install] +WantedBy=multi-user.target diff --git a/hassio_install b/hassio_install new file mode 100644 index 0000000..e24c45c --- /dev/null +++ b/hassio_install @@ -0,0 +1,150 @@ +#!/bin/bash +set -e + +ARCH=$(uname -m) +DOCKER_REPO=homeassistant +DATA_SHARE=/usr/share/hassio +URL_VERSION="https://s3.amazonaws.com/hassio-version/stable.json" +URL_BIN_HASSIO="https://raw.githubusercontent.com/home-assistant/hassio-installer/master/install/files/hassio-supervisor" +URL_BIN_APPARMOR="https://raw.githubusercontent.com/home-assistant/hassio-installer/master/install/files/hassio-apparmor" +URL_SERVICE_HASSIO="https://raw.githubusercontent.com/home-assistant/hassio-installer/master/install/files/hassio-supervisor.service" +URL_SERVICE_APPARMOR="https://raw.githubusercontent.com/home-assistant/hassio-installer/master/install/files/hassio-apparmor.service" +URL_APPARMOR_PROFILE="http://s3.amazonaws.com/hassio-version/apparmor.txt" + +# Check env +command -v systemctl > /dev/null 2>&1 || { echo "[Error] Only systemd is supported!"; exit 1; } +command -v docker > /dev/null 2>&1 || { echo "[Error] Please install docker first"; exit 1; } +command -v jq > /dev/null 2>&1 || { echo "[Error] Please install jq first"; exit 1; } +command -v curl > /dev/null 2>&1 || { echo "[Error] Please install curl first"; exit 1; } +command -v avahi-daemon > /dev/null 2>&1 || { echo "[Error] Please install avahi first"; exit 1; } +command -v dbus-daemon > /dev/null 2>&1 || { echo "[Error] Please install dbus first"; exit 1; } +command -v apparmor_parser > /dev/null 2>&1 || echo "[Warning] No AppArmor support on host." +command -v nmcli > /dev/null 2>&1 || echo "[Warning] No NetworkManager support on host." + +function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; } + +# Parse command line parameters +while [[ $# > 0 ]]; do + arg="$1" + + case $arg in + -m|--machine) + MACHINE=$2 + shift + ;; + -d|--data-share) + DATA_SHARE=$2 + shift + ;; + *) + echo "[Error] Unrecognized option $1" + exit 1 + ;; + esac + shift +done + +# Generate hardware options +case $ARCH in + "i386" | "i686") + MACHINE=${MACHINE:=qemux86} + HOMEASSISTANT_DOCKER="$DOCKER_REPO/$MACHINE-homeassistant" + HASSIO_DOCKER="$DOCKER_REPO/i386-hassio-supervisor" + ;; + "x86_64") + MACHINE=${MACHINE:=qemux86-64} + HOMEASSISTANT_DOCKER="$DOCKER_REPO/$MACHINE-homeassistant" + HASSIO_DOCKER="$DOCKER_REPO/amd64-hassio-supervisor" + ;; + "arm" | "armv7l" | "armv6l") + if [ -z $MACHINE ]; then + echo "[ERROR] Please set machine for $ARCH" + exit 1 + fi + HOMEASSISTANT_DOCKER="$DOCKER_REPO/$MACHINE-homeassistant" + HASSIO_DOCKER="$DOCKER_REPO/armhf-hassio-supervisor" + ;; + "aarch64") + if [ -z $MACHINE ]; then + echo "[ERROR] Please set machine for $ARCH" + exit 1 + fi + HOMEASSISTANT_DOCKER="$DOCKER_REPO/$MACHINE-homeassistant" + HASSIO_DOCKER="$DOCKER_REPO/aarch64-hassio-supervisor" + ;; + *) + echo "[Error] $ARCH unknown!" + exit 1 + ;; +esac + +if [ -z "${HOMEASSISTANT_DOCKER}" ]; then + echo "[Error] Found no Home Assistant Docker images for this host!" +fi + +### Main + +# Init folders +if [ ! -d "$DATA_SHARE" ]; then + mkdir -p "$DATA_SHARE" +fi + +# Read infos from web +HASSIO_VERSION=$(curl -s $URL_VERSION | jq -e -r '.supervisor') + +## +# Write config +cat > /etc/hassio.json <<- EOF +{ + "supervisor": "${HASSIO_DOCKER}", + "homeassistant": "${HOMEASSISTANT_DOCKER}", + "data": "${DATA_SHARE}" +} +EOF + +## +# Check DNS settings +DOCKER_VERSION="$(docker --version | grep -Po "\d{2}\.\d{2}\.\d")" +if version_gt "18.09.0" "${DOCKER_VERSION}" && [ ! -e "/etc/docker/daemon.json" ]; then + echo "[Warning] Create DNS settings for Docker to avoid systemd bug!" + mkdir -p /etc/docker + echo '{"dns": ["8.8.8.8", "8.8.4.4"]}' > /etc/docker/daemon.json + + echo "[Info] Restart Docker and wait 30 seconds" + systemctl restart docker.service && sleep 30 +fi + +## +# Pull supervisor image +echo "[Info] Install supervisor Docker container" +docker pull "$HASSIO_DOCKER:$HASSIO_VERSION" > /dev/null +docker tag "$HASSIO_DOCKER:$HASSIO_VERSION" "$HASSIO_DOCKER:latest" > /dev/null + +## +# Install Hass.io Supervisor +echo "[Info] Install supervisor startup scripts" +curl -sL ${URL_BIN_HASSIO} > /usr/sbin/hassio-supervisor +curl -sL ${URL_SERVICE_HASSIO} > /etc/systemd/system/hassio-supervisor.service + +chmod a+x /usr/sbin/hassio-supervisor +systemctl enable hassio-supervisor.service + +# +# Install Hass.io AppArmor +if command -v apparmor_parser > /dev/null 2>&1; then + echo "[Info] Install AppArmor scripts" + mkdir -p ${DATA_SHARE}/apparmor + curl -sL ${URL_BIN_APPARMOR} > /usr/sbin/hassio-apparmor + curl -sL ${URL_SERVICE_APPARMOR} > /etc/systemd/system/hassio-apparmor.service + curl -sL ${URL_APPARMOR_PROFILE} > ${DATA_SHARE}/apparmor/hassio-supervisor + + chmod a+x /usr/sbin/hassio-apparmor + systemctl enable hassio-apparmor.service + + systemctl start hassio-apparmor.service +fi + +## +# Init system +echo "[Info] Run Hass.io" +systemctl start hassio-supervisor.service