Last active
January 20, 2022 14:36
-
-
Save danielpetroianu/6e00624436eab3036b0c8b270b359b62 to your computer and use it in GitHub Desktop.
Generate Homer services from docker labels. Inspired by https://github.com/pawelmalak/flame
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
_DOCKER_LABEL_NAME="homer.service.name" | |
_DOCKER_LABEL_URL="homer.service.url" | |
_DI_RESULT_JSONKEY_CATEGORY="category" | |
_DI_RESULT_JSONKEY_CATEGORY_ICON="category_icon" | |
_DI_RESULT_JSONKEY_CATEGORY_ORDER="category_order_index" | |
_DI_RESULT_JSONKEY_ICON="icon" | |
_DI_RESULT_JSONKEY_NAME="name" | |
_DI_RESULT_JSONKEY_DESCRIPTION="description" | |
_DI_RESULT_JSONKEY_URL="url" | |
_DI_RESULT_JSONKEY_URL_TARGET="url_target" # https://www.w3schools.com/tags/att_a_target.asp | |
_DI_RESULT_JSONKEY_ORDER="order_index" | |
function findDockerContainers() { | |
# get all containers that want to be displayed in Homer | |
docker ps --filter "label=$_DOCKER_LABEL_URL" --format "{{.Names}}" | |
} | |
function readDockerContainersLables() { | |
# get the labels from the passed containers and output them as json | |
function _jsonDockerInspectResult() { | |
jq '{ | |
'"$_DI_RESULT_JSONKEY_CATEGORY"' : (."homer.service.category.name" // "Apps"), | |
'"$_DI_RESULT_JSONKEY_CATEGORY_ICON"' : (."homer.service.category.icon" // ""), | |
'"$_DI_RESULT_JSONKEY_CATEGORY_ORDER"': (."homer.service.category.order_index" // "999"), | |
'"$_DI_RESULT_JSONKEY_ICON"' : (."homer.service.icon" // ""), | |
'"$_DI_RESULT_JSONKEY_NAME"' : (."'"$_DOCKER_LABEL_NAME"'" // ."com.docker.compose.service"), | |
'"$_DI_RESULT_JSONKEY_DESCRIPTION"' : (."homer.service.description" // ."'"$_DOCKER_LABEL_URL"'"), | |
'"$_DI_RESULT_JSONKEY_URL"' : (."'"$_DOCKER_LABEL_URL"'"), | |
'"$_DI_RESULT_JSONKEY_URL_TARGET"' : (."homer.service.url.target" // "_blank"), | |
'"$_DI_RESULT_JSONKEY_ORDER"' : (."homer.service.order_index" // "999") | |
}' | |
} | |
while read containerName; do | |
docker inspect $containerName --format='{{json .Config.Labels}}' | _jsonDockerInspectResult | |
done | |
} | |
function groupByCategory() { | |
# group all containers by the $_DI_RESULT_JSONKEY_CATEGORY | |
function _readAll() { | |
local inputs=() | |
while read input; do | |
inputs+=( $input ) | |
done | |
echo ${inputs[@]} | |
} | |
_readAll | jq -s ' | |
group_by(.'"$_DI_RESULT_JSONKEY_CATEGORY"') | |
| map({ | |
'"$_DI_RESULT_JSONKEY_CATEGORY"' : (.[0].'"$_DI_RESULT_JSONKEY_CATEGORY"'), | |
'"$_DI_RESULT_JSONKEY_CATEGORY_ICON"' : (.[0].'"$_DI_RESULT_JSONKEY_CATEGORY_ICON"'), | |
'"$_DI_RESULT_JSONKEY_CATEGORY_ORDER"' : (.[0].'"$_DI_RESULT_JSONKEY_CATEGORY_ORDER"'), | |
items: del( | |
.[].'"$_DI_RESULT_JSONKEY_CATEGORY"', | |
.[].'"$_DI_RESULT_JSONKEY_CATEGORY_ICON"', | |
.[].'"$_DI_RESULT_JSONKEY_CATEGORY_ORDER"' | |
) | |
})' | |
} | |
function mapToHomerConfigYAML() { | |
# use jq to generate the structure, in JSON, that homer expects | |
# and converted it to yaml | |
jq -r '{ | |
services: [ | |
. | |
| sort_by(.'"$_DI_RESULT_JSONKEY_CATEGORY_ORDER"', .'"$_DI_RESULT_JSONKEY_CATEGORY"') | |
| .[] | |
| { | |
name: (.'"$_DI_RESULT_JSONKEY_CATEGORY"'), | |
icon: (.'"$_DI_RESULT_JSONKEY_CATEGORY_ICON"' // "" | if . == "" then "" else "fas \(.)" end), | |
items: [ | |
.items | |
| sort_by(.'"$_DI_RESULT_JSONKEY_ORDER"', .'"$_DI_RESULT_JSONKEY_NAME"') | |
| .[] | |
| { | |
name: .'"$_DI_RESULT_JSONKEY_NAME"', | |
icon: (.'"$_DI_RESULT_JSONKEY_ICON"' // "" | if . == "" then "" else "fas \(.)" end), | |
subtitle: .'"$_DI_RESULT_JSONKEY_DESCRIPTION"', | |
url: .'"$_DI_RESULT_JSONKEY_URL"', | |
target: .'"$_DI_RESULT_JSONKEY_URL_TARGET"', | |
} | |
] | |
} | |
] | |
}' \ | |
| yq --prettyPrint e '.' - # convert to yaml | |
} | |
function writeToHomerConfig() { | |
local configFile="$1" | |
# delete the current services | |
yq -i e 'del(.services)' "$configFile" | |
# add the new services | |
yq e '.' - >> "$configFile" | |
} | |
# main | |
# some input checks | |
if ! command -v jq &> /dev/null; then | |
echo "ERROR:" | |
echo " 'jq' could not be found." | |
echo " see https://stedolan.github.io/jq/download/ for how to install it." | |
exit 1 | |
fi | |
if ! command -v yq &> /dev/null; then | |
echo "ERROR:" | |
echo " 'yq' could not be found." | |
echo " see https://mikefarah.gitbook.io/yq/#install for how to install it." | |
exit 1 | |
fi | |
HOMER_CONFIG_FILE="$1" | |
if [[ -z "$HOMER_CONFIG_FILE" ]]; then | |
echo "ERROR:" | |
echo " Pass the path to the homer config file" | |
echo "" | |
echo " Usage:" | |
echo " $0 path/to/homer/config.yml" | |
exit 1 | |
fi | |
if [[ ! -f "$HOMER_CONFIG_FILE" ]]; then | |
echo "ERROR:" | |
echo " File not found at '$HOMER_CONFIG_FILE'" | |
exit 1 | |
fi | |
# do the job | |
findDockerContainers \ | |
| readDockerContainersLables \ | |
| groupByCategory \ | |
| mapToHomerConfigYAML \ | |
| writeToHomerConfig $HOMER_CONFIG_FILE | |
echo "Done" | |
echo "Check $HOMER_CONFIG_FILE" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Still learning Bash, so for sure things can be improved.
Tested on Raspbian 10 (buster)
With that in mind, this is how I'm using it:
(i'm adding them via docker compose)
and
.config/appdata/homer/config.yml
should now contain