dk: implémenter status

This commit is contained in:
Jephté Clain 2020-03-26 16:40:37 +04:00
parent 4f206d732c
commit 1960c0c94e
7 changed files with 146 additions and 31 deletions

14
TODO.md
View File

@ -1,17 +1,3 @@
# TODO
## dk
Ajouter le support du déploiement de services dans un swarm
Les nouvelles actions suivantes sont disponibles:
* deploy -- déployer un service
* bpd -- équivalent à build, push, deploy
* update -- mettre à jour un service déployé
* bpu -- équivalent à build, push, update
* rollback -- annuler la mise à jour d'un service
Pour toutes ces actions, utiliser par défaut docker-stack.yml s'il existe,
sinon utiliser docker-compose.yml (en tenant compte des paramètres des profils)
-*- coding: utf-8 mode: markdown -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8:noeol:binary

118
dk
View File

@ -1,7 +1,7 @@
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/auto" || exit 1
urequire pff
urequire pff json
function display_help() {
uecho "$scriptname: outil pour faciliter l'utilisation de docker
@ -92,6 +92,19 @@ COMMANDES
$scriptname -- service logs web -f
Pour des cas d'utilisation plus complexe, il faut lancer directement
docker service
sta|status SERVICE [num]
Afficher le status du service spécifié: pour chaque occurence, sur quel
noeud il tourne (ou tournait), quel est le statut actuel ainsi que le
message associé.
'num' est le numéro de l'instance de service. Si ce numéro est précisé,
afficher les informations uniquement pour cette instance là, ainsi que
les logs
Il est possible de spécifier un filtre docker name=value avant 'num'. Ce
filtre est utilisé pour sélectionner certaines instances du service.
- id=<ID> a task's ID ou prefix
- name=<string> a task's name or prefix
- node=<string> a node's name or ID
- desired-state=(running|shutdown|accepted)
u|update SERVICE [args...]
Mettre à jour un service, équivalent à 'service update SERVICE'
scale SERVICE=REPLICAS [args...]
@ -105,7 +118,7 @@ COMMANDES
ps [filter|name=value]
Afficher les containers en cours d'exécution
Le filtre est une expression régulière de type awk qui est mise en
correspondace avec les noms de l'image et de la tâche.
correspondance avec les noms de l'image et de la tâche.
Il est aussi possible d'utiliser un filtre docker de la forme name=value
- ancestor=(<image-name>[:tag]|<image-id>| <image@digest>)
containers created from an image or a descendant.
@ -1198,6 +1211,99 @@ function auto_service() {
fi
}
function __format() {
# formatter une liste de valeur. chaque argument est de la forme [SIZE:]VALUE
# il ne faudrait utiliser la forme VALUE que pour le dernier argument
local size value
for value in "$@"; do
if [[ "$value" == *:* ]]; then
size="${value%%:*}"
value="${value#*:}"
else
size=
fi
if [ -n "$size" ]; then
while [ "${#value}" -lt "$size" ]; do
value="$value "
done
if [ "${#value}" -gt "$size" ]; then
[ "$size" -gt 1 ] && value="${value:0:$(($size - 1))}"
value="$value"$'\xe2\x80\xa6'
fi
fi
echo -n "${value} "
done
echo
}
function __status_query_task() {
setx taskData="$DOCKER" inspect "$taskID"
setx taskSlot=json_get 0.Slot <<<"$taskData"
setx taskStatus=json_get 0.Status.Err <<<"$taskData"
setx serviceID=json_get 0.ServiceID <<<"$taskData"
}
function __status_query_service() {
[ -n "$serviceData" ] && return
setx serviceID=json_get 0.ServiceID <<<"$taskData"
setx serviceData="$DOCKER" inspect "$serviceID"
setx serviceName=json_get 0.Spec.Name <<<"$serviceData"
setx serviceUpdateStatus=json_get 0.UpdateStatus.Message <<<"$serviceData"
}
function __status_process_data() {
__status_query_task
__status_query_service
if [ -n "$serviceUpdateStatus" ]; then
echo "\
================
$serviceName: $serviceUpdateStatus
================"
serviceUpdateStatus=
fi
if [ "$num" -eq 0 ]; then
# afficher les en-têtes
__format 3:num 32:taskName 20:node 8:dState 20:cState :error
fi
if [ -z "$fnum" -o "$num" == "$fnum" ]; then
taskName="$serviceName.$taskSlot"
__format 3:"$num" 32:"$taskName.$taskID" 20:"$node" 8:"$desiredState" 20:"$currentState" :"$taskStatus"
fi
if [ "$num" == "$fnum" ]; then
"$DOCKER" service logs -f "$taskID"
fi
let num=num+1
}
function auto_status() {
local service="$1"; shift
[ -n "$service" ] || {
eerror "Vous devez spécifier le nom du service"
return 1
}
if [ -f docker-compose.yml -o -f docker-stack.yml ]; then
# si on est dans répertoire de projet, il est possible de spécifier le
# service sans préfixe
local -a replace_env_args env_args
local -a replace_deploy_args deploy_args
local project_name container_name
docker_set_deploy_args set_container_name
service="${container_name}_${service#${container_name}_}"
fi
local -a pscmd
local fnum
pscmd=(
"$DOCKER" service ps "$service"
--format "taskID={{.ID}};node={{.Node}};desiredState='{{.DesiredState}}';currentState='{{.CurrentState}}';__status_process_data"
)
while [[ "$1" == *=* ]]; do
pscmd+=(--filter "$1")
shift
done
fnum="$1"; shift
local num=0 taskData taskStatus taskSlot serviceID serviceData serviceName serviceUpdateStatus
eval "$("${pscmd[@]}")"
}
function default_compose_show_ip() {
local -a cmd cids; local cid
cmd=(
@ -1783,6 +1889,14 @@ while [ $# -gt 0 ]; do
enote "Profil $PROFILE"
auto_service "${args[@]}" || die
;;
sta|status)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do
args+=("$1"); shift
done
enote "Profil $PROFILE"
auto_status "${args[@]}" || die
;;
u|update)
args=()
while [ $# -gt 0 -a "$1" != -- ]; do

View File

@ -29,3 +29,17 @@ function json_get(line) {
function awkjson() {
json_filter | awkrun -f "$JSONFUNCS" "$@"
}
function json_get() { php_json_get "$@"; }
function json_each() { php_json_each "$@"; }
function json_build() { php_json_build "$@"; }
function php_json_get() {
"$ULIBDIR/support/php/json_get.php" "$@"
}
function php_json_each() {
"$ULIBDIR/support/php/json_each.php" "$@"
}
function php_json_build() {
"$ULIBDIR/support/php/json_build.php" "$@"
}

View File

@ -11,7 +11,7 @@ foreach ($data as $datum) {
$keys = explode(".", trim($argv[$i]));
foreach ($keys as $key) {
if ($result === null) break;
if (!$key) continue;
if ($key === "") continue;
if (isset($result[$key])) {
$result = $result[$key];
} else {

View File

@ -3,15 +3,26 @@
if ($argc <= 1) die("ERROR: Vous devez spécifier le nom de la clé\n");
$argindex = 1;
$arg = $argv[1];
$sep = "\t";
if ($arg == "-s") {
$sep = $argv[2];
$argindex += 2;
} elseif (substr($arg, 0, 2) == "-s") {
$sep = substr($arg, 2);
$argindex++;
}
$datum = json_decode(stream_get_contents(STDIN), true);
$first = true;
for ($i = 1; $i < $argc; $i++) {
for ($i = $argindex; $i < $argc; $i++) {
$result = $datum;
$keys = explode(".", trim($argv[$i]));
foreach ($keys as $key) {
if ($result === null) break;
if (!$key) continue;
if ($key === "") continue;
if (isset($result[$key])) {
$result = $result[$key];
} else {
@ -20,7 +31,7 @@ for ($i = 1; $i < $argc; $i++) {
}
if ($first) $first = false;
else echo "\t";
else echo $sep;
if (is_array($result)) var_export($result);
else echo $result;
}

12
repoctl
View File

@ -1,7 +1,7 @@
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS
urequire DEFAULTS json
function display_help() {
uecho "$scriptname: piloter un serveur git (gitolite, gogs, gitea, etc.)
@ -39,16 +39,6 @@ ACTIONS
Supprimer le dépôt spécifié"
}
function json_build() {
"$scriptdir/lib/repoctl/json_build.php" "$@"
}
function json_get() {
"$scriptdir/lib/repoctl/json_get.php" "$@"
}
function json_each() {
"$scriptdir/lib/repoctl/json_each.php" "$@"
}
function repoctl_init() {
repourl="${1%.git}"
[ -n "$repourl" ] || return