Je peux le faire avec Shell en combinant getent
et awk
comme ceci:
getent passwd $user | awk -F: '{ print $6 }'
Pour référence, dans Puppet, je peux utiliser un fait personnalisé, comme ceci:
require 'etc'
Etc.passwd { |user|
Facter.add("home_#{user.name}") do
setcode do
user.dir
end
end
}
qui rend le répertoire personnel de l'utilisateur disponible en tant que home_<user name>
fait.
Comment obtenir le répertoire personnel d'un utilisateur distant arbitraire ?
Ansible (à partir de la version 1.4) révèle déjà les variables d’environnement pour l’utilisateur sous le ansible_env
variable.
- hosts: all
tasks:
- name: debug through ansible.env
debug: var=ansible_env.HOME
Alternativement, vous pouvez accéder aux variables d'environnement en utilisant un lookup on env
:
- hosts: all
tasks:
- name: debug through lookup on env
debug: var=lookup('env','HOME')
Malheureusement, vous ne pouvez apparemment utiliser ceci que pour obtenir des variables d'environnement pour l'utilisateur connecté, comme le montre ce livret et cette sortie:
- hosts: all
tasks:
- name: debug specified user's home dir through ansible.env
debug: var=ansible_env.HOME
become: true
become_user: "{{ user }}"
- name: debug specified user's home dir through lookup on env
debug: var=lookup('env','HOME')
become: true
become_user: "{{ user }}"
[~ # ~] sortie [~ # ~] :
vagrant@Test-01:~$ ansible-playbook -i "inventory/vagrant" env_vars.yml -e "user=testuser"
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.0.30]
TASK: [debug specified user's home dir through ansible.env] *******************
ok: [192.168.0.30] => {
"var": {
"/home/vagrant": "/home/vagrant"
}
}
TASK: [debug specified user's home dir through lookup on env] *****************
ok: [192.168.0.30] => {
"var": {
"/home/vagrant": "/home/vagrant"
}
}
PLAY RECAP ********************************************************************
192.168.0.30 : ok=3 changed=0 unreachable=0 failed=0
Comme pour tout ce qui est dans Ansible, si vous ne pouvez pas obtenir un module qui vous donne ce que vous voulez, vous êtes toujours libre de Shell out moins descriptif) en utilisant quelque chose comme ceci:
- hosts: all
tasks:
- name: grep and register
Shell: >
egrep "^{{ user }}:" /etc/passwd | awk -F: '{ print $6 }'
changed_when: false
register: user_home
- name: debug output
debug: var=user_home.stdout
Il y a peut-être une façon plus propre de faire cela et je suis un peu surpris que l'utilisation de become_user
le passage à l'utilisateur spécifié ne semble pas affecter la recherche env
, mais cela devrait vous donner ce que vous voulez.
Ansible 1.8 a introduit le module getent
. Il enregistre le résultat de getent en tant que fait de l'hôte. Dans ce cas, il s'agit de getent_passwd
.
Imprimer le dossier de départ pour un user
donné:
---
- getent:
database: passwd
key: "{{ user }}"
split: ":"
- debug:
msg: "{{ getent_passwd[user][4] }}"
Accumuler une table de recherche (user_homes
), En utilisant set_fact
et le Jinja2 combine()
filtre :
---
- assert:
that:
- user_name is defined
- when: user_homes is undefined or user_name not in user_homes
block:
- name: getent
become: yes
getent:
database: passwd
key: "{{ user_name }}"
split: ":"
- name: set fact
set_fact:
"user_homes": "{{ user_homes | d({}) | combine({user_name: getent_passwd[user_name][4]}) }}"
Ce serait mieux avec un module de faits personnalisé cependant.
Les méthodes lookup()
ou ENV var pour trouver le domicile d'un utilisateur arbitraire ne fonctionneront malheureusement pas de manière fiable avec Ansible car elles s'exécutent sous le nom d'utilisateur spécifié avec --user=REMOTE_USER
, et éventuellement avec Sudo
(si Sudo: yes
dans le livre de jeu ou --Sudo
passé). Ces deux modes d’exécution (Sudo ou non Sudo) modifieront l’environnement Shell dans lequel Ansible est exécuté, et même dans ce cas, vous serez limité à l’utilisateur spécifié en tant que -u REMOTE_USER
ou root
.
Vous pouvez essayer d'utiliser Sudo: yes
, et Sudo_user: myarbitraryuser
ensemble ... cependant, à cause d'un bogue dans certaines versions de Ansible , vous constaterez qu'il ne se comporte pas comme il se doit. Si vous êtes sur Ansible> = 1.9
, vous pouvez utiliser become: true
, et become_user: myarbitraryuser
au lieu. Cependant, cela signifie que les playbooks et les rôles que vous écrivez ne fonctionneront pas avec les versions précédentes d'Ansible.
Si vous recherchez un moyen portable d'obtenir le répertoire personnel d'un utilisateur qui fonctionne également avec LDAP ou un autre service d'annuaire, utilisez getent
.
Créez un livre de lecture simple nommé: playbooks/ad-hoc/get-user-homedir.yml
- hosts: all
tasks:
- name:
Shell: >
getent passwd {{ user }} | cut -d: -f6
changed_when: false
register: user_home
- name: debug output
debug: var=user_home.stdout
Exécutez-le avec:
ansible-playbook -i inventory/racktables.py playbooks/ad-hoc/get-user-homedir.yml -e "user=someuser"
Je pense qu'il y a plusieurs réponses données ici qui pourraient marcher, mais je pensais montrer que vous pouvez l'obtenir à partir du module ansible user , en l'enregistrant en tant que variable.
- user:
name: www-data
state: present
register: webserver_user_registered
Note: cela créera l'utilisateur s'il n'existe pas ...
Nous pouvons donc utiliser debug pour afficher les valeurs de cette variable, y compris le chemin ...
- debug:
var: webserver_user_registered
TASK [wordpress : debug] ******************
ok: [wordpresssite.org] => {
"webserver_user_registered": {
"append": false,
"changed": false,
"comment": "www-data",
"failed": false,
"group": 33,
"home": "/var/www", <<------ this is the user home dir
"move_home": false,
"name": "www-data",
"Shell": "/usr/sbin/nologin",
"state": "present",
"uid": 33
}
}
Et vous pouvez utiliser ces propriétés dans d'autres modules comme celui-ci;
- file:
name: "{{ webserver_user_registered.home }}/.wp-cli"
state: directory
Je sais que c'est un fil assez ancien, mais je pense que c'est un moyen un peu plus simple d'obtenir le répertoire de base des utilisateurs
- name: Get users homedir
local_action: command echo ~
register: homedir
Sur les systèmes Linux (ou Unix), le signe-tilde indique le répertoire de base de l'utilisateur.
Chaque réponse mentionne comment imprimer les détails du répertoire de base lors de l'exécution du playbook et de son affichage à l'écran à l'aide de debug et var .
S'adapter à @TrinitronX réponse
Informations supplémentaires sur l'utilisation de ces informations pour une nouvelle tâche.
J'ai une liste d'utilisateurs dont le répertoire de base doit être extrait. J'ai donc ajouté les détails de l'utilisateur à une liste
- name: Get home directory
Shell: >
getent passwd {{ item.user }} | cut -d: -f6
changed_when: false
with_items:
- "{{Java}}"
register: user_home
Ici, cette étape va parcourir toute la liste des utilisateurs et va enregistrer ces détails dans user_home. Et ce sera sous la forme d'un tableau.
La prochaine étape consiste à utiliser ces informations pour une nouvelle tâche, par exemple, la création d’un fichier dans un profil bash. Ceci est juste un exemple et peut être n'importe quel scénario, mais la méthode restera la même.
- name: Set Java home in .bash_profile
lineinfile: path="{{ item.stdout }}/.bash_profile" regexp='^source "{{ Java_dir }}/.bash_profile_Java"' line='source "{{ Java_dir }}/.bash_profile_Java"' state=present
with_items:
- "{{ user_home.results }}"
loop_control:
label: "{{ item.stdout }}"
J'ai défini un fait pour Java_dir sur/usr/Java/latest dans le même livre de lecture.
Le tableau user_home.results contiendra les détails de la tâche Obtenir le répertoire de base. Maintenant, nous parcourons ce tableau et prenons la valeur stdout qui contient le chemin du répertoire de base.
J'ai mis loop_control pour l'impression du répertoire de base uniquement, sinon il affichera tout le tableau.
Grâce à ce processus, nous pouvons nous assurer que si n nombre d’utilisateurs sont présents, nous pouvons suivre cette méthode et que tous seront pris en charge.
Remarque: j'ai commencé à apprendre le Ansible, au cas où une terminologie que j'aurais utilisée serait mauvaise, veuillez l'excuser. J'ai passé du temps à comprendre comment faire cela et à penser à partager la même chose.
Vous pouvez utiliser expanduser
.
Par exemple, en parcourant une liste d'utilisateurs:
- name: Deploys .bashrc
template:
src: bashrc.j2
dest: "{{ '~' + item | expanduser }}/.bashrc"
mode: 0640
owner: "{{ item }}"
group: "{{ item }}"
with_items: user_list
Il n'y a pas de moyen facile de faire cela dans Ansible en ce moment et c'est pourquoi vous devriez ajouter vos votes à cette question
https://github.com/ansible/ansible/issues/15901
Bien que vous puissiez utiliser cette solution de contournement: https://stackoverflow.com/a/33343455/99834 vous ne devez pas oublier d’envoyer les commentaires voulant qu’ils soient faciles à utiliser.