diff --git a/.devcontainer.json b/.devcontainer.json new file mode 100644 index 0000000..8aaa696 --- /dev/null +++ b/.devcontainer.json @@ -0,0 +1,33 @@ +{ + "name": "Example devcontainer for add-on repositories", + "image": "ghcr.io/home-assistant/devcontainer:2-addons", + "appPort": ["7123:8123", "7357:4357"], + "postStartCommand": "bash devcontainer_bootstrap", + "runArgs": ["-e", "GIT_EDITOR=code --wait", "--privileged"], + "containerEnv": { + "WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}" + }, + "workspaceFolder": "/mnt/supervisor/addons/local/${localWorkspaceFolderBasename}", + "workspaceMount": "source=${localWorkspaceFolder},target=${containerWorkspaceFolder},type=bind,consistency=cached", + "customizations": { + "vscode": { + "extensions": ["timonwong.shellcheck", "esbenp.prettier-vscode"], + "settings": { + "terminal.integrated.profiles.linux": { + "zsh": { + "path": "/usr/bin/zsh" + } + }, + "terminal.integrated.defaultProfile.linux": "zsh", + "editor.formatOnPaste": false, + "editor.formatOnSave": true, + "editor.formatOnType": true, + "files.trimTrailingWhitespace": true + } + } + }, + "mounts": [ + "type=volume,target=/var/lib/docker", + "type=volume,target=/mnt/supervisor" + ] +} diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..f84f1ce --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: weekly + time: "06:00" \ No newline at end of file diff --git a/.github/workflows/builder.yaml b/.github/workflows/builder.yaml new file mode 100644 index 0000000..e4a6fae --- /dev/null +++ b/.github/workflows/builder.yaml @@ -0,0 +1,117 @@ +name: Builder + +env: + BUILD_ARGS: "--test" + MONITORED_FILES: "build.yaml config.yaml Dockerfile rootfs" + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + init: + runs-on: ubuntu-latest + name: Initialize builds + outputs: + changed_addons: ${{ steps.changed_addons.outputs.addons }} + changed: ${{ steps.changed_addons.outputs.changed }} + steps: + - name: Check out the repository + uses: actions/checkout@v4.2.2 + + - name: Get changed files + id: changed_files + uses: jitterbit/get-changed-files@v1 + + - name: Find add-on directories + id: addons + uses: home-assistant/actions/helpers/find-addons@master + + - name: Get changed add-ons + id: changed_addons + run: | + declare -a changed_addons + for addon in ${{ steps.addons.outputs.addons }}; do + if [[ "${{ steps.changed_files.outputs.all }}" =~ $addon ]]; then + for file in ${{ env.MONITORED_FILES }}; do + if [[ "${{ steps.changed_files.outputs.all }}" =~ $addon/$file ]]; then + if [[ ! "${changed_addons[@]}" =~ $addon ]]; then + changed_addons+=("\"${addon}\","); + fi + fi + done + fi + done + + changed=$(echo ${changed_addons[@]} | rev | cut -c 2- | rev) + + if [[ -n ${changed} ]]; then + echo "Changed add-ons: $changed"; + echo "changed=true" >> $GITHUB_OUTPUT; + echo "addons=[$changed]" >> $GITHUB_OUTPUT; + else + echo "No add-on had any monitored files changed (${{ env.MONITORED_FILES }})"; + fi + build: + needs: init + runs-on: ubuntu-latest + if: needs.init.outputs.changed == 'true' + name: Build ${{ matrix.arch }} ${{ matrix.addon }} add-on + strategy: + matrix: + addon: ${{ fromJson(needs.init.outputs.changed_addons) }} + arch: ["aarch64", "amd64", "armhf", "armv7", "i386"] + permissions: + contents: read + packages: write + + steps: + - name: Check out repository + uses: actions/checkout@v4.2.2 + + - name: Get information + id: info + uses: home-assistant/actions/helpers/info@master + with: + path: "./${{ matrix.addon }}" + + - name: Check if add-on should be built + id: check + run: | + if [[ "${{ steps.info.outputs.image }}" == "null" ]]; then + echo "Image property is not defined, skipping build" + echo "build_arch=false" >> $GITHUB_OUTPUT; + elif [[ "${{ steps.info.outputs.architectures }}" =~ ${{ matrix.arch }} ]]; then + echo "build_arch=true" >> $GITHUB_OUTPUT; + echo "image=$(echo ${{ steps.info.outputs.image }} | cut -d'/' -f3)" >> $GITHUB_OUTPUT; + if [[ -z "${{ github.head_ref }}" ]] && [[ "${{ github.event_name }}" == "push" ]]; then + echo "BUILD_ARGS=" >> $GITHUB_ENV; + fi + else + echo "${{ matrix.arch }} is not a valid arch for ${{ matrix.addon }}, skipping build"; + echo "build_arch=false" >> $GITHUB_OUTPUT; + fi + + - name: Login to GitHub Container Registry + if: env.BUILD_ARGS != '--test' + uses: docker/login-action@v3.4.0 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build ${{ matrix.addon }} add-on + if: steps.check.outputs.build_arch == 'true' + uses: home-assistant/builder@2025.03.0 + with: + args: | + ${{ env.BUILD_ARGS }} \ + --${{ matrix.arch }} \ + --target /data/${{ matrix.addon }} \ + --image "${{ steps.check.outputs.image }}" \ + --docker-hub "ghcr.io/${{ github.repository_owner }}" \ + --addon \ No newline at end of file diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..9efe13d --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,41 @@ +name: Lint + +on: + push: + branches: + - master + pull_request: + branches: + - master + schedule: + - cron: "0 0 * * *" + +jobs: + find: + name: Find add-ons + runs-on: ubuntu-latest + outputs: + addons: ${{ steps.addons.outputs.addons_list }} + steps: + - name: ⤵️ Check out code from GitHub + uses: actions/checkout@v4.2.2 + + - name: 🔍 Find add-on directories + id: addons + uses: home-assistant/actions/helpers/find-addons@master + + lint: + name: Lint add-on ${{ matrix.path }} + runs-on: ubuntu-latest + needs: find + strategy: + matrix: + path: ${{ fromJson(needs.find.outputs.addons) }} + steps: + - name: ⤵️ Check out code from GitHub + uses: actions/checkout@v4.2.2 + + - name: 🚀 Run Home Assistant Add-on Lint + uses: frenck/action-addon-linter@v2.18 + with: + path: "./${{ matrix.path }}" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md index 7c581c7..c619ea0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,23 @@ -# home-assistant-futurehome +# Futurehome Home Assistant add-on + Futurehome add-on for Home Assistant. + +[![Open your Home Assistant instance and show the add add-on repository dialog with a specific repository URL pre-filled.](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fadrianjagielak%2Fhome-assistant-futurehome) + + diff --git a/futurehome/CHANGELOG.md b/futurehome/CHANGELOG.md new file mode 100644 index 0000000..beaf414 --- /dev/null +++ b/futurehome/CHANGELOG.md @@ -0,0 +1,15 @@ + + +## 1.2.0 + +- Add an apparmor profile +- Update to 3.15 base image with s6 v3 +- Add a sample script to run as service and constrain in aa profile + +## 1.1.0 + +- Updates + +## 1.0.0 + +- Initial release diff --git a/futurehome/Dockerfile b/futurehome/Dockerfile new file mode 100644 index 0000000..9d1a983 --- /dev/null +++ b/futurehome/Dockerfile @@ -0,0 +1,12 @@ +# https://developers.home-assistant.io/docs/add-ons/configuration#add-on-dockerfile +ARG BUILD_FROM +FROM $BUILD_FROM + +# Execute during the build of the image +ARG TEMPIO_VERSION BUILD_ARCH +RUN \ + curl -sSLf -o /usr/bin/tempio \ + "https://github.com/home-assistant/tempio/releases/download/${TEMPIO_VERSION}/tempio_${BUILD_ARCH}" + +# Copy root filesystem +COPY rootfs / diff --git a/futurehome/README.md b/futurehome/README.md new file mode 100644 index 0000000..262c360 --- /dev/null +++ b/futurehome/README.md @@ -0,0 +1,3 @@ +# Futurehome Home Assistant add-on + +Futurehome add-on for Home Assistant. diff --git a/futurehome/apparmor.txt b/futurehome/apparmor.txt new file mode 100644 index 0000000..e788a6c --- /dev/null +++ b/futurehome/apparmor.txt @@ -0,0 +1,57 @@ +#include + +profile example flags=(attach_disconnected,mediate_deleted) { + #include + + # Capabilities + file, + signal (send) set=(kill,term,int,hup,cont), + + # S6-Overlay + /init ix, + /bin/** ix, + /usr/bin/** ix, + /run/{s6,s6-rc*,service}/** ix, + /package/** ix, + /command/** ix, + /etc/services.d/** rwix, + /etc/cont-init.d/** rwix, + /etc/cont-finish.d/** rwix, + /run/{,**} rwk, + /dev/tty rw, + + # Bashio + /usr/lib/bashio/** ix, + /tmp/** rwk, + + # Access to options.json and other files within your addon + /data/** rw, + + # Start new profile for service + /usr/bin/my_program cx -> my_program, + + profile my_program flags=(attach_disconnected,mediate_deleted) { + #include + + # Receive signals from S6-Overlay + signal (receive) peer=*_example, + + # Access to options.json and other files within your addon + /data/** rw, + + # Access to mapped volumes specified in config.json + /share/** rw, + + # Access required for service functionality + # Note: List was built by doing the following: + # 1. Add what is obviously needed based on what is in the script + # 2. Add `complain` as a flag to this profile temporarily and run the addon + # 3. Review the audit log with `journalctl _TRANSPORT="audit" -g 'apparmor="ALLOWED"'` and add other access as needed + # Remember to remove the `complain` flag when you are done + /usr/bin/my_program r, + /bin/bash rix, + /bin/echo ix, + /etc/passwd r, + /dev/tty rw, + } +} \ No newline at end of file diff --git a/futurehome/build.yaml b/futurehome/build.yaml new file mode 100644 index 0000000..f1398ba --- /dev/null +++ b/futurehome/build.yaml @@ -0,0 +1,14 @@ +# https://developers.home-assistant.io/docs/add-ons/configuration#add-on-dockerfile +build_from: + aarch64: "ghcr.io/home-assistant/aarch64-base:3.15" + amd64: "ghcr.io/home-assistant/amd64-base:3.15" + armhf: "ghcr.io/home-assistant/armhf-base:3.15" + armv7: "ghcr.io/home-assistant/armv7-base:3.15" + i386: "ghcr.io/home-assistant/i386-base:3.15" +labels: + org.opencontainers.image.title: "Home Assistant Add-on: Futurehome" + org.opencontainers.image.description: "Futurehome Home Assistant add-on" + org.opencontainers.image.source: "https://github.com/adrianjagielak/home-assistant-futurehome" + org.opencontainers.image.licenses: "MIT License" +args: + TEMPIO_VERSION: "2021.09.0" diff --git a/futurehome/config.yaml b/futurehome/config.yaml new file mode 100644 index 0000000..c869bc9 --- /dev/null +++ b/futurehome/config.yaml @@ -0,0 +1,20 @@ +# https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config +name: Futurehome add-on +version: "0.0.1" +slug: example +description: Futurehome Home Assistant add-on +url: "https://github.com/adrianjagielak/home-assistant-futurehome" +arch: + - armhf + - armv7 + - aarch64 + - amd64 + - i386 +init: false +map: + - share:rw +options: + message: "Hello world..." +schema: + message: "str?" +image: "ghcr.io/adrianjagielak/{arch}-home-assistant-futurehome" diff --git a/futurehome/icon.png b/futurehome/icon.png new file mode 100644 index 0000000..d4415c1 Binary files /dev/null and b/futurehome/icon.png differ diff --git a/futurehome/logo.png b/futurehome/logo.png new file mode 100644 index 0000000..106e5c2 Binary files /dev/null and b/futurehome/logo.png differ diff --git a/futurehome/rootfs/etc/services.d/example/finish b/futurehome/rootfs/etc/services.d/example/finish new file mode 100755 index 0000000..230d179 --- /dev/null +++ b/futurehome/rootfs/etc/services.d/example/finish @@ -0,0 +1,15 @@ +#!/usr/bin/env bashio +# ============================================================================== +# Take down the S6 supervision tree when example fails +# s6-overlay docs: https://github.com/just-containers/s6-overlay +# ============================================================================== + +declare APP_EXIT_CODE=${1} + +if [[ "${APP_EXIT_CODE}" -ne 0 ]] && [[ "${APP_EXIT_CODE}" -ne 256 ]]; then + bashio::log.warning "Halt add-on with exit code ${APP_EXIT_CODE}" + echo "${APP_EXIT_CODE}" > /run/s6-linux-init-container-results/exitcode + exec /run/s6/basedir/bin/halt +fi + +bashio::log.info "Service restart after closing" diff --git a/futurehome/rootfs/etc/services.d/example/run b/futurehome/rootfs/etc/services.d/example/run new file mode 100755 index 0000000..6c329bd --- /dev/null +++ b/futurehome/rootfs/etc/services.d/example/run @@ -0,0 +1,19 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Start the example service +# s6-overlay docs: https://github.com/just-containers/s6-overlay +# ============================================================================== + +# Add your code here + +# Declare variables +declare message + +## Get the 'message' key from the user config options. +message=$(bashio::config 'message') + +## Print the message the user supplied, defaults to "Hello World..." +bashio::log.info "${message:="Hello World..."}" + +## Run your program +exec /usr/bin/my_program diff --git a/futurehome/rootfs/usr/bin/my_program b/futurehome/rootfs/usr/bin/my_program new file mode 100755 index 0000000..a287b13 --- /dev/null +++ b/futurehome/rootfs/usr/bin/my_program @@ -0,0 +1,3 @@ +#!/bin/bash + +echo "All done!" > /share/example_addon_output.txt diff --git a/futurehome/translations/en.yaml b/futurehome/translations/en.yaml new file mode 100644 index 0000000..70de024 --- /dev/null +++ b/futurehome/translations/en.yaml @@ -0,0 +1,4 @@ +configuration: + message: + name: Message + description: The message that will be printed to the log when starting this example add-on. diff --git a/repository.yaml b/repository.yaml new file mode 100644 index 0000000..aec5f4c --- /dev/null +++ b/repository.yaml @@ -0,0 +1,4 @@ +# https://developers.home-assistant.io/docs/add-ons/repository#repository-configuration +name: Futurehome Home Assistant add-on repository +url: 'https://https://github.com/adrianjagielak/home-assistant-futurehome' +maintainer: Adrian Jagielak