ansible: birkaç satır için lineinfile?


162

Aynı şekilde lineinfiledosyaya bir satır eklemek için bir modül vardır, birkaç satır eklemenin bir yolu var mı?

Tüm dosyayı sağlamak zorunda olduğunuz için bir şablon kullanmak istemiyorum. Ben sadece bir şablon bir seçenek değil bu yüzden zaten dosyanın ne içerdiğini bilmeden varolan bir dosyaya bir şey eklemek istiyorum.


templateKullanmak istemediğinizi anlıyorum , ama kullanmak lineinfilebir antipattern . Ayrıca, "dosyada ne olduğunu bilmediğiniz" anlamına gelen güçlü bir kırmızı bayrak, bu da bilinmeyen hataların önemli riskine yol açar.
tedder42

39
Bu bir anti-desen değil. Lineinfile'ın amacı, aynı dosyayı yöneten ve bazen kaçınılmaz olan birden fazla kaynağı desteklemektir. Çoğu yapılandırma dosyası sabit bir biçime sahiptir ve çakışmaları önlemek için mantık genellikle çok önemli değildir.
Doug F

Bilgisayarımdaki dosyaların büyük çoğunluğunda ne olduğunu bilmiyorum; hepsini tıklatmak istediğim anlamına gelmez!
DylanYoung

Yanıtlar:


222

Bunu yapmak için bir döngü kullanabilirsiniz . with_itemsDöngü kullanan bir örnek :

- name: Set some kernel parameters
  lineinfile:
    dest: /etc/sysctl.conf
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
  with_items:
    - { regexp: '^kernel.shmall', line: 'kernel.shmall = 2097152' }
    - { regexp: '^kernel.shmmax', line: 'kernel.shmmax = 134217728' }
    - { regexp: '^fs.file-max', line: 'fs.file-max = 65536' }

Emin olun line = ve regexp = argümanında tırnak işareti vardır . Yapmadım ve almaya devam ettim msg: this module requires key=value arguments. Verilen örnekte bu doğru - sadece örneği takip etmedim.
JDS

1
İlk değişiklikten önce nasıl tek bir yedekleme yapılacağını sorabilir miyim? belki item.backup? : D
tdihp

6
Bu muhtemelen Ansible 2.0'dan önce oylandı. Şimdi daha iyi bir cevap: stackoverflow.com/a/28306576/972128
kkurian

@kkurian Kesinlikle sadece takıyorsanız, değiştiriyorsanız değil mi?
ndtreviv

7
@kkurian Örneğin json dosyasına bazı satırlar eklemeniz ve herhangi bir işaretçi istemiyorsanız blockinfile çözümü çalışmaz. İşaretçileri "" olarak ayarlayabilmenize rağmen, ansible blockinfile yine de işaretçileri arayacak, bulmayacak ve bloğu tekrar yerleştirecektir. Bu nedenle, işaretleyicisiz blockinfile idempotent değildir, bir loop ile lineinfile olur.
saçma

176

Bunun blockinfileyerine kullanmayı deneyebilirsiniz .

Gibi bir şey yapabilirsin

- blockinfile: |
    dest=/etc/network/interfaces backup=yes
    content="iface eth0 inet static
        address 192.168.0.1
        netmask 255.255.255.0"

8
blockinfileModül harika bunu kullanmayı tercih ettik her zaman dışarı çalıştı. Özellikle insertafter/ insertbeforeoptions'ın sezgisel davranışını seviyorum .
Jay Taylor

9
En çok oy alan cevap muhtemelen Ansible 2.0'dan önceydi, ama şimdi daha doğru cevap bu.
Willem van Ketwich

11
Blockinfile markör gerektirir. Bu bazen bir seçenek değildir.
ceving

1
İle içeriğin üzerine yazabilir miyiz blockinfile?
pkaramol

1
Bunu yapmanın doğru bir yolu olduğunu düşünüyorum. docs.ansible.com/ansible/blockinfile_module.html
Paulo Victor

20

Benzersiz özellik = değer satırları kümesini yapılandırmanız gerekirse, daha kısa bir döngü öneririm. Örneğin:

- name: Configure kernel parameters
  lineinfile:
    dest: /etc/sysctl.conf
    regexp: "^{{ item.property | regex_escape() }}="
    line: "{{ item.property }}={{ item.value }}"
  with_items:
    - { property: 'kernel.shmall', value: '2097152' }
    - { property: 'kernel.shmmax', value: '134217728' }
    - { property: 'fs.file-max', value: '65536' }

Alix Axel tarafından önerilen şekilde bir diksiyon kullanarak ve eşleşen yorumların otomatik olarak kaldırılmasını ekleyerek,

- name: Configure IPV4 Forwarding
  lineinfile:
    path: /etc/sysctl.conf
    regexp: "^#? *{{ item.key | regex_escape() }}="
    line: "{{ item.key }}={{ item.value }}"
  with_dict:
    'net.ipv4.ip_forward': 1

2
With_dict ile kullanırsanız daha kısa ve öz olur.
Alix Axel

18

İşte çözüm ile birlikte kullanılabilecek gürültüsüz bir sürümü:

- name: add lines
  lineinfile: 
    dest: fruits.txt
    line: '{{ item }}'
  with_items:
    - 'Orange'
    - 'Apple'
    - 'Banana' 

Her öğe için, öğe fruit.txt dosyasında varsa, herhangi bir işlem yapılmaz.

Öğe yoksa dosyanın sonuna eklenir.

Tereyağından kıl çeker gibi.


Bu yerleştirici ile birleştirilemez.
ceving

Birden fazla satır eksikse, öğenin bir sırada görünmesini istiyorum. Öğelerin eklendiği siparişten nasıl emin olabilirim?
MUY Belçika

5

İdeal değil, ancak birden fazla aramaya izin verilir lineinfile. Bunu kullanarak insert_afteristediğiniz sonucu elde edebilirsiniz:

- name: Set first line at EOF (1/3)
  lineinfile: dest=/path/to/file regexp="^string 1" line="string 1"
- name: Set second line after first (2/3)
  lineinfile: dest=/path/to/file regexp="^string 2" line="string 2" insertafter="^string 1"
- name: Set third line after second (3/3)
  lineinfile: dest=/path/to/file regexp="^string 3" line="string 3" insertafter="^string 2"

5
evet ama yine de her seferinde bir satır. 15 satırım varsa, bunları tek bir komutla eklemeyi tercih ederim. Bu mümkün görünmüyor.
Michael

1
Teşekkürler. Görünüşe göre bu, sonra / önce ekleme ile birden fazla satır yapmanın tek yolu.
timss

5

Bunu \nline parametresini kullanarak yapabildim .

Dosyanın doğrulanabilmesi ve tek bir satırın eklenmesi geçersiz bir dosya oluşturuyorsa özellikle yararlıdır.

Benim durumumda, ben ekleyerek oldu AuthorizedKeysCommandve AuthorizedKeysCommandUserhiç sshd_config şu komutla,:

- lineinfile: dest=/etc/ssh/sshd_config line='AuthorizedKeysCommand /etc/ssh/ldap-keys\nAuthorizedKeysCommandUser nobody' validate='/usr/sbin/sshd -T -f %s'

Seçeneklerden yalnızca birini eklemek, doğrulamayı geçemeyen bir dosya oluşturur.


12
Bu, çalışma kitabının her çalıştırılışında satırı ek bir kez oluşturur - satırın zaten var olduğunu doğru olarak algılamaz. En azından benim için Ansible 1.7.1'de böyle
David

1
Bir hata rapor ettim , ama Ansible adamlarının bunu düzeltmeye hiçbir ilgisi yok.
ceving

1
Şimdi bu çözümden daha iyi olması gereken yeni bir blok dosya modülü var. ( docs.ansible.com/ansible/blockinfile_module.html )
Penz

1

Birden fazla satır eklemek için blockfile kullanabilirsiniz:

- name: Add mappings to /etc/hosts
  blockinfile:
    path: /etc/hosts
    block: |
      '10.10.10.10  server.example.com'
      '10.10.10.11  server1.example.com'

Bir satır eklemek için lininfile kullanabilirsiniz:

- name: server.example.com in /etc/hosts
  lineinfile:
    path: /etc/hosts
    line: '192.0.2.42 server.example.com server'
    state: present

1

Birden çok satır eklemek için, burada değişken de dahil olmak üzere lineinfilemodülü basitleştirmek için kullanabilirsiniz :)with_itemsvars

---
- hosts: localhost  #change Host group as par inventory
  gather_facts: no
  become: yes
  vars:
    test_server: "10.168.1.1"
    test_server_name: "test-server"
    file_dest: "/etc/test/test_agentd.conf"

  - name: configuring test.conf
    lineinfile:
      dest: "{{ item.dest }}"
      regexp: "{{ item.regexp }}"
      line: "{{ item.line }}"
    with_items:
      - { dest: '"{{ file_dest }}"', regexp: 'Server=', line: 'Server="{{test_server}}"' }
      - { dest: '"{{ file_dest }}"', regexp: 'ServerActive=', line: 'ServerActive="{{test_server}}"' }
      - { dest: '"{{ file_dest }}"', regexp: 'Hostname=', line: 'Hostname="{{test_server_name}}"' }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.