summaryrefslogtreecommitdiffstats
path: root/libexec/container/list
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/container/list')
-rwxr-xr-xlibexec/container/list439
1 files changed, 439 insertions, 0 deletions
diff --git a/libexec/container/list b/libexec/container/list
new file mode 100755
index 0000000..ba794ab
--- /dev/null
+++ b/libexec/container/list
@@ -0,0 +1,439 @@
+#!/bin/sh
+
+# Copyright (C) 2014-2021 Daniel Baumann <daniel.baumann@open-infrastructure.net>
+#
+# SPDX-License-Identifier: GPL-3.0+
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set -e
+
+PROJECT="open-infrastructure"
+PROGRAM="container"
+COMMAND="$(basename ${0})"
+
+CONFIG="/etc/${PROJECT}/${PROGRAM}/config"
+HOOKS="/etc/${PROJECT}/${PROGRAM}/hooks"
+MACHINES="/var/lib/machines"
+
+VERSION="$(${PROGRAM} version)"
+
+Parameters ()
+{
+ GETOPT_LONGOPTIONS="all,csv-separator:,format:,host:,nwdiag-color:,nwdiag-label:,other,started,stopped,"
+ GETOPT_OPTIONS="a,f:,h:,o,s,t,"
+
+ PARAMETERS="$(getopt --longoptions ${GETOPT_LONGOPTIONS} --name=${COMMAND} --options ${GETOPT_OPTIONS} --shell sh -- ${@})"
+
+ if [ "${?}" != "0" ]
+ then
+ echo "'${COMMAND}': getopt exit" >&2
+ exit 1
+ fi
+
+ eval set -- "${PARAMETERS}"
+
+ while true
+ do
+ case "${1}" in
+ -a|--all)
+ LIST="${LIST} all"
+ shift 1
+ ;;
+
+ --csv-separator)
+ CSV_SEPARATOR="${2}"
+ shift 2
+ ;;
+
+ -f|--format)
+ FORMAT="${2}"
+ shift 2
+ ;;
+
+ -h|--host)
+ HOST="${2}"
+ shift 2
+ ;;
+
+ --nwdiag-color)
+ NWDIAG_COLOR="${2}"
+ shift 2
+ ;;
+
+ --nwdiag-label)
+ NWDIAG_LABEL="${2}"
+ shift 2
+ ;;
+
+ -o|--other)
+ LIST="${LIST} other"
+ shift 1
+ ;;
+
+ -s|--started)
+ LIST="${LIST} started"
+ shift 1
+ ;;
+
+ -t|--stopped)
+ LIST="${LIST} stopped"
+ shift 1
+ ;;
+
+ --)
+ shift 1
+ break
+ ;;
+
+ *)
+ echo "'${COMMAND}': getopt error" >&2
+ exit 1
+ ;;
+ esac
+ done
+}
+
+Usage ()
+{
+ echo "Usage: ${PROGRAM} ${COMMAND} [-a|--all] [--csv-separator SEPARATOR] [--format FORMAT] [-h|--host HOSTNAME] [--nwdiag-color COLOR] [--nwdiag-label LABEL] [-o|--other] [-s|--started] [-t|--stopped]" >&2
+ exit 1
+}
+
+Parameters "${@}"
+
+LIST="${LIST:-started stopped}"
+FORMAT="${FORMAT:-cli}"
+HOST="${HOST:-$(hostname -f 2> /dev/null || hostname)}"
+
+CSV_SEPARATOR="${CSV_SEPARATOR:-,}"
+
+# Pre hooks
+for FILE in "${HOOKS}/pre-${COMMAND}".* "${HOOKS}/${NAME}.pre-${COMMAND}"
+do
+ if [ -x "${FILE}" ]
+ then
+ "${FILE}"
+ fi
+done
+
+# Run
+List ()
+{
+ case "${FORMAT}" in
+ cli)
+ printf "%1s %-74s %-19s\n" "${STATUS}" "${BLUE}${CONTAINER}${NORMAL}" "${YELLOW}${ADDRESS}${NORMAL}"
+ ;;
+
+ csv)
+ echo "${HOST}${CSV_SEPARATOR}${CONTAINER}${CSV_SEPARATOR}${STATE}${CSV_SEPARATOR}${ADDRESS}"
+ ;;
+
+ json)
+
+cat << EOF
+ {
+ "name": "${CONTAINER}",
+ "status": "${STATE}",
+ "address": "${ADDRESS}",
+ },
+EOF
+
+ ;;
+
+ nwdiag)
+ Nwdiag_width "${CONTAINER}"
+
+ case "${STATE}" in
+ started)
+ COLOR="#73d216"
+ ;;
+
+ stopped)
+ COLOR="#cc0000"
+ ;;
+
+ other)
+ COLOR="#d3d7cf"
+ ;;
+ esac
+
+ echo " ${CONTAINER} [address = \"${ADDRESS}\", color = \"${COLOR}\", shape = \"flowchart.terminator\", width = \"${WIDTH}\"];"
+ ;;
+
+ shell|sh)
+ echo "${CONTAINER}"
+ ;;
+
+ yaml)
+
+cat << EOF
+ - name: ${CONTAINER}
+ address: ${ADDRESS}
+EOF
+
+ ;;
+
+ xml)
+
+cat << EOF
+ <container>
+ <name>${CONTAINER}</name>
+ <address>${ADDRESS}</address>
+ </container>
+EOF
+
+ ;;
+ esac
+}
+
+Nwdiag_width ()
+{
+ NAME="${1}"
+
+ CHARACTERS="$(echo "${NAME}" | wc -c)"
+
+ if [ "${CHARACTERS}" -gt 13 ]
+ then
+ # default width is 128 fitting 13 characters
+ WIDTH="$(( ${CHARACTERS} - 13 ))"
+ WIDTH="$(( ${WIDTH} * 5 ))"
+ WIDTH="$(( ${WIDTH} + 128 ))"
+ else
+ WIDTH="128"
+ fi
+}
+
+case "${FORMAT}" in
+ cli)
+ RED="$(tput setaf 1)$(tput bold)"
+ GREEN="$(tput setaf 2)$(tput bold)"
+ YELLOW="$(tput setaf 3)$(tput bold)"
+ BLUE="$(tput setaf 4)$(tput bold)"
+ WHITE="$(tput setaf 7)$(tput bold)"
+ NORMAL="$(tput sgr0)"
+
+cat << EOF
+${WHITE} ${NORMAL} Container IP Address
+--------------------------------------------------------------------------------
+EOF
+
+ ;;
+
+ csv)
+
+cat << EOF
+# compute-tools ${VERSION}
+Host${CSV_SEPARATOR}Container${CSV_SEPARATOR}Status${CSV_SEPARATOR}IPv4-Address
+EOF
+
+ ;;
+
+ json)
+
+cat << EOF
+{
+ "compute-tools": {
+ "version": "${VERSION}",
+ },
+ "host": {
+ "name": "${HOST}",
+ },
+ "container": [
+EOF
+
+ ;;
+
+ nwdiag)
+ NETWORK="$(echo ${HOST} | sed -e 's|\.|_|g')"
+
+cat << EOF
+# compute-tools ${VERSION}
+nwdiag {
+ external_connector = none;
+ network ${NETWORK} {
+EOF
+
+ if [ -n "${NWDIAG_LABEL}" ]
+ then
+ echo " label = \"${NWDIAG_LABEL}\""
+ else
+ echo " label = \"\""
+ fi
+
+ NUMBER="$(${0} --format=short | wc -l)"
+
+ if [ -n "${NWDIAG_COLOR}" ]
+ then
+ COLOR="${NWDIAG_COLOR}"
+ else
+ COLOR="#3465a4"
+ fi
+
+ Nwdiag_width "${HOST}"
+
+cat << EOF
+ # host
+ ${HOST} [color = "${COLOR}", shape = "box", numbered = "${NUMBER}", width = "${WIDTH}"];
+ # container
+EOF
+
+ ;;
+
+ yaml)
+
+cat << EOF
+---
+compute_tools:
+ version: ${VERSION}
+
+host:
+ name: ${HOST}
+
+container:
+EOF
+
+ ;;
+
+ xml)
+
+cat << EOF
+<compute-tools>
+ <version>${VERSION}</version>
+</compute-tools>
+<host>
+ <name>${HOST}</name>
+</host>
+<containers>
+EOF
+
+ ;;
+esac
+
+if ls "${MACHINES}"/* > /dev/null 2>&1
+then
+ CONTAINERS="$(cd "${MACHINES}" 2>/dev/null && find -maxdepth 1 \( -type d -or -type l \) -and -not -name 'lost+found' -printf '%P\n' | sort)"
+fi
+
+for CONTAINER in ${CONTAINERS}
+do
+ STATE="$(machinectl show ${CONTAINER} 2>&1 | awk -FState= '/^State=/ { print $2 }')"
+
+ if [ -e "${CONFIG}/${CONTAINER}.conf" ]
+ then
+ CONTAINER_SERVER="$(awk -Fcnt.container-server= '/^cnt.container-server=/ { print $2 }' ${CONFIG}/${CONTAINER}.conf)"
+ CONTAINER_SERVER="${CONTAINER_SERVER:-false}"
+
+ case "${CONTAINER_SERVER}" in
+ ${HOST}|true)
+ ;;
+
+ *)
+ STATE="other"
+ ;;
+ esac
+ else
+ STATE="other"
+ fi
+
+ case "${STATE}" in
+ running)
+ STATE="started"
+ STATUS="${GREEN}●${NORMAL}"
+ ;;
+
+ other)
+ STATUS="${WHITE}○${NORMAL}"
+ ;;
+
+ *)
+ STATE="stopped"
+ STATUS="${RED}●${NORMAL}"
+ ;;
+ esac
+
+ ADDRESS=""
+
+ if ls "${MACHINES}/${CONTAINER}/etc/systemd/network"/*.network > /dev/null 2>&1
+ then
+ ADDRESS="$(awk -FAddress= '/^Address/ { print $2 }' ${MACHINES}/${CONTAINER}/etc/systemd/network/*.network | head -n1)"
+ elif [ -e "${MACHINES}/${CONTAINER}/etc/network/interfaces" ]
+ then
+ ADDRESS="$(awk '/address/ { print $2 }' ${MACHINES}/${CONTAINER}/etc/network/interfaces | head -n1)"
+ fi
+
+ ADDRESS="${ADDRESS:-n/a}"
+
+ if echo ${LIST} | grep -qs all
+ then
+ List
+ fi
+
+ for ITEM in other started stopped
+ do
+ if echo ${LIST} | grep -qs ${ITEM}
+ then
+ case "${STATE}" in
+ ${ITEM})
+ List
+ ;;
+ esac
+ fi
+ done
+done
+
+case "${FORMAT}" in
+ cli)
+
+cat << EOF
+--------------------------------------------------------------------------------
+EOF
+
+ ;;
+
+ json)
+
+cat << EOF
+ ],
+}
+EOF
+
+ ;;
+
+ nwdiag)
+
+cat << EOF
+ }
+}
+EOF
+
+ ;;
+
+ xml)
+
+cat << EOF
+</containers>
+EOF
+
+ ;;
+esac
+
+# Post hooks
+for FILE in "${HOOKS}/post-${COMMAND}".* "${HOOKS}/${NAME}.post-${COMMAND}"
+do
+ if [ -x "${FILE}" ]
+ then
+ "${FILE}"
+ fi
+done