Uzaktaki bir sistemdeki Ansible görevini kullanarak dosya taşıma / yeniden adlandırma


203

Uzaktaki bir sistemdeki Ansible modülünü kullanarak bir dosyayı / dizini taşımak / yeniden adlandırmak nasıl mümkün olur? Komut / kabuk görevlerini kullanmak istemiyorum ve dosyayı yerel sistemden uzak sisteme kopyalamak istemiyorum.


Neden command / shell'i kullanmak istemiyorsunuz?
Nick Urban

4
Sadece belirtilen görevleri kullanmadan bir yol olup olmadığını bilmek istedim. Görünüşe göre şu anda başka bir yol yok.
Christian Berendt

1
Neden kopyalamak yerine özel olarak taşımak istiyorsunuz? Bu, sistemin durumunu belirleyen idempotent bir adımdan ziyade tek seferlik bir eylem gibi görünüyor.
Nick Urban

2
Bir RPM paketine dahil bir örnek yapılandırma dosyası var ve bu örnek yapılandırma dosyasını taşımak istiyorum.
Christian Berendt

1
Şu anda dosyaya referans vermek için bir sembolik bağlantı kullanıyorum. Get_url kullanmak benim için bir seçenek değil çünkü sistem internete erişemiyor.
Christian Berendt

Yanıtlar:


203

Dosya modülü uzaktaki sisteme dosya kopyalamaz. Src parametresi, dosya modülü tarafından bir dosyaya sembolik bağlantı oluştururken kullanılır.

Bir dosyayı tamamen uzaktaki bir sistemde taşımak / yeniden adlandırmak istiyorsanız, en iyi seçeneğiniz komut modülünü kullanarak sadece uygun komutu çağırmaktır:

- name: Move foo to bar
  command: mv /path/to/foo /path/to/bar

Eğer fantezi almak istiyorsanız önce foo'nun gerçekten var olup olmadığını kontrol etmek için stat modülünü kullanabilirsiniz:

- name: stat foo
  stat: path=/path/to/foo
  register: foo_stat

- name: Move foo to bar
  command: mv /path/to/foo /path/to/bar
  when: foo_stat.stat.exists

3
Komut modülünü kullanmadan, başka tek seçeneğiniz kendi özel modülünüzü yazmak olacaktır.
Bruce P

2
Uzak dosyaları kopyalamanın geçerli yolu bu olduğundan doğru yanıt olarak etiketlendi.
Christian Berendt

11
Atlamadan önce bakmayla ilgili olarak: bu removesseçeneği commandmodüle ( burada belgelenmiştir ) kullanmamanın bir nedeni var mı? Görünüşe göre bu seçenek Ansible'ı kontrol ettirecek.
Jim Witschey

2
Ansible, işleyiciyi bildirmek için değişiklikleri izler, bu da bu çözümü yetersiz kılar.
boh

4
Eğer kullanırsanız elle dosyanın varlığını kontrol etmek gerekmez removes: /path/to/foove creates: /path/to/bar. @Fonant bunu başka bir cevaba yorum olarak zaten belirtti, ancak bu kabul edilen cevap olduğu için tekrar belirtmek istiyorum.
Michael Trojanek

218

Sürüm 2.0'dan , kopya modülünderemote_src parametre kullanabilirsiniz .

Eğer Trueo src uzaktan / hedef makineye gidecek.

- name: Copy files from foo to bar
  copy: remote_src=True src=/path/to/foo dest=/path/to/bar

Dosyayı taşımak istiyorsanız, dosya modülüyle eski dosyayı silmeniz gerekir

- name: Remove old files foo
  file: path=/path/to/foo state=absent

2.8 sürümünden itibaren kopya modülü remote_src özyinelemeli kopyalamayı destekler.


29
Küçük açıklama: "Şu anda remote_src yinelemeli kopyalamayı desteklemiyor." ansible modülünden alınmıştır doc. Bu nedenle, özyinelemeli olarak kopyalamak istiyorsanız, yine de kabuk / komut modülüne ihtiyacınız vardır.
klaas

23
Anlamıyorum. Kopyalama ve silme, taşıma ile aynı şey değildir. Birincisi, atomik değil. Bir diğeri için, özellikle büyük dosyalar için daha yavaştır. Ansible'da yeniyim, ama bu benim için gerçekten garip görünüyor.
mlissner

19
@alex dediğim şey bunu yapmanın doğru yolu olamaz. 50 şeye karşı rüzgara karşı çıkıyorum ama bu çılgınca. Başka bir sorun: izinler ve diğer özellikler korunmaz. Başka: Kopyalama sırasında dosya değiştirilirse ne olur ?
mlissner

2
@ Hamish Downer ve mlissner. Tüm ihtiyaçlarınız için en iyi çözüm olduğunu söylemedim. Ayrıca, birçok dosyayı kopyalamak istiyorsanız, kopya modülünü kullanmamanız gerektiğini yazdım. "Komut / kabuk görevlerini kullanmak istemiyorum" sorusunu okuyun.
Alex

7
@Alex bu, dosyaları yanlışlıkla taşıma ile ilgili bir soruya verilen en yüksek ikinci oylama cevabıdır. Soru kopyalamakla ilgili değil. Taşımak yerine kopyalamayla ilgili birçok sorun var, bu nedenle bu cevap yanlış. Bu yüzden bir aşağı oy alır. SO görgü kuralları downvotes açıklamaktır. Başka bir yerde belirtildiği gibi, şimdiye kadarki en iyi seçenekcommand: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Alec Wenzowski

106

Komut modülünde oluştur seçeneği yararlı buldum. Buna ne dersin:

- name: Move foo to bar
  command: creates="path/to/bar" mv /path/to/foo /path/to/bar

Bruce P'nin önerdiği gibi stat kullanarak 2 görev yaklaşımı yapardım. Şimdi bunu tek bir görev olarak yapıyorum. Bence bu çok daha net.


60
Veya daha da iyisi: command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Fonant

8

Benim için iyi çalışan bir başka seçenek de senkronizasyon modülünü kullanmaktır . Daha sonra dosya modülünü kullanarak orijinal dizini kaldırın.

İşte dokümanlardan bir örnek:

- synchronize:
    src: /first/absolute/path
    dest: /second/absolute/path
    archive: yes
  delegate_to: "{{ inventory_hostname }}"

Bu, her durumda yerel olarak çalışmaz çünkü destdizin aynı makinede olsa bile SSH üzerinden erişilir.
Karl Richter

5

Bunu başarmak için başka bir yol kullanıyor fileile state: hard.

Bu benim çalışmam gereken bir örnek:

- name: Link source file to another destination
  file:
    src: /path/to/source/file
    path: /target/path/of/file
    state: hard

Sadece localhost (OSX) üzerinde test edildi, ancak Linux üzerinde de çalışmalı. Windows için söyleyemem.

Mutlak yolların gerekli olduğunu unutmayın. Yoksa bağlantıyı oluşturmama izin vermedi. Ayrıca dosya sistemlerini geçemezsiniz, bu nedenle bağlı herhangi bir ortamla çalışmak başarısız olabilir.

Kaynak dosyayı daha sonra kaldırırsanız, sabit bağlantı taşınmaya çok benzer:

- name: Remove old file
  file:
    path: /path/to/source/file
    state: absent

Bir diğer avantaj ise, oyunun ortasındayken değişikliklerin devam etmesidir. Birisi kaynağı değiştirirse, herhangi bir değişiklik hedef dosyaya yansıtılır.

Yoluyla bir dosyaya bağlantı sayısını doğrulayabilirsiniz ls -l. Sabit bağlantı sayısı modun yanında gösterilir (örneğin, bir dosyada 2 bağlantı olduğunda rwxr-xr-x 2).


2
Sert bağlantılar (((dizinler için izin verilmez gibi Maalesef bu, bir dizin için çalışmaz
Drew

1
Bu cevap, hedef sistem hakkında, özellikle src ve dest'in aynı bölümde bulunduğunu varsayar. Bu doğru olmayabilir ve bu nedenle bu cevap kullanılmamalıdır.
mikky

4

Bruce, dosya zaten oradaysa taşınsın mı taşınmayacağını kontrol etmek için hedefi belirlemeye çalışmıyordu; mv denemeden önce taşınacak dosyanın gerçekten var olduğundan emin oluyordu.

Tom'unki gibi ilgi alanınız yalnızca dosya zaten yoksa hareket etmekse, Bruce'un kontrolünü karışıma entegre etmemiz gerektiğini düşünüyorum:

- name: stat foo
  stat: path=/path/to/foo
  register: foo_stat

- name: Move foo to bar
  command: creates="path/to/bar" mv /path/to/foo /path/to/bar
  when: foo_stat.stat.exists

3

Benim için çalışmasını sağladım:

  Tasks:
  - name: checking if the file 1 exists
     stat:      
      path: /path/to/foo abc.xts
     register: stat_result

  - name: moving file 1
    command: mv /path/to/foo abc.xts /tmp
    when: stat_result.stat.exists == True

Yukarıdaki oynatma kitabı, dosyayı tmp klasörüne taşımadan önce abc.xts dosyasının var olup olmadığını kontrol eder.


3
Kullanmanıza gerek yok when: stat_result.stat.exists == True. Sadece kullanmak when: stat_result.stat.existsyeterince iyi.
kuttumiah

Ben genellikle == Trueçünkü dosya bulunamadığı zaman bir şeyler yapıyorum çünkü == False.
eduprado

Modül özelliklerinin Resmi dokümantasyon sayfasınastat göre existsbir booleandeğer döndürür . Yani, sadece koyarsanız when: stat_result.stat.existsdosya için de aynı olan when: stat_result.stat.exists == Trueancak daha fazla metin ve gereksiz koşullu kontrol ile durumu karşılar .
kuttumiah

0

Bu aşırıya kaçmış gibi görünebilir, ancak komut modülünü kullanmaktan kaçınmak istiyorsanız (ki bunu yapmak, komut kullanmak idempotent olmadığı için) kopyala ve arşivden çıkarmayı kullanabilirsiniz.

  1. İhtiyacınız olan dosyaları arşivlemek için tar kullanın. Eğer ileriyi düşünüyorsanız, bu gerçekten mantıklı. Belirli bir dizinde bir dizi dosya isteyebilirsiniz. Bu dizini tüm dosyalarla oluşturun ve bir zift içinde arşivleyin.
  2. Arşivden çıkarma modülünü kullanın. Bunu yaptığınızda, destination: ve remote_src: anahtar sözcüğüyle birlikte, tüm dosyalarınızı kopyalamak için geçici bir klasöre yerleştirebilir ve ardından tam olarak istediğiniz yerde açabilirsiniz.

Katran ile arşivlemede herhangi bir idempotence yok
visit1985 15

0

Yapabilirsiniz -

Geçici Komutu Kullanma

ansible all -m command -a" mv /path/to/foo /path/to/bar"

Ya da playbook kullanarak yapmak istiyorsanız

- name: Move File foo to destination bar
  command: mv /path/to/foo /path/to/bar

0

Bu bir YIL eski konu olduğunu biliyorum , ama hayal kırıklığına uğradım ve keyfi bir dosya listesi için tam olarak bunu yapmak için bir rol inşa ettim. Uygun gördüğünüz şekilde genişletin:

main.yml

- name: created destination directory
  file:
    path: /path/to/directory
    state: directory
    mode: '0750'
- include_tasks: move.yml
  loop:
    - file1
    - file2
    - file3

move.yml

- name: stat the file
  stat:
    path: {{ item }}
  register: my_file

- name: hard link the file into directory
  file:
    src: /original/path/to/{{ item }}
    dest: /path/to/directory/{{ item }}
    state: hard
  when: my_file.stat.exists

- name: Delete the original file
  file:
    path: /original/path/to/{{ item }}
    state: absent
  when: my_file.stat.exists

Sabit bağlamanın burada kopyalamaya tercih edildiğine dikkat edin, çünkü mülkiyet ve izinleri doğal olarak korur (dosyanın ikinci bir kopyası için daha fazla disk alanı tüketmemeye ek olarak).


0

Windows'ta: - name: Move old folder to backup win_command: "cmd.exe /c move /Y {{ sourcePath }} {{ destinationFolderPath }}"

Yeniden adlandırmak için bunun yerine rename veya ren komutunu kullanın

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.