Feature complete tpcompose/ixcompose

This commit is contained in:
Lockszmith (@kateryna) 2025-02-25 01:04:52 -05:00
parent f420053442
commit fd6911b4d6
1 changed files with 157 additions and 18 deletions

View File

@ -36,7 +36,137 @@ append_file_param() {
echo "${*}"
}
sort-tipi() {
# 111 is followed an NBSP literal
# the 111 lines will be added only if `runtipi` is found
# sort --unique makes sure only one such line exists
# This in effect creates a methodical spacing between runtipi
# and the rest of the list
sed -Ee 's|^|555|; s|^555runtipi|111 \n000runtipi|;' \
| sort --unique \
| sed -Ee 's/^[[:digit:]]{3}//'
}
dls() {
local base='{{.Status}}\t{{.ID}}\t{{.Names}}\t{{.Image}}' #'\t{{.Networks}}\t{{.Ports}}\t{{.Mounts}}'
local compose='{{.Label "com.docker.compose.project"}}\t{{.Label "com.docker.compose.service"}}'
local format="table $compose\t$base"
docker container ls --all --format "$format" | (sed -u '1s/.*/\U&/; q'; sort-tipi)
}
get-docker-list() {
local POST_PROCESS=" | sed -Ee '#PP1 #PP2 #PP3' #PP_SORT"
local PP1='s/@.+//g;'
local PP2='s/ ix-/\nix-/g; s/(^|\n)ix-/\1/g;'
local PP3=''
local PP_SORT='| sort-tipi'
local SRC="" SRC_DOCKER="docker ps -a --format '{{.Label \"com.docker.compose.project\"}}@{{.Names}}' | sed -Ee 's/^@/<_no-compose-project_>:/;'"
local FILTER=""
local LIST=''
local MK_SEARCH_LIST="| xargs -r | sed 's/@//g; s/^/^(/; s/ *$/)@/; s/ /|/g;'"
local ARG=${1:---help}
while [ -n "$ARG" ]; do
case "$ARG" in
--debug)
set -x
;;
-G)
POST_PROCESS="${MK_SEARCH_LIST}"
PP_SORT=''
;;
-a)
SRC="${SRC_DOCKER}"
if [ -z "$LIST" ]; then
ARG="+X"
continue
fi
;;
-c)
PP1=''
if [ -z "$SRC" ]; then
ARG="-r"
continue
fi
;;
-r)
SRC="${SRC_DOCKER/ps -a /ps }"
if [ -z "$LIST" ]; then
ARG="+X"
continue
fi
;;
+X)
PP2=''
;;
ix|truenas)
LIST="find /mnt/.ix-apps/app_configs/* -maxdepth 0 -printf 'ix-%f@ '"
;;
tp|runtipi)
LIST="find apps/* -maxdepth 0 -printf '%f@ ' ; echo runtipi"
;;
other)
FILTER="grep -vE \""$(get-docker-list ix -G)"\" | grep -vE \""$(get-docker-list tp -G)"\""
if [ -z "$LIST" ] && [ -z "$SRC" ]; then
ARG="-c"
continue
fi
;;
*)
printf '%s %-12s %s\n' \
"Usage:" "" ""\
" ${BASE_NAME} ls <options>" "" ""\
"" "" "" \
"Available options:" "" ""\
"" "-G" "Create grep -E matching logic" \
"" "-a" "All containers (including inactive ones)" \
"" "-r" "Runing containers only" \
"" "+X" "for IX apps - preserve the ix- prefix" \
"" "" "" \
"" "ix|truenas" "IX (TrueNAS SCALE) apps" \
"" "tp|runtipi" "Runtipi apps" \
"" "other" "All other apps" \
&& return 1
;;
esac
shift
ARG="${1}"
done
if [ 0 -eq "${#LIST}" ]; then
LIST="${SRC}"
SRC=''
fi
if [ 0 -eq "${#LIST}" ]; then
printf "Source missing, must specify one of the following: -a | -r | ix | tp | other\n" >&2
return 1
fi
POST_PROCESS="${POST_PROCESS/\#PP1/${PP1}}"
POST_PROCESS="${POST_PROCESS/\#PP2/${PP2}}"
POST_PROCESS="${POST_PROCESS/\#PP3/${PP3}}"
POST_PROCESS="${POST_PROCESS/\#PP_SORT/${PP_SORT}}"
[ -n "$SRC" ] \
&& CLI="$SRC | grep -E \"\$(($LIST) $MK_SEARCH_LIST)\"" \
|| CLI="($LIST)"
CLI="$CLI ${FILTER:+| $FILTER} ${POST_PROCESS}"
printf '%s\n' $(eval "$CLI")
}
list-docker-apps() {
local LIST="$(get-docker-list "$@")"
local RUNNING="$(get-docker-list "$@" -r | sort-tipi)"
local LIMBO="$(get-docker-list "$@" -a | grep -xF "$LIST" | grep -vxF "$RUNNING" | sort-tipi)"
local DOWN="$(grep -Fxv -f <(printf '%s\n' "$RUNNING" "$LIMBO") <<<"$LIST" | sort-tipi)"
printf 'RUNNING\n' && printf ' %s\n' ${RUNNING:-"<nothing>"}
[ -n "$LIMBO" ] && printf '\nLIMBO \n' && printf ' %s\n' $LIMBO || true
[ -n "$DOWN" ] && printf '\nDOWN \n' && printf ' %s\n' $DOWN || true
}
runtipi-app-docker-compose() {
if [ $# -eq 0 ]; then
list-docker-apps tp
return 1
fi
local APP="${1:-Must supply app name}"
docker compose \
@ -52,7 +182,24 @@ runtipi-app-docker-compose() {
append_file_param --file "docker-compose.yml"
append_file_param --file "user-config/tipi-compose.yml"
fi) \
${@:2}
${2:-ps -a} ${3:+"${@:3}"}
}
ix-app-docker-compose() {
if [ $# -eq 0 ]; then
list-docker-apps ix
return 1
fi
local APP="${1:-Must supply app name}"
DCSRC="$(
find /mnt/.ix-apps/app_configs/ -type f \
-path "*/${APP}/*/rendered/docker-compose.yaml" -printf '%T@ %p\n' \
| sort -n | cut -d' ' -f2- | head -1
)"
set -x
docker compose "--file=${DCSRC}" "--project-name=ix-${APP}" ${2:-ps -a} ${3:+"${@:3}"}
}
link-exists() {
@ -131,13 +278,6 @@ manage-ipvlan() {
# ip link show [ DEVICE | group GROUP ] [up] [master DEV] [vrf NAME] [type TYPE] [nomaster]
}
dls() {
local base='{{.Status}}\t{{.ID}}\t{{.Names}}\t{{.Image}}' #'\t{{.Networks}}\t{{.Ports}}\t{{.Mounts}}'
local compose='{{.Label "com.docker.compose.project"}}\t{{.Label "com.docker.compose.service"}}'
local format="table $compose\t$base"
docker container ls --all --format "$format" | ( sed -u '1s/.*/\U&/; q'; sed -Ee 's|^|555|; s|^555runtipi|000runtipi|;' | sort | sed -Ee 's/^[[:digit:]]{3}//' )
}
case "${1}" in
cli)
runtipi-cli "${@:2}"
@ -159,16 +299,14 @@ case "${1}" in
dls)
dls "${@:2}"
;;
app)
ls)
get-docker-list "${@:2}"
;;
tpcompose)
runtipi-app-docker-compose "${@:2}"
;;
ixapp)
DCSRC="$(
find /mnt/.ix-apps/app_configs/ -type f \
-path "*/${2:?Must supply app name}/*/rendered/docker-compose.yaml" -printf '%T@ %p\n' \
| sort -n | cut -d' ' -f2- | head -1
)"
docker compose "--file=${DCSRC}" "--project-name=ix-${2}" "${@:3}"
ixcompose)
ix-app-docker-compose "${@:2}"
;;
shell)
runtipi-app-docker-compose "${2:?}" exec ${5:+"${@:5}"} -it "${4:-${2}}" "${3:-bash}"
@ -197,8 +335,9 @@ case "${1}" in
"" "update" "update runtipi to a specific version" \
"" "" "" \
"docker/docker-compose" "" ""\
"" "app" "docker compose for runtipi apps" \
"" "ixapp" "docker compose for ix/TrueNAS SCALE docker based app" \
"" "tpcompose" "docker compose for runtipi apps" \
"" "ixcompose" "docker compose for ix/TrueNAS SCALE docker based app" \
"" "ls" "list applications (or contrainers)" \
"" "dls" "stylized docker ls" \
"" "dockge" "docker compose for dockge stacks" \
"" "shell" "enter an insteractive shell" \