diff --git a/dk b/dk index a8b41bd..051af86 100755 --- a/dk +++ b/dk @@ -55,7 +55,10 @@ COMMANDES container après utilisation. x|exec SERVICE COMMAND Lancer une commande dans le container correspondant au service spécifié, - qui doit être en fonctionnement + qui doit être en fonctionnement. Si la commande n'est pas spécifiée, la + valeur par défaut est bash. Avec les options --select-service et + --select-machine, l'argument SERVICE vaut par défaut 'SS' + Un pseudo-tty est alloué pour la commande et STDIN est ouvert. d|brd [NAME=VALUE...] Construire les images (comme avec build), démarrer les services et suivre les logs de façon interactive (comme avec up). Dès que l'on @@ -119,6 +122,12 @@ COMMANDES systemd|systemd-unit Générer une unité systemd qui démarre les services. A priori, ce n'est nécessaire que si aucune politique de redémarrage n'a été définie. + cp|copy CONTAINER:SRC DEST + cp|copy SRC CONTAINER:DEST + Copier un fichier ou un répertoire depuis/vers un container. Avec les + options --select-service et --select-machine, il est possible d'utiliser + 'SS' pour signifier le container sélectionné e.g + $scriptname -s X_Y -- cp file SS:path/to/dir 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 @@ -239,6 +248,21 @@ OPTIONS générales -m, --set-machine MACHINE Choisir l'environnement docker-machine spécifié avant de lancer les commandes. Utiliser -u pour desélectionner la machine en cours, e.g -m-u + -s, --select-service SERVICE[.N] + Sélectionner le service spécifié. Si le service a plusieurs instances, + il est possible de sélectionner une instance en particulier avec le + suffixe '.N' (par défaut, la première instance est sélectionnée) + Quand un service est sélectionné, dans les commandes 'cp' et 'exec', la + chaine 'SS' est remplacée par le nom du container correspondant e.g + $scriptname -s X_Y exec SS bash + $scriptname -s X_Y -- cp -L SS:path/to/file destdir + -t, --select-machine SERVICE[.N] + Sélectionner le service spécifié, puis choisir l'environnement + docker-machine correspondant. Cette option a la priorité sur l'option + --select-service + Cette option est traitée après l'option --set-machine, ce qui permet de + se connecter sur le manager d'un cluster puis de sélectionner le worker + sur lequel tourne un service -n, --fake Ne pas lancer les commandes, simplement les afficher -e, --build-arg, --env VAR=VALUE @@ -1265,13 +1289,28 @@ function auto_exec() { local project_name container_name if [ -f docker-compose.yml ]; then compose_set_env_args - compose_exec "$@" + local container="$1"; shift + if [ -n "$SELECT_CONTAINER" ]; then + [ -z "$container" -o "$container" == SS ] && container="$SELECT_CONTAINER" + fi + local command="$1"; shift + [ -n "$command" ] || command=bash + compose_exec "$container" "$command" "$@" elif [ -f Dockerfile ]; then docker_set_env_args docker_check_name set_container_name - docker_exec "$@" + exec_args=(-it) + local command="$1"; shift + [ -n "$command" ] || command=bash + docker_exec "$command" "$@" else - ${FAKE:+qvals} "$DOCKER" exec "$@" + local container="$1"; shift + if [ -n "$SELECT_CONTAINER" ]; then + [ -z "$container" -o "$container" == SS ] && container="$SELECT_CONTAINER" + fi + local command="$1"; shift + [ -n "$command" ] || command=bash + ${FAKE:+qvals} "$DOCKER" exec -it "$container" "$command" "$@" fi } @@ -1358,6 +1397,7 @@ function __format() { function __status_query_task() { setx taskData="$DOCKER" inspect "$taskID" + setx taskID=json_get 0.ID <<<"$taskData" setx taskSlot=json_get 0.Slot <<<"$taskData" setx taskStatus=json_get 0.Status.Err <<<"$taskData" setx serviceID=json_get 0.ServiceID <<<"$taskData" @@ -1381,11 +1421,11 @@ $serviceName: $serviceUpdateStatus fi if [ "$num" -eq 0 ]; then # afficher les en-têtes - __format 3:num 32:taskName 32:node 8:dState 20:cState :error + __format 3:num 48:taskName 32:node 8:dState 20:cState :error fi if [ -z "$fnum" -o "$num" == "$fnum" ]; then taskName="$serviceName.$taskSlot" - __format 3:"$num" 32:"$taskName.$taskID" 32:"$node" 8:"$desiredState" 20:"$currentState" :"$taskStatus" + __format 3:"$num" 48:"$taskName.$taskID" 32:"$node" 8:"$desiredState" 20:"$currentState" :"$taskStatus" fi if [ "$num" == "$fnum" ]; then "$DOCKER" service logs -f "$taskID" @@ -1573,6 +1613,25 @@ EOF local_run "$HOST" "$tmpscript" } +function auto_copy() { + local src="$1"; shift + local dest="$1"; shift + if [ -n "$SELECT_CONTAINER" ]; then + if [ "${src#SS:}" != "$src" ]; then + src="$SELECT_CONTAINER${src#SS}" + elif [ "${src#:}" != "$src" ]; then + src="$SELECT_CONTAINER$src" + fi + if [ "${dest#SS:}" != "$dest" ]; then + dest="$SELECT_CONTAINER${dest#SS}" + elif [ "${dest#:}" != "$dest" ]; then + dest="$SELECT_CONTAINER$dest" + fi + fi + + "$DOCKER" cp "$src" "$dest" "$@" +} + function default_local_composer() { # lancement direct case "$1" in @@ -1785,6 +1844,8 @@ export PROFILE chdir= CONFIG= DM_SET_MACHINE= +SELECT_CONTAINER= +SELECT_MACHINE= USE_STACK= FAKE= VARS=() @@ -1804,6 +1865,8 @@ args=( -P,--prod PROFILE=prod -T,--test PROFILE=test -m:,--set-machine: DM_SET_MACHINE= + -s:,--select-service: SELECT_CONTAINER= + -t:,--select-machine: SELECT_MACHINE= --stack USE_STACK=1 -n,--fake FAKE=1 -e:,--build-arg:,--env: VARS @@ -1828,6 +1891,66 @@ if [ -n "$DM_SET_MACHINE" ]; then # pour warning ci-dessous [ "$DM_SET_MACHINE" == -u ] && DM_SET_MACHINE= fi + +if [ -n "$SELECT_MACHINE" -o -n "$SELECT_CONTAINER" ]; then + function __ss_process_data() { + [ -n "$found" ] && return + __status_query_task + __status_query_service + if [ -n "$slot" ]; then + if [ "$taskSlot" == "$slot" ]; then + # ne prendre que le slot qui correspond + found=1 + fi + else + # prendre le premier + found=1 + fi + taskName="$serviceName.$taskSlot" + } + + if [ -n "$SELECT_MACHINE" ]; then service="$SELECT_MACHINE" + elif [ -n "$SELECT_CONTAINER" ]; then service="$SELECT_CONTAINER" + fi + 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 + docker_set_deploy_args set_container_name + service="${container_name}_${service#${container_name}_}" + fi + if [[ "$service" == *.* ]]; then + slot="${service##*.}" + service="${service%.*}" + else + slot= + fi + + psargs=( + --filter desired-state=running + --format "taskID={{.ID}};node={{.Node}};__ss_process_data" + ) + found= + eval "$("$DOCKER" service ps "$service" "${psargs[@]}" 2>/dev/null)" + + if [ -n "$found" ]; then + SELECT_CONTAINER="$serviceName.$taskSlot.$taskID" + if [ -n "$SELECT_MACHINE" ]; then + DM_SET_MACHINE="$node" + else + enote "Sélection du container $SELECT_CONTAINER" + fi + else + die "$service${slot:+.$slot}: service introuvable" + fi +fi +if [ -n "$SELECT_MACHINE" ]; then + enote "Sélection de la machine $DM_SET_MACHINE" + + [ -n "$DM_AVAILABLE" ] || die "docker-machine n'est pas disponible" + setx dm_env=docker-machine env "$DM_SET_MACHINE" || die + eval "$dm_env" +fi + if [ -n "$DM_AVAILABLE" ]; then found= for dm_profile in "${DM_PROFILES[@]}"; do @@ -2083,6 +2206,14 @@ while [ $# -gt 0 ]; do enote "Profil $PROFILE" auto_systemd_unit "${args[@]}" || die ;; + cp|copy) + args=() + while [ $# -gt 0 -a "$1" != -- ]; do + args+=("$1"); shift + done + enote "Profil $PROFILE" + auto_copy "${args[@]}" || die + ;; ps) pscmd=( "$DOCKER" container ps -a