Fórum Root.cz
Hlavní témata => Server => Téma založeno: Jiří Šachl 13. 08. 2021, 14:39:28
-
zdravím.
Standardní výstup z pc:
Static hostname: ubuntuserver
Icon name: computer-vm
Chassis: vm
Machine ID: dc9ba6f6ac344d5d8240e87cf0c436f1
Boot ID: 9f11ecf7227146be9616046e66800565
Virtualization: kvm
Operating System: Ubuntu 20.04.2 LTS
Kernel: Linux 5.4.0-81-generic
Architecture: x86-64
Dalo by se nějak přesměrovat výstup do souboru ale jen ve formátu:
Static hostname: ubuntuserver, Operating System: Ubuntu 20.04.2 LTS, Kernel: Linux 5.4.0-81-generic, Architecture: x86-64
-
Něco ve smyslu
hostnamectl | grep -E "(Static hostname:|Operating System:|Kernel:|Architecture:)" | sed -e 's/^ \+//g' -e 's/$/, /g' | tr -d $'\n'
Výrazem v grepu si vyberete řádky, co chcete, první příkaz v sedu odstraní leading whitespace, druhý příkaz dá na konce řádků čárky, a nakonec se to prožene příkazem tr, který smaže newlines. Jediná deviace je, že i za posledním polem je ", "
-
Tohle
hostnamectl | sed -e 's/^ \+//g' | grep -E "(Static hostname:|Operating System:|Kernel:|Architecture:)" | sed '$!s/$/,/' | tr '\n' ' ' | grep -v '\['mi vraci
Static hostname: localhost.localdomain, Operating System: blabla, Kernel: Linux 5.x86_64, Architecture: x86-64
-
nebo jenom v perlu
hostnamectl | perl -nle 's/^\s+//; push @x, $_ if /^(Static hostname|Operating System|Kernel|Architecture):/;' -e 'END { print join ",", @x }'
-
nebo bez hostnamectl ;-)
echo "Static hostname: $(hostname), Operating System: $(lsb_release -ds), Kernel: $(uname -sr), Architecture: $(arch)"
-
PARÁDA. Moc děkuji všem. Vše funguje.
-
Z uvedených možností jsem vybral jednu a připravil script pro ansible. Účelem je postit ho nad sítí a vycucnout z ní co je za podřízená distra, v jaké architektuře apod. Takový script se pustí jen jednou. Hodí se tam kde těch počítačů jsou desítky.
Nicméně stále tápu a mám tam jednu banální chybu:
---
- hosts: all
remote_user: spravce
become: yes
become_method: sudo
tasks:
- name: Vytvor vycuc z hostname
shell: 'echo "IP address: $(hostname -I)Static hostname: $(hostname), Operating System: $(lsb_release -ds), Kernel: $(uname -sr), Architecture: $(arch)" >> /home/spravce/$(hostname).txt'
- name: Zmena prav k souboru
file:
path: '/home/spravce/$(hostname).txt'
owner: spravce
group: spravce
mode: '0644'
- name: Odeslani logu na ridici server
fetch:
src: '/home/spravce/$(hostname).txt'
dest: '/home/spravce/ansible_sachlj/funguje/hostname/'
už v kroku kdy se mají nastavit práva k souboru (vygeneruje soubor s právy roota) to hodí chybovou hlášku:
FAILED! => {"changed": false, "msg": "file (/home/spravce/$(hostname).txt) is absent, cannot continue", "path": "/home/spravce/$(hostname).txt", "state": "absent"}
kdy mi jasně říká že soubor $(hostname).txt nenašel...přitom v kroku kdy soubor definuje ho v pohodě udělá např. centos8.txt....
jak mu tedy mám v dalších krocích (změna práv a odeslání na řídící server) definovat název kterému bude rozumět? Název je hostname.txt každého serveru.
Děkuji
-
Z uvedených možností jsem vybral jednu a připravil script pro ansible.
https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html#ansible-facts
-
https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html#ansible-facts
bezva to je ale až moc podrobné a neřeší to problém. Potřebuji vytáhnout data o podřízené stanici: tj. hostname, ip adresa, distro, architektura (32 n 64 bit), kernel...víc nepotřebuji..to uložit do souboru a ten mi zaslat na řídící server, tj.server kde je ansible..proč? no proto abych pak z těch souborů složil soubor hosts a rozčlenil servery do skupin : ubuntu,debian a rhel, centos a řídil pak scripty podle distra..mám tak už v čísti sítě to takto udělané, tam bylo ale jen pár serverů kde se ty informace získaly ručně...
-
bezva to je ale až moc podrobné a neřeší to problém.
Jak to že ne? Pomocí ansible voláte shell skript, který vám zjišťuje vše, co potřebujete. Jenže, pokud není určeno jinak, ansible si zjišťuje fakta automaticky (TASK [Gathering Facts]) před voláním dalších tasku. Tedy před tím vaším shell taskem si to už samo zjistilo všechna data.
Udělejte si to jak chcete, ale je vždy lepší používat vestavěné funkce namísto volání shell.
-
beru zpět...už jsem našel co a jak..teď si s tím hraju..
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
-
celé je to v tomhle příkazu.
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
ansible all -m ansible.builtin.setup --tree /tmp/facts
co mě zajímá lze pak vyzobat. Například:
ansible all -m ansible.builtin.setup --tree /tmp/facts -a 'filter=ansible_all_ipv4_addresses,size,labels,ansible_hostname,ansible_kernel,ansible_os_family'
do filtru lze dát cokoliv co si vyčtu z toho kompletního výpisu.
-
Není potřeba dopředu nic skládat a rozčleňovat, ansible si ten systém ošahává právě proto, aby věděl, s čím pracuje, takže veškeré "řízení" je možné za běhu. Typicky bývá jeden z prvních tasků playbooku load varsů, které jsou nějakým způsobem odlišné -- třeba právě podle distribuce/architektury, jako názvy balíků, cesty, atp.
Takže pustíš playbook, ansible ví, že je to CentOS, a naloaduje si soubor s varsama, které platí pro CentOS. V dalším tasku chceš třeba instalovat specifický balík -- název pro CentOS máš zadefinovaný právě v tom už naloadovaném souboru. Pro Debian se ten balík ale jmenuje jinak, takže máš další soubor, který se loaduje, pokud je distro Debian -- tímto způsobem to máš všechno na hromádce uspořádané, když ti přibude další distro, tak si jen přidáš další soubor a do něj příslušné specifikum. Stejně tak jde pak i běh samotného tasku podmiňovat hodnotou dostupných faktů.
Záleží, jak moc si s tím pohraješ a jak moc to budeš chtít mít parametrizované, ale cílem je mít ideálně roli, která je univerzální a přitom stále přehledně definovaná, což oceníš při pozdějších aktualizacích.
https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html (https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html)
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/first_found_lookup.html (https://docs.ansible.com/ansible/latest/collections/ansible/builtin/first_found_lookup.html)
https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html#ansible-facts
bezva to je ale až moc podrobné a neřeší to problém. Potřebuji vytáhnout data o podřízené stanici: tj. hostname, ip adresa, distro, architektura (32 n 64 bit), kernel...víc nepotřebuji..to uložit do souboru a ten mi zaslat na řídící server, tj.server kde je ansible..proč? no proto abych pak z těch souborů složil soubor hosts a rozčlenil servery do skupin : ubuntu,debian a rhel, centos a řídil pak scripty podle distra..mám tak už v čísti sítě to takto udělané, tam bylo ale jen pár serverů kde se ty informace získaly ručně...
-
celé je to v tomhle příkazu.
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html
ansible all -m ansible.builtin.setup --tree /tmp/facts
co mě zajímá lze pak vyzobat. Například:
ansible all -m ansible.builtin.setup --tree /tmp/facts -a 'filter=ansible_all_ipv4_addresses,size,labels,ansible_hostname,ansible_kernel,ansible_os_family'
do filtru lze dát cokoliv co si vyčtu z toho kompletního výpisu.
Ansible si pri pripojeni na host tu masinu osaha sam dost podrobne. https://docs.ansible.com/ansible/latest/user_guide/playbooks_vars_facts.html
-
Vlastne staci do tasku dat
- name: Play tasks by distro
include: "{{ansible_tasks['ansible_distribution']}}-{{ansible_tasks['ansible_distribution_major_version']}}.yaml"
alebo pouzit when...
Nez to davat natvrdo do host suboru a udrziavat to, tak je lepsie nechat ansible nech sa rozhodne sam podla aktualnej situacie.
-
Já jsem použil tohleto.
ansible all -m ansible.builtin.setup --tree /tmp/facts -a 'filter=ansible_all_ipv4_addresses,labels,ansible_hostname,ansible_hostname,size,ansible_kernel,ansible_os_family,ansible_distribution_file_variety,ansible_distribution_version,ansible_distribution_release'
celé je to kvůli tomuhle.
---
- hosts: rhel,centos
remote_user: spravce
become: yes
become_method: sudo
tasks:
- name: Update vsechny instalovane balicky cestou YUM modulu
yum:
name: '*'
state: latest
update_cache: yes
update_only: yes
register: yum_update_status
- name: Odstran balicky ktere uz nejsou potreba
yum:
autoremove: yes
- name: Restart kdyz se balicky aktualizovaly
reboot:
post_reboot_delay: 60
when: yum_update_status.changed
- hosts: debian,ubuntu
remote_user: spravce
become: yes
become_method: sudo
tasks:
- name: Update vsechny instalovane balicky cestou APT modulu
apt:
name: '*'
state: latest
update_cache: yes
only_upgrade: yes
register: apt_update_status
- name: Odstran balicky ktere uz nejsou potreba
apt:
autoremove: yes
- name: Restart kdyz se balicky aktualizovaly
reboot:
post_reboot_delay: 60
when: apt_update_status.changed
Mohl bych zjišťovat jaké distro je a podle toho příkazy, tohle je ale rychlejší..v hosts mám pak skupiny podle dister....
takhle mám udělané de fakto všechny scripty...
-
jako jo, ale pořád je tam "externí" závislost -- tu si zkus zeliminovat a integrovat logiku přímo do playbooku... funkční to máš, tohle je spíš o tom, jak moc elegantně chceš ten nástroj používat, protože když pak tomu přijde někdo, kdo ansible bude znát o trochu víc, tak se bude chytat za hlavu a buď uteče, nebo to přepíše podle nějakých zaběhlých "best practice"
existuje bezpohlavní modul, který umí obhospodařit různé package managery:
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/package_module.html (https://docs.ansible.com/ansible/latest/collections/ansible/builtin/package_module.html)
a pro inspiraci starší thread
https://serverfault.com/questions/587727/how-to-unify-package-installation-tasks-in-ansible (https://serverfault.com/questions/587727/how-to-unify-package-installation-tasks-in-ansible)
Já jsem použil tohleto.