From e431f4e7c2c0a7913385cf6cb07455cf93901faf Mon Sep 17 00:00:00 2001
From: Freezed <2160318-free_zed@users.noreply.gitlab.com>
Date: Fri, 14 Jan 2022 03:12:01 +0100
Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20users=20configuration?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Add config files for my_user
- Add dotfiles for root
- Add GPS prune config (my_user)
- Add idempotence to font config
---
 Makefile                                |   8 +-
 README.md                               |  11 +-
 tasks/become_user_cfg.yml               |   1 -
 tasks/user_cfg/files/dotfiles/gitconfig |  43 ++++
 tasks/user_cfg/files/dotfiles/vimrc     | 101 ++++++++++
 tasks/user_cfg/files/dotfiles/zlogin    |  27 +++
 tasks/user_cfg/files/dotfiles/zlogout   |  11 ++
 tasks/user_cfg/files/dotfiles/zshenv    |  15 ++
 tasks/user_cfg/files/dotfiles/zshrc     | 251 ++++++++++++++++++++++++
 tasks/{ => user_cfg}/files/sshd_config  |   0
 tasks/user_cfg/main.yml                 |  13 ++
 tasks/user_cfg/my_user.yml              |  65 ++++++
 tasks/user_cfg/root.yml                 |  49 +++++
 tasks/user_cfg/templates/pruneconfig.j2 |  35 ++++
 tasks/user_cfg/vars/git.yml             |  33 ++++
 tasks/vars/main.yml                     |   1 +
 16 files changed, 656 insertions(+), 8 deletions(-)
 create mode 100644 tasks/user_cfg/files/dotfiles/gitconfig
 create mode 100644 tasks/user_cfg/files/dotfiles/vimrc
 create mode 100644 tasks/user_cfg/files/dotfiles/zlogin
 create mode 100644 tasks/user_cfg/files/dotfiles/zlogout
 create mode 100644 tasks/user_cfg/files/dotfiles/zshenv
 create mode 100644 tasks/user_cfg/files/dotfiles/zshrc
 rename tasks/{ => user_cfg}/files/sshd_config (100%)
 create mode 100644 tasks/user_cfg/main.yml
 create mode 100644 tasks/user_cfg/my_user.yml
 create mode 100644 tasks/user_cfg/root.yml
 create mode 100644 tasks/user_cfg/templates/pruneconfig.j2
 create mode 100644 tasks/user_cfg/vars/git.yml

diff --git a/Makefile b/Makefile
index 3befe11..0f391ae 100644
--- a/Makefile
+++ b/Makefile
@@ -7,9 +7,13 @@ clean:
 
 open_all:
 	${EDITOR} .gitignore inventory Makefile README.md
-	${EDITOR} tasks/files/*
-	${EDITOR} tasks/vars/*
 	${EDITOR} tasks/*.yml
+	${EDITOR} tasks/user_cfg/*.yml
+	${EDITOR} tasks/user_cfg/files/sshd_config
+	${EDITOR} tasks/user_cfg/files/dotfiles/*
+	${EDITOR} tasks/user_cfg/templates/*.j2
+	${EDITOR} tasks/user_cfg/vars/*.yml
+	${EDITOR} tasks/vars/*.yml
 
 inventory_generation:
 	cp inventory.sample inventory && ${EDITOR} inventory
diff --git a/README.md b/README.md
index 60c11bc..1c76121 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
-forga Ansible base playbook
-===========================
+forga Ansible base tasks
+========================
 
 
 💡 Idea
 -------
 
-Get info and set basic config for _Debian_ and _Ubuntu_ distrib.
+Get info and set basic config for _Debian_ and _Ubuntu_ distrib, using [_Gnome_](https://www.gnome.org/), [_Mate_](https://mate-desktop.org/) or no desktop environment.
 
 Suitable for server and workstation.
 
@@ -13,11 +13,12 @@ Suitable for server and workstation.
 ✨ Features
 -----------
 
-|   playbook                                            |   purpose                                                             |
+|   task                                                |   purpose                                                             |
 |   :--------------------------------------:            |   :--------------------------------------------------------------:    |
 | [`become_user_cfg.yml`](tasks/become_user_cfg.yml)    |   Set `sudo` without password for `become_user` access                |
 | [`host_info.yml`](tasks/host_info.yml)                |   Return message with distribution full name & version                |
 | [`shutdown.yml`](tasks/shutdown.yml)                  |   Shutdown target in 10 min                                           |
+| [`user_cfg`](tasks/user_cfg/main.yml)                 |   Configure `{{ my_user }}` & `root` users                            |
 | [`whoami.yml`](tasks/whoami.yml)                      |   Return message with `ansible_user` & `become_user` (`sudo` method)  |
 
 
@@ -27,4 +28,4 @@ Suitable for server and workstation.
 1. Setup your `inventory` file from [`inventory.sample`](inventory.sample) :
     - `make inventory_generation`
 1. Run `host_info` playbook to `<group_foo>` & `<group_bar>` :
-    - `ansible-playbook host_info.yml -i inventory -e host_list=<group_foo>:<group_bar>`
+    - `ansible-playbook tasks/host_info.yml -i inventory -e host_list=<group_foo>:<group_bar>`
diff --git a/tasks/become_user_cfg.yml b/tasks/become_user_cfg.yml
index 53801a2..3adc3c6 100644
--- a/tasks/become_user_cfg.yml
+++ b/tasks/become_user_cfg.yml
@@ -31,7 +31,6 @@
     - name: "SSH | Local public key is present for {{ my_user }}"
       become: yes
       ansible.builtin.authorized_key:
-        comment: "Managed by Ansible from GitLab @free_zed"
         key: https://gitlab.com/free_zed.keys
         state: present
         user: "{{ my_user }}"
diff --git a/tasks/user_cfg/files/dotfiles/gitconfig b/tasks/user_cfg/files/dotfiles/gitconfig
new file mode 100644
index 0000000..19bfcf6
--- /dev/null
+++ b/tasks/user_cfg/files/dotfiles/gitconfig
@@ -0,0 +1,43 @@
+# ############################################# #
+#                 ~/.gitconfig                  #
+#                                               #
+#       This file is managed by Ansible         #
+#       Manual edition will be overridden       #
+#                                               #
+#   https://lab.frogg.it/fcode/ansible/debian   #
+#                                               #
+# ############################################# #
+
+[color]
+	diff = auto
+	status = auto
+	branch = auto
+
+[alias]
+	ap = add --patch
+	ba = branch -av
+	cia = commit --amend --no-edit
+	ci = commit
+	co = checkout
+	diff = diff --ignore-all-space
+	lga = log --graph --oneline --decorate --since=10days --all
+	lgla = log --graph --oneline --decorate --date=short --all
+	lg = log --graph --oneline --decorate --since=10days
+	st = status
+
+[mergetool]
+	keepBackup = no
+	keepTemporaries = no
+	prompt = no
+
+[merge]
+	tool = meld
+
+[url "ssh://git@github.com/"]
+	pushInsteadOf = https://github.com/
+
+[url "ssh://git@gitlab.com/"]
+	pushInsteadOf = https://gitlab.com/
+
+[url "ssh://git@lab.frogg.it/"]
+	pushInsteadOf = https://lab.frogg.it/
diff --git a/tasks/user_cfg/files/dotfiles/vimrc b/tasks/user_cfg/files/dotfiles/vimrc
new file mode 100644
index 0000000..a65bfe1
--- /dev/null
+++ b/tasks/user_cfg/files/dotfiles/vimrc
@@ -0,0 +1,101 @@
+" """"""""""""""""""""""""""""""""""""""""""""" "
+"                   ~/.vimrc                    "
+"                                               "
+"       This file is managed by Ansible         "
+"       Manual edition will be overridden       "
+"                                               "
+"   https://lab.frogg.it/fcode/ansible/debian   "
+"   http://formation-debian.via.ecp.fr/         "
+"                                               "
+" """"""""""""""""""""""""""""""""""""""""""""" "
+
+" ':help options.txt' ou ':help nom_du_paramètre' dans Vim
+" pour avoir de l'aide sur les paramètres de ce fichier de configuration
+
+" Avertissement par flash (visual bell) plutôt que par beep
+set vb
+
+" Active la coloration syntaxique
+syntax on
+" Définit le jeu de couleurs utilisé
+" Les jeux de couleur disponibles sont les fichiers avec l'extension .vim
+" dans le répertoire /usr/share/vim/vimcurrent/colors/
+colorscheme delek
+
+" Affiche la position du curseur 'ligne,colonne'
+set ruler
+" Affiche une barre de status en bas de l'écran
+set laststatus=2
+" Contenu de la barre de status
+set statusline=%<%f%h%m%r%=%l,%c\ %P
+
+" Largeur maxi du texte inséré
+" '72' permet de wrapper automatiquement à 72 caractères
+" '0' désactive la fonction
+set textwidth=0
+
+" Wrappe à 72 caractères avec la touche '#'
+map # gwap
+" Wrappe et justifie à 72 caractères avec la touche '@'
+map @ {v}! par 72j
+
+" Ne pas assurer la compatibilité avec l'ancien Vi
+set nocompatible
+" Nombre de colonnes (inutile, voire gênant)
+"set columns=80
+" Nombre de commandes dans l'historique
+set history=50
+" Options du fichier ~/.viminfo
+set viminfo='20,\"50
+" Active la touche Backspace
+set backspace=2
+" Autorise le passage d'une ligne à l'autre avec les flèches gauche et droite
+set whichwrap=<,>,[,]
+" Garde toujours une ligne visible à l'écran au dessus du curseur
+set scrolloff=1
+" Affiche les commandes dans la barre de status
+set showcmd
+" Affiche la paire de parenthèses
+set showmatch
+" Essaye de garder le curseur dans la même colonne quand on change de ligne
+set nostartofline
+" Option de la complétion automatique
+set wildmode=list:full
+" Par défaut, ne garde pas l'indentation de la ligne précédente
+" quand on commence une nouvelle ligne
+set noautoindent
+" Options d'indentation pour un fichier C
+set cinoptions=(0
+
+" xterm-debian est un terminal couleur
+if &term =~ "xterm-debian" || &term =~ "xterm-xfree86"
+    set t_Co=16
+    set t_Sf=[3%dm
+    set t_Sb=[4%dm
+endif
+
+" Quand on fait de la programmation, on veut qu'il n'y ait jamais de
+" vraies tabulations insérées mais seulement des espaces
+set expandtab
+
+" Décommentez les 2 lignes suivantes si vous voulez avoir les tabulations et
+" les espaces marqués en caractères bleus
+"set list
+"set listchars=tab:>-,trail:-
+
+" Les recherches ne sont pas 'case sensitives'
+set ignorecase
+
+" Le découpage des folders se base sur l'indentation
+set foldmethod=indent
+" 12 niveaux d'indentation par défaut pour les folders
+set foldlevel=12
+
+" Recherches incrémentalees : rechercher au fur et à mesure qu'on
+" tape le motif de recherche
+set incsearch
+" Mettre en surbrillance le mot cherché
+"set hlsearch
+
+" Décommentez la ligne suivante si vous voulez afficher les numéros de ligne
+"set number
diff --git a/tasks/user_cfg/files/dotfiles/zlogin b/tasks/user_cfg/files/dotfiles/zlogin
new file mode 100644
index 0000000..6cc6ffa
--- /dev/null
+++ b/tasks/user_cfg/files/dotfiles/zlogin
@@ -0,0 +1,27 @@
+# ############################################# #
+#                 ~/.zlogin                     #
+#                                               #
+#       This file is managed by Ansible         #
+#       Manual edition will be overridden       #
+#                                               #
+#   https://lab.frogg.it/fcode/ansible/debian   #
+#                                               #
+# ############################################# #
+
+USAGE_FILE=/var/.usage
+
+lsb_release -d | sed 's/Description:/-=VERSION=-\t/g'
+
+echo -e "-=UPTIME=-\t   $(uptime)\n"
+
+echo -e "-=WHOisHERE=-\n $(w)\n"
+
+echo -e "\n-=IPs=-\n    $(ip -br address|grep UP)\n"
+
+echo -e "-=SCREEN=-\n   $(screen -list)"
+
+echo -e "-=DISKSPACE=-"
+[[ -n $(zpool list) ]] &> /dev/null && zpool list || df -h -t ext4 --output=source,used,avail,target
+
+echo -e "\n-=USAGE=-"
+[[ -e $USAGE_FILE ]] && cat ${USAGE_FILE} || echo "Usage unknown"
diff --git a/tasks/user_cfg/files/dotfiles/zlogout b/tasks/user_cfg/files/dotfiles/zlogout
new file mode 100644
index 0000000..b2b9439
--- /dev/null
+++ b/tasks/user_cfg/files/dotfiles/zlogout
@@ -0,0 +1,11 @@
+# ############################################# #
+#                 ~/.zlogout                    #
+#                                               #
+#       This file is managed by Ansible         #
+#       Manual edition will be overridden       #
+#                                               #
+#   https://lab.frogg.it/fcode/ansible/debian   #
+#                                               #
+# ############################################# #
+
+echo "Exiting ${HOSTNAME}…"
diff --git a/tasks/user_cfg/files/dotfiles/zshenv b/tasks/user_cfg/files/dotfiles/zshenv
new file mode 100644
index 0000000..2bc3fe0
--- /dev/null
+++ b/tasks/user_cfg/files/dotfiles/zshenv
@@ -0,0 +1,15 @@
+# ############################################# #
+#                 ~/.zshenv                     #
+#                                               #
+#       This file is managed by Ansible         #
+#       Manual edition will be overridden       #
+#                                               #
+#   https://lab.frogg.it/fcode/ansible/debian   #
+#                                               #
+# ############################################# #
+
+export PATH="/usr/local/bin:/usr/local/sbin:/bin:/usr/bin:/usr/sbin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/sbin:$HOME/bin:$HOME/.local/bin"
+export VISUAL=vim
+export EDITOR=vim
+
+umask 022
diff --git a/tasks/user_cfg/files/dotfiles/zshrc b/tasks/user_cfg/files/dotfiles/zshrc
new file mode 100644
index 0000000..053f417
--- /dev/null
+++ b/tasks/user_cfg/files/dotfiles/zshrc
@@ -0,0 +1,251 @@
+# ############################################# #
+#                 ~/.zshrc                      #
+#                                               #
+#       This file is managed by Ansible         #
+#       Manual edition will be overridden       #
+#                                               #
+#   https://lab.frogg.it/fcode/ansible/debian   #
+#    from http://formation-debian.via.ecp.fr    #
+#                                               #
+# ############################################# #
+
+
+# ############ #
+# 1. Les alias #
+# ############ #
+
+# Gestion du 'ls' couleur
+alias ls='ls --color'
+alias ll='ls -hal'
+
+# Demande confirmation avant d'écraser un fichier
+alias cp='cp --interactive'
+alias mv='mv --interactive'
+alias rm='rm --interactive'
+
+# Quelques alias pratiques
+alias c='clear'
+alias less='less --quiet'
+alias df='df --human-readable'
+alias du='du --human-readable'
+alias md='mkdir --parent'
+
+# Mes alias
+function gh() { grep --color "$1" ~/.history }
+alias ada='sudo apt update && sudo apt list --upgradable && sudo apt clean'
+alias agr='sudo apt upgrade && sudo apt autoclean && sudo apt autoremove'
+alias apti='sudo apt install'
+alias p1='ping -c 1 '
+alias gpu='for proj in $(find ~/git -mindepth 1 -maxdepth 1 -type d -printf "%p\n");do echo "## ${proj}";cd ${proj};git fetch --prune;done;cd ~'
+alias p1='ping -c 1 '
+alias sudo='sudo '
+alias ttoday='cat ~/.timed|grep "$(date +%d) Oct 2021" | timed parse'
+alias vact='source ~/.venvs/$(pwd | cut -d"/" -f5)/bin/activate'
+alias vc10='~/pylocal/bin/python3.10 -m venv --clear --copies ~/.venvs/$(pwd | cut -d "/" -f5)'
+alias vc7='~/pylocal/bin/python3.7 -m venv --clear --copies ~/.venvs/$(pwd | cut -d "/" -f5)'
+alias vc8='~/pylocal/bin/python3.8 -m venv --clear --copies ~/.venvs/$(pwd | cut -d "/" -f5)'
+alias vc9='~/pylocal/bin/python3.9 -m venv --clear --copies ~/.venvs/$(pwd | cut -d "/" -f5)'
+alias vc='python3 -m venv --clear --copies ~/.venvs/$(pwd | cut -d "/" -f5)'
+
+# Timed
+alias tart='timed start _job_;vi ~/.timed +'
+alias tsto='timed stop;ttod'
+alias ttod='cat ~/.timed | grep "$(date +%d) Jan 2022" | timed parse'
+
+
+# ######################### #
+# 2. Définition des touches #
+# ######################### #
+
+# Correspondance touches-fonction
+#bindkey ''    delete-char
+#bindkey '[3~' delete-char
+#bindkey '[2~' overwrite-mode
+
+# Beginning/end of line
+bindkey ""      beginning-of-line
+bindkey "\e[1~"   beginning-of-line
+bindkey "\e[H"    beginning-of-line
+bindkey ""      end-of-line
+bindkey "\e[4~"   end-of-line
+bindkey "\e[F"  end-of-line
+
+# History search
+bindkey '^R'      history-incremental-search-backward
+bindkey '^F'      history-incremental-search-forward
+
+# ctrl+<- | ctrl+->
+bindkey "^[[1;5D" backward-word
+bindkey "^[[1;5C" forward-word
+
+
+# Prompt couleur (la couleur n'est pas la même pour le root et
+# pour les simples utilisateurs)
+if [ "`id -u`" -eq 0 ]; then
+  export PS1="%{%}%T %{%}%n%{%}@%{%}%m %{%}%~ %{%}%#%{%} "
+else
+  export PS1="%{%}%T %{%}%n%{%}@%{%}%m %{%}%~ %{%}%#%{%} "
+fi
+
+# Prise en charge des touches [début], [fin] et autres
+typeset -A key
+
+key[Home]=${terminfo[khome]}
+key[End]=${terminfo[kend]}
+key[Insert]=${terminfo[kich1]}
+key[Delete]=${terminfo[kdch1]}
+key[Up]=${terminfo[kcuu1]}
+key[Down]=${terminfo[kcud1]}
+key[Left]=${terminfo[kcub1]}
+key[Right]=${terminfo[kcuf1]}
+key[PageUp]=${terminfo[kpp]}
+key[PageDown]=${terminfo[knp]}
+
+[[ -n "${key[Home]}"    ]]  && bindkey  "${key[Home]}"    beginning-of-line
+[[ -n "${key[End]}"     ]]  && bindkey  "${key[End]}"     end-of-line
+[[ -n "${key[Insert]}"  ]]  && bindkey  "${key[Insert]}"  overwrite-mode
+[[ -n "${key[Delete]}"  ]]  && bindkey  "${key[Delete]}"  delete-char
+[[ -n "${key[Up]}"      ]]  && bindkey  "${key[Up]}"      up-line-or-history
+[[ -n "${key[Down]}"    ]]  && bindkey  "${key[Down]}"    down-line-or-history
+[[ -n "${key[Left]}"    ]]  && bindkey  "${key[Left]}"    backward-char
+[[ -n "${key[Right]}"   ]]  && bindkey  "${key[Right]}"   forward-char
+
+
+# Titre de la fenêtre d'un xterm
+case $TERM in
+   xterm*)
+       precmd () {print -Pn "\e]0;%n@%m: %~\a"}
+       ;;
+esac
+
+# Gestion de la couleur pour 'ls' (exportation de LS_COLORS)
+if [ -x /usr/bin/dircolors ]
+then
+  if [ -r ~/.dir_colors ]
+  then
+    eval "`dircolors ~/.dir_colors`"
+  elif [ -r /etc/dir_colors ]
+  then
+    eval "`dircolors /etc/dir_colors`"
+  else
+    eval "`dircolors`"
+  fi
+fi
+
+
+# ####################################### #
+# 3. Options de zsh (cf 'man zshoptions') #
+# ####################################### #
+
+# Je ne veux JAMAIS de beeps
+unsetopt beep
+unsetopt hist_beep
+unsetopt list_beep
+# >| doit être utilisés pour pouvoir écraser un fichier déjà existant ;
+# le fichier ne sera pas écrasé avec '>'
+#~ unsetopt clobber
+# Ctrl+D est équivalent à 'logout'
+unsetopt ignore_eof
+# Affiche le code de sortie si différent de '0'
+setopt print_exit_value
+# Demande confirmation pour 'rm *'
+unsetopt rm_star_silent
+# Correction orthographique des commandes
+# Désactivé car, contrairement à ce que dit le "man", il essaye de
+# corriger les commandes avant de les hasher
+#setopt correct
+# Si on utilise des jokers dans une liste d'arguments, retire les jokers
+# qui ne correspondent à rien au lieu de donner une erreur
+setopt nullglob
+
+# Options de complétion
+# Quand le dernier caractère d'une complétion est '/' et que l'on
+# tape 'espace' après, le '/' est effacé
+setopt auto_remove_slash
+# Ne fait pas de complétion sur les fichiers et répertoires cachés
+unsetopt glob_dots
+
+# Traite les liens symboliques comme il faut
+setopt chase_links
+
+# Quand l'utilisateur commence sa commande par '!' pour faire de la
+# complétion historique, il n'exécute pas la commande immédiatement
+# mais il écrit la commande dans le prompt
+setopt hist_verify
+# Si la commande est invalide mais correspond au nom d'un sous-répertoire
+# exécuter 'cd sous-répertoire'
+setopt auto_cd
+# L'exécution de "cd" met le répertoire d'où l'on vient sur la pile
+setopt auto_pushd
+# Ignore les doublons dans la pile
+setopt pushd_ignore_dups
+# N'affiche pas la pile après un "pushd" ou "popd"
+setopt pushd_silent
+# "pushd" sans argument = "pushd $HOME"
+setopt pushd_to_home
+
+# Les jobs qui tournent en tâche de fond sont nicé à '0'
+unsetopt bg_nice
+# N'envoie pas de "HUP" aux jobs qui tourent quand le shell se ferme
+unsetopt hup
+
+
+# ########################################### #
+# 4. Paramètres de l'historique des commandes #
+# ########################################### #
+
+setopt EXTENDED_HISTORY
+export HISTTIMEFORMAT="[%F %T] "
+
+# Nombre d'entrées dans l'historique
+export HISTORY=50000
+export SAVEHIST=50000
+
+# Fichier où est stocké l'historique
+export HISTFILE=$HOME/.history
+
+# Ajoute l'historique à la fin de l'ancien fichier
+setopt APPEND_HISTORY
+
+# Chaque ligne est ajoutée dans l'historique à mesure qu'elle est tapée
+setopt INC_APPEND_HISTORY
+
+# Ne stocke pas  une ligne dans l'historique si elle  est identique à la
+# précédente
+setopt HIST_IGNORE_DUPS
+
+# Supprime les  répétitions dans le fichier  d'historique, ne conservant
+# que la dernière occurrence ajoutée
+setopt HIST_IGNORE_ALL_DUPS
+
+# Supprime les  répétitions dans l'historique lorsqu'il  est plein, mais
+# pas avant
+#setopt hist_expire_dups_first
+
+# N'enregistre  pas plus d'une fois  une même ligne, quelles  que soient
+# les options fixées pour la session courante
+#setopt hist_save_no_dups
+
+# La recherche dans  l'historique avec l'éditeur de commandes  de zsh ne
+# montre  pas  une même  ligne  plus  d'une fois,  même  si  elle a  été
+# enregistrée
+setopt HIST_FIND_NO_DUPS
+
+
+# ####################################### #
+# 5. Complétion des options des commandes #
+# ####################################### #
+
+zstyle ':completion:*' matcher-list '' 'm:{a-z}={A-Z}'
+zstyle ':completion:*' max-errors 3 numeric
+zstyle ':completion:*' use-compctl false
+
+autoload -U compinit
+compinit
+
+[[ -e ~/opt/zsh-autosuggestions/zsh-autosuggestions.zsh ]] && source ~/opt/zsh-autosuggestions/zsh-autosuggestions.zsh
+
+# ###################### #
+# 6. Local configuration #
+# ###################### #
+[[ -e ~/.zshlocal ]] && source ~/.zshlocal
diff --git a/tasks/files/sshd_config b/tasks/user_cfg/files/sshd_config
similarity index 100%
rename from tasks/files/sshd_config
rename to tasks/user_cfg/files/sshd_config
diff --git a/tasks/user_cfg/main.yml b/tasks/user_cfg/main.yml
new file mode 100644
index 0000000..f3f9265
--- /dev/null
+++ b/tasks/user_cfg/main.yml
@@ -0,0 +1,13 @@
+---
+- hosts: "{{ host_list }}"
+  become_user: "{{ my_user }}"
+  become_method: su
+  remote_user: root
+
+  tasks:
+
+  - name: "IMPORT_TASKS | root"
+    ansible.builtin.import_tasks: root.yml
+
+  - name: "IMPORT_TASKS | {{ my_user }}"
+    ansible.builtin.import_tasks: my_user.yml
diff --git a/tasks/user_cfg/my_user.yml b/tasks/user_cfg/my_user.yml
new file mode 100644
index 0000000..c9f2987
--- /dev/null
+++ b/tasks/user_cfg/my_user.yml
@@ -0,0 +1,65 @@
+---
+
+- name: MY USER | dotfiles
+  become: yes
+  ansible.builtin.copy:
+    src: "{{ item }}"
+    dest: "/home/{{ my_user }}/.{{ item | basename }}"
+    mode: 0640
+    owner: "{{ my_user }}"
+    group: "{{ my_user }}"
+  with_fileglob:
+    files/dotfiles/*
+  loop_control:
+    label: "{{ item | basename }}"
+
+- name: MY USER | Set ZSH for shell
+  become: no
+  ansible.builtin.user:
+    name: "{{ my_user }}"
+    shell: /bin/zsh
+    state: present
+
+- name: MY USER | Git directory presence
+  become: yes
+  when: inventory_hostname in groups.station
+  ansible.builtin.file:
+    group: "{{ my_user }}"
+    mode: '0750'
+    owner: "{{ my_user }}"
+    path: "/home/{{ my_user }}/git"
+    state: directory
+
+- name: INCLUDE_VARS | git
+  ansible.builtin.include_vars: "vars/git.yml"
+
+- name: MY USER | Clone git repos
+  become: yes
+  when: inventory_hostname in groups.station
+  ansible.builtin.git:
+    dest: "/home/{{ my_user }}/git/{{ item.local_name }}"
+    repo:  "{{ item.url_https }}"
+    remote: "origin"
+    update: no
+    accept_hostkey: yes
+  with_items: "{{ git_repositories }}"
+  loop_control:
+    label: "{{ item.local_name }}"
+
+- name: MY USER | OSM cache dir presence
+  become: yes
+  when: inventory_hostname in groups.station
+  ansible.builtin.file:
+    group: "{{ my_user }}"
+    mode: '0750'
+    owner: "{{ my_user }}"
+    path: "/home/{{ my_user }}/.osm-tiles/"
+    state: directory
+
+- name: MY USER | GPS Prune config
+  ansible.builtin.template:
+    src: templates/pruneconfig.j2
+    dest: "/home/{{ my_user }}/.pruneconfig"
+    owner: "{{ my_user }}"
+    group: "{{ my_user }}"
+    mode: '0640'
diff --git a/tasks/user_cfg/root.yml b/tasks/user_cfg/root.yml
new file mode 100644
index 0000000..cd87761
--- /dev/null
+++ b/tasks/user_cfg/root.yml
@@ -0,0 +1,49 @@
+---
+
+- name: ROOT | dotfiles presence
+  become: no
+  ansible.builtin.copy:
+    src: "{{ item }}"
+    dest: "/root/.{{ item | basename }}"
+    mode: 0640
+    owner: root
+    group: root
+  with_fileglob:
+    files/dotfiles/*
+  loop_control:
+    label: "{{ item | basename }}"
+
+- name: ROOT | ZSH files absence
+  become: no
+  ansible.builtin.file:
+    path: "/etc/zsh/zlogin"
+    state: absent
+
+- name: ROOT | Set ZSH for shell
+  become: no
+  ansible.builtin.user:
+    name: root
+    shell: /bin/zsh
+    state: present
+
+- name: ROOT | TEMP-FIX font dir absence
+  become: no
+  ansible.builtin.file:
+    path: "/usr/local/share/fonts/fonts/"
+    state: absent
+
+- name: ROOT | JetBrainsMono presence
+  become: no
+  ansible.builtin.find:
+    path: "/usr/local/share/fonts/"
+    patterns: "JetBrainsMono*"
+    recurse: yes
+  register: font_presence
+
+- name: ROOT | install JetBrainsMono font
+  become: no
+  when: font_presence.matched < 50
+  ansible.builtin.unarchive:
+    dest: "/usr/local/share/"
+    remote_src: yes
+    src: https://download.jetbrains.com/fonts/JetBrainsMono-2.242.zip
diff --git a/tasks/user_cfg/templates/pruneconfig.j2 b/tasks/user_cfg/templates/pruneconfig.j2
new file mode 100644
index 0000000..bea383e
--- /dev/null
+++ b/tasks/user_cfg/templates/pruneconfig.j2
@@ -0,0 +1,35 @@
+# ############################################# #
+#            GpsPrune config file               #
+#               ~/.pruneconfig                  #
+#                                               #
+#       This file is managed by Ansible         #
+#       Manual edition will be overridden       #
+#                                               #
+#   https://lab.frogg.it/fcode/ansible/debian   #
+#                                               #
+# ############################################# #
+
+prune.unitsetkey=unitset.kilometres
+prune.mapsource=6
+prune.autosavesettings=1
+prune.exiftoolpath=exiftool
+prune.numfixedmapsources=6
+prune.kmzimagewidth=240
+prune.altitudetolerance=0
+prune.lastimportfileformat=-1
+prune.heightexaggeration=100
+prune.windowbounds=0x27x1920x1053
+prune.gnuplotpath=gnuplot
+prune.showmap=1
+prune.gpsbabelpath=gpsbabel
+prune.coorddisplay=19
+prune.waypointiconsize=1
+prune.povrayfont=crystal.ttf
+prune.terraingridsize=50
+prune.diskcache=/home/{{ my_user }}/.osm-tiles
+prune.gpsformat=garmin
+prune.latlonrange=45.06822;45.55014;5.77311;6.30281
+prune.antialias=1
+prune.gpsdevice=usb\:
+prune.trackdirectory=/home/{{ my_user }}/Documents/perso/cartes/
+prune.mapsourcelist=o\:OpenTopoMap;https\://a.tile.opentopomap.org/;png;18|
diff --git a/tasks/user_cfg/vars/git.yml b/tasks/user_cfg/vars/git.yml
new file mode 100644
index 0000000..bbb5084
--- /dev/null
+++ b/tasks/user_cfg/vars/git.yml
@@ -0,0 +1,33 @@
+---
+git_repositories:
+  - {local_name: "afpy19",              url_https: "https://gitlab.com/free_zed/afpy19.git"}
+  - {local_name: "askthom",             url_https: "https://lab.frogg.it/fcode/askthom.git"}
+  - {local_name: "courotaf.gitlab.io",  url_https: "https://gitlab.com/courotaf/courotaf.gitlab.io.git"}
+  - {local_name: "djlease",             url_https: "https://gitlab.com/free_zed/djlease.git"}
+  - {local_name: "eb-car",              url_https: "https://gitlab.com/combien-de-temps-pour-faire-sonner-la-cloche-a-aiguebelle/combien-de-temps-pour-faire-sonner-la-cloche-a-aiguebelle.gitlab.io.git"}
+  - {local_name: "exchange",            url_https: "https://gitlab.com/free_zed/mymsesb.git"}
+  - {local_name: "forga-a14n",          url_https: "https://gitlab.com/free_zed/djbp.git"}
+  - {local_name: "forga-core",          url_https: "https://gitlab.com/forga/tool/django/core.git"}
+  - {local_name: "forga-emb",           url_https: "https://gitlab.com/forga/process/fr/embarquement.git"}
+  - {local_name: "forga-glio",          url_https: "https://gitlab.com/forga/forga.gitlab.io.git"}
+  - {local_name: "forga-man",           url_https: "https://gitlab.com/forga/process/fr/manuel.git"}
+  - {local_name: "forga-tool-debian",   url_https: "https://lab.frogg.it/fcode/ansible/debian.git"}
+  - {local_name: "freezed.gl.io",       url_https: "https://gitlab.com/free_zed/free_zed.gitlab.io.git"}
+  - {local_name: "ftalk-gitlab",        url_https: "https://gitlab.com/ftalk/2020-gitlab.git"}
+  - {local_name: "gpxpy",               url_https: "https://github.com/freezed/gpxpy.git"}
+  - {local_name: "grandpy",             url_https: "https://github.com/freezed/ocp7.git"}
+  - {local_name: "hellozappa",          url_https: "https://gitlab.com/free_zed/hellozappa.git"}
+  - {local_name: "men-rt-ocp08",        url_https: "https://github.com/remace/OC-P8-Purbeurre.git"}
+  - {local_name: "men-rt-ocp09",        url_https: "https://github.com/remace/P9-OCPizza_doc_Technique.git"}
+  - {local_name: "mountaingpx",         url_https: "https://github.com/krisanselmo/mountaingpx.git"}
+  - {local_name: "myasb",               url_https: "https://gitlab.com/forga/tool/ansible/debian.git"}
+  - {local_name: "mygpxsb",             url_https: "https://gitlab.com/courotaf/mygpxsb.git"}
+  - {local_name: "mypsb",               url_https: "https://gitlab.com/free_zed/mypsb.git"}
+  - {local_name: "mypumlt",             url_https: "https://gitlab.com/free_zed/mypumlt.git"}
+  - {local_name: "myshellsb",           url_https: "https://gitlab.com/free_zed/shell.git"}
+  - {local_name: "ocp13",               url_https: "https://github.com/freezed/ocp13.git"}
+  - {local_name: "ocp5",                url_https: "https://github.com/freezed/ocp5.git"}
+  - {local_name: "ocp8",                url_https: "https://gitlab.com/free_zed/ocp8.git"}
+  - {local_name: "pyconfr19",           url_https: "https://gitlab.com/free_zed/pyconfr19.git"}
+  - {local_name: "python-itop-api",     url_https: "https://github.com/guillaume-philippon/python-itop-api.git"}
+  - {local_name: "signature_pad",       url_https: "https://github.com/szimek/signature_pad.git"}
diff --git a/tasks/vars/main.yml b/tasks/vars/main.yml
index 41ff73f..2a26a75 100644
--- a/tasks/vars/main.yml
+++ b/tasks/vars/main.yml
@@ -19,6 +19,7 @@ base_pkg:
   - vim
   - wget
   - xkcdpass
+  - zsh
 
 base_uninstall_pkg: []
 
-- 
GitLab