Cara memindahkan / mengganti nama file menggunakan tugas Ansible pada sistem jarak jauh


202

Bagaimana mungkin memindahkan / mengganti nama file / direktori menggunakan modul Ansible pada sistem jarak jauh? Saya tidak ingin menggunakan perintah / tugas shell dan saya tidak ingin menyalin file dari sistem lokal ke sistem jarak jauh.


Mengapa Anda tidak ingin menggunakan perintah / shell?
Nick Urban

4
Hanya ingin tahu apakah ada cara tanpa menggunakan tugas yang disebutkan. Sepertinya tidak ada cara lain saat ini.
Christian Berendt

1
Mengapa Anda ingin memindahkannya secara khusus daripada menyalinnya? Itu kelihatannya seperti tindakan satu kali, dan bukan jenis langkah sistem yang menjamin negara.
Nick Urban

2
Saya memiliki file konfigurasi sampel yang disertakan dalam paket RPM dan saya ingin memindahkan file konfigurasi sampel ini.
Christian Berendt

1
Saat ini saya menggunakan symlink untuk referensi file. Menggunakan get_url bukan pilihan bagi saya karena sistem tidak dapat menjangkau internet.
Christian Berendt

Jawaban:


201

Modul file tidak menyalin file di sistem jarak jauh. Parameter src hanya digunakan oleh modul file saat membuat symlink ke file.

Jika Anda ingin memindahkan / mengganti nama file seluruhnya pada sistem jarak jauh, maka cara terbaik Anda adalah menggunakan modul perintah untuk menjalankan perintah yang sesuai:

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

Jika Anda ingin menjadi mewah maka Anda dapat menggunakan modul stat terlebih dahulu untuk memeriksa apakah foo benar-benar ada:

- 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
Tanpa menggunakan modul perintah, satu-satunya pilihan Anda adalah menulis modul sendiri.
Bruce P

2
Ditandai sebagai jawaban yang benar karena ini adalah cara saat ini untuk menyalin file jarak jauh.
Christian Berendt

11
Mengenai melihat sebelum Anda melompat: apakah ada alasan untuk tidak menggunakan removesopsi ke commandmodul (didokumentasikan di sini )? Tampaknya opsi itu akan membuat Ansible memeriksa terlebih dahulu.
Jim Witschey

2
Jejak yang mungkin berubah untuk memberi tahu pawang, yang membuat solusi ini tidak optimal.
boh

3
Anda tidak perlu memeriksa keberadaan file secara manual jika Anda menggunakan removes: /path/to/foodan creates: /path/to/bar. @Fonant sudah menyebut ini sebagai komentar pada jawaban lain, tetapi karena ini adalah yang diterima, saya ingin menunjukkannya lagi.
Michael Trojanek

218

Dari versi 2.0 , dalam modul salin yang dapat Anda gunakanremote_src parameter.

Jika Trueitu akan pergi ke mesin remote / target untuk src.

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

Jika Anda ingin memindahkan file, Anda perlu menghapus file lama dengan modul file

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

Dari versi 2.8 modul copy remote_src mendukung penyalinan rekursif.


29
Komentar kecil: "Saat ini remote_src tidak mendukung penyalinan rekursif." diambil dari modul modul ansible. Jadi jika Anda ingin menyalin secara rekursif Anda masih memerlukan modul shell / command.
klaas

23
Saya tidak mengerti. Menyalin lalu menghapus tidak sama dengan memindahkan. Untuk satu, itu bukan atom. Untuk yang lain, ini lebih lambat, terutama untuk file besar. Saya baru mengenal Ansible, tetapi ini tampaknya sangat aneh bagi saya.
mlissner

19
@ alex apa yang saya katakan tidak bisa menjadi cara yang tepat untuk melakukan ini. Saya akan melawan angin melawan 50 sesuatu, tetapi ini gila. Masalah lain: izin dan atribut lainnya tidak dipertahankan. Lain: Bagaimana jika file diubah selama copy ?
mlissner

2
@Hamish Downer dan mlissner. Saya tidak mengatakan bahwa itu adalah solusi terbaik untuk semua kebutuhan Anda. Saya juga menulis bahwa jika Anda ingin menyalin banyak file Anda tidak boleh menggunakan modul copy. Baca pertanyaan "Saya tidak ingin menggunakan perintah / tugas shell".
Alex

7
@Alex, ini adalah jawaban pilihan tertinggi kedua pada pertanyaan tentang memindahkan file idempotently. Pertanyaannya bukan tentang menyalin. Ada banyak masalah dengan penyalinan alih-alih pindah karena itu jawaban ini salah. Jadi itu mendapat downvote. Etiket pada SO adalah untuk menjelaskan downvotes. Seperti disebutkan di tempat lain, pilihan terbaik sejauh ini adalahcommand: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Alec Wenzowski

106

Saya telah menemukan opsi create dalam modul perintah berguna. Bagaimana dengan ini:

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

Saya biasa melakukan pendekatan 2 tugas menggunakan stat seperti yang disarankan Bruce P. Sekarang saya melakukan ini sebagai satu tugas dengan menciptakan. Saya pikir ini jauh lebih jelas.


60
Atau, lebih baik lagi: command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Fonant

8

Opsi lain yang telah bekerja dengan baik untuk saya adalah menggunakan modul sinkronisasi . Kemudian hapus direktori asli menggunakan modul file.

Berikut ini adalah contoh dari dokumen:

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

Ini tidak berfungsi secara lokal dalam setiap kasus karena destdiakses melalui SSH bahkan jika direktori berada di mesin yang sama.
Karl Richter

5

Cara lain untuk mencapai ini adalah menggunakan filedengan state: hard.

Ini adalah contoh saya mulai bekerja:

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

Hanya diuji pada localhost (OSX), tetapi harus bekerja di Linux juga. Saya tidak tahu untuk Windows.

Perhatikan bahwa jalur absolut diperlukan. Jika tidak, saya tidak akan membuat tautan. Anda juga tidak dapat melewati sistem file, jadi bekerja dengan media yang dipasang mungkin gagal.

Hardlink sangat mirip dengan memindahkan, jika Anda menghapus file sumber setelahnya:

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

Manfaat lain adalah perubahan tetap ada saat Anda sedang bermain. Jadi, jika seseorang mengubah sumber, setiap perubahan tercermin dalam file target.

Anda dapat memverifikasi jumlah tautan ke suatu file melalui ls -l. Jumlah hardlink ditampilkan di sebelah mode (misalnya rwxr-xr-x 2, ketika file memiliki 2 tautan).


2
Sayangnya, ini tidak akan berfungsi untuk direktori, karena tautan keras tidak diizinkan untuk direktori (((
Drew

1
Jawaban ini membuat asumsi tentang sistem target, khususnya bahwa src dan dest berada di partisi yang sama. Ini mungkin tidak benar dan karena itu jawaban ini tidak boleh digunakan.
mikky

4

Bruce tidak berusaha menentukan tujuan untuk memeriksa apakah akan memindahkan file jika sudah ada di sana; dia memastikan file yang akan dipindahkan benar-benar ada sebelum mencoba mv.

Jika minat Anda, seperti minat Tom, hanya memindahkan jika file tersebut belum ada, saya pikir kita harus mengintegrasikan cek Bruce ke dalam campuran:

- 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

Ini adalah cara saya membuatnya bekerja untuk saya:

  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

playbook di atas, akan memeriksa apakah file abc.xts ada sebelum memindahkan file ke folder tmp.


3
Tidak perlu digunakan when: stat_result.stat.exists == True. Hanya menggunakan when: stat_result.stat.existscukup baik.
kuttumiah

Saya biasanya menggunakan == Truekarena saya selalu melakukan sesuatu ketika file tidak ditemukan atau == False.
eduprado

Menurut halaman dokumentasi resmistat exists properti modul mengembalikan booleannilai. Jadi, jika Anda hanya menempatkan when: stat_result.stat.existsitu akan memenuhi syarat jika file hadir yang juga identik when: stat_result.stat.exists == Truetetapi dengan lebih banyak teks dan pemeriksaan bersyarat yang tidak perlu.
kuttumiah

0

Ini mungkin terlihat seperti berlebihan, tetapi jika Anda ingin menghindari menggunakan modul perintah (yang saya lakukan, karena menggunakan perintah tidak idempoten), Anda dapat menggunakan kombinasi dari salinan dan tidak mengarsipkan.

  1. Gunakan tar untuk mengarsipkan file yang Anda butuhkan. Jika Anda berpikir ke depan, ini sebenarnya masuk akal. Anda mungkin menginginkan serangkaian file dalam direktori yang diberikan. Buat direktori itu dengan semua file dan arsipkan dalam tar.
  2. Gunakan modul unarchive. Ketika Anda melakukannya, bersama dengan tujuan: dan remote_src: kata kunci, Anda dapat menempatkan menyalin semua file Anda ke folder sementara untuk memulai dan kemudian membongkar mereka di tempat yang Anda inginkan.

Tidak ada idempotensi dalam pengarsipan dengan tar
visit1985

0

Anda dapat melakukannya dengan -

Menggunakan Perintah Ad Hoc

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

Atau Anda jika Anda ingin melakukannya dengan menggunakan playbook

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

0

Saya tahu ini adalah topik lama TAHUN , tetapi saya frustrasi dan membangun peran untuk diri saya sendiri untuk melakukan hal ini untuk daftar file yang sewenang-wenang. Perluas sesuai keinginan Anda:

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

Perhatikan bahwa tautan keras lebih disukai daripada menyalin di sini, karena itu secara inheren mempertahankan kepemilikan dan izin (selain tidak menggunakan lebih banyak ruang disk untuk salinan kedua file).


0

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

Untuk mengganti nama, gunakan ganti nama atau perintah ren

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.