Jak przenieść / zmienić nazwę pliku za pomocą zadania Ansible w systemie zdalnym
202
Jak można przenieść / zmienić nazwę pliku / katalogu za pomocą modułu Ansible w systemie zdalnym? Nie chcę używać zadań polecenia / powłoki i nie chcę kopiować pliku z systemu lokalnego do systemu zdalnego.
Chciałem tylko wiedzieć, czy istnieje sposób bez korzystania ze wspomnianych zadań. Wygląda na to, że w tej chwili nie ma innego wyjścia.
Christian Berendt
1
Dlaczego chcesz go specjalnie przenieść, a nie skopiować? To wydaje się być działaniem jednorazowym, a nie idempotentnym krokiem zapewniającym stan systemu.
Nick Urban
2
Mam przykładowy plik konfiguracyjny zawarty w pakiecie RPM i chcę przenieść ten przykładowy plik konfiguracyjny.
Christian Berendt,
1
W tej chwili używam dowiązania symbolicznego do odwołania do pliku. Korzystanie z get_url nie jest dla mnie opcją, ponieważ system nie może połączyć się z Internetem.
Christian Berendt,
Odpowiedzi:
201
Moduł plików nie kopiuje plików w systemie zdalnym. Parametr src jest używany tylko przez moduł pliku podczas tworzenia dowiązania symbolicznego do pliku.
Jeśli chcesz przenieść / zmienić nazwę pliku w całości na zdalnym systemie, najlepiej jest użyć modułu poleceń, aby po prostu wywołać odpowiednie polecenie:
- name: Move foo to bar
command: mv /path/to/foo /path/to/bar
Jeśli chcesz się spodobać, możesz najpierw użyć modułu statystyk, aby sprawdzić, czy foo faktycznie istnieje:
- 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
Bez korzystania z modułu poleceń jedynym wyborem byłoby napisanie własnego modułu niestandardowego.
Bruce P,
2
Oznaczono jako poprawną odpowiedź, ponieważ jest to obecny sposób kopiowania plików zdalnych.
Christian Berendt
11
Jeśli chodzi o patrzenie przed skokiem: czy jest jakiś powód, aby nie korzystać z removesopcji commandmodułu ( tutaj udokumentowane )? Wygląda na to, że ta opcja sprawi, że najpierw sprawdzimy Ansible.
Jim Witschey
2
Ansible śledzi zmiany, aby powiadomić program obsługi, co powoduje, że to rozwiązanie nie jest optymalne.
boh
3
Nie musisz ręcznie sprawdzać istnienia pliku, jeśli używasz removes: /path/to/fooi creates: /path/to/bar. @Fonant już wspomniał o tym jako komentarz do innej odpowiedzi, ale ponieważ jest to zaakceptowana, chcę to jeszcze raz podkreślić.
Mała uwaga: „Obecnie remote_src nie obsługuje kopiowania rekurencyjnego”. zaczerpnięte z modułu ansible doc. Więc jeśli chcesz kopiować rekurencyjnie, nadal potrzebujesz powłoki / modułu poleceń.
klaas
23
Nie rozumiem. Kopiowanie, a następnie usuwanie nie jest tym samym, co przenoszenie. Po pierwsze, nie jest atomowy. Po drugie, jest wolniejszy, szczególnie w przypadku dużych plików. Jestem nowy w Ansible, ale wydaje mi się to dziwne.
mlissner,
19
@alex to, co mówię, nie może być dobrym sposobem na zrobienie tego. Idę pod wiatr przeciw 50 głosom pozytywnym, ale to szalone. Kolejny problem: uprawnienia i inne atrybuty nie są utrzymywane. Kolejne: co jeśli plik zostanie zmieniony podczas kopiowania ?
mlissner
2
@Hamish Downer i mlissner. Nie powiedziałem, że to najlepsze rozwiązanie dla wszystkich twoich potrzeb. Napisałem również, że jeśli chcesz skopiować wiele plików, nie powinieneś używać modułu kopiowania. Przeczytaj pytanie „Nie chcę używać poleceń / zadań powłoki”.
Alex
7
@Alex jest to druga najwyżej głosowana odpowiedź na pytanie dotyczące idempotentnego przenoszenia plików. Pytanie nie dotyczy kopiowania. Istnieje wiele problemów z kopiowaniem zamiast przenoszenia, dlatego ta odpowiedź jest niepoprawna. Więc dostaje opinię negatywną. Etykieta dotycząca SO ma na celu wyjaśnienie głosów negatywnych. Jak wspomniano gdzie indziej, najlepszą jak dotąd opcją jestcommand: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Alec Wenzowski
106
Uważam, że opcja create w module poleceń jest przydatna. Co powiesz na to:
- name: Move foo to bar
command: creates="path/to/bar" mv /path/to/foo /path/to/bar
Kiedyś stosowałem podejście z dwoma zadaniami, używając statystyk, jak sugeruje Bruce P. Teraz robię to jako jedno zadanie z tworzeniem. Myślę, że jest to o wiele wyraźniejsze.
To nie działa lokalnie w każdym przypadku, ponieważ destjest dostępne przez SSH, nawet jeśli katalog znajduje się na tym samym komputerze.
Karl Richter
5
Innym sposobem na osiągnięcie tego jest użycie filez state: hard.
Oto przykład, który mam do pracy:
- name: Link source file to another destination
file:
src: /path/to/source/file
path: /target/path/of/file
state: hard
Testowany tylko na localhost (OSX), ale powinien również działać na Linuksie. Nie mogę powiedzieć dla Windows.
Pamiętaj, że potrzebne są ścieżki bezwzględne. W przeciwnym razie nie pozwoli mi to utworzyć linku. Nie można także krzyżować systemów plików, więc praca z dowolnym zamontowanym nośnikiem może się nie powieść.
Hardlink jest bardzo podobny do przenoszenia, jeśli później usuniesz plik źródłowy:
- name: Remove old file
file:
path: /path/to/source/file
state: absent
Kolejną korzyścią jest to, że zmiany są utrzymywane, gdy jesteś w trakcie gry. Jeśli więc ktoś zmieni źródło, każda zmiana zostanie odzwierciedlona w pliku docelowym.
Możesz sprawdzić liczbę linków do pliku poprzez ls -l. Liczba twardych dowiązań jest pokazana obok trybu (np. Rwxr-xr-x 2, gdy plik ma 2 dowiązania).
Niestety, to nie zadziała w przypadku katalogu, ponieważ twarde linki nie są dozwolone w przypadku katalogów (((
Drew
1
Ta odpowiedź zakłada założenie o systemie docelowym, w szczególności, że zarówno src, jak i dest znajdują się na tej samej partycji. To może nie być prawda i dlatego nie należy używać tej odpowiedzi.
mikky
4
Bruce nie próbował statystykować miejsca docelowego, aby sprawdzić, czy przenieść plik, jeśli już tam był; upewniał się, że plik, który ma zostać przeniesiony, faktycznie istniał przed próbą wykonania mv.
Jeśli twoim zainteresowaniem, podobnie jak Toma, jest przeniesienie się tylko wtedy, gdy plik jeszcze nie istnieje, myślę, że nadal powinniśmy zintegrować czek Bruce'a z miksem:
- 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
Nie musisz używać when: stat_result.stat.exists == True. Samo używanie when: stat_result.stat.existsjest wystarczająco dobre.
kuttumiah
Zwykle używam, == Trueponieważ zawsze coś robię, gdy nie można znaleźć pliku lub == False.
eduprado,
Zgodnie z oficjalną dokumentacją stronastatexists właściwości modułu zwraca booleanwartość. Tak więc, jeśli wstawisz when: stat_result.stat.exists, spełni warunek, jeśli plik jest obecny, który jest identyczny, when: stat_result.stat.exists == Trueale zawiera więcej tekstów i niepotrzebne sprawdzenie warunkowe.
kuttumiah
0
Może się to wydawać przesadą, ale jeśli chcesz uniknąć używania modułu poleceń (co robię, ponieważ użycie polecenia nie jest idempotentne), możesz użyć kombinacji kopiowania i archiwizacji.
Użyj tar do zarchiwizowania potrzebnych plików. Jeśli myślisz z wyprzedzeniem, ma to sens. Możesz chcieć serii plików w danym katalogu. Utwórz ten katalog ze wszystkimi plikami i zarchiwizuj je w pliku tar.
Użyj modułu archiwizującego. Gdy to zrobisz, wraz ze słowem kluczowym destination: i remote_src:, możesz skopiować wszystkie pliki do folderu tymczasowego, aby rozpocząć, a następnie rozpakować je dokładnie tam, gdzie chcesz.
Wiem, że to stary LATOWY temat, ale denerwowałem się i stworzyłem dla siebie rolę, aby robić to dokładnie na dowolnej liście plików. Rozszerz według własnego uznania:
- 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
Pamiętaj, że twarde linkowanie jest lepsze niż kopiowanie tutaj, ponieważ z natury zachowuje własność i uprawnienia (oprócz tego, że nie zajmuje więcej miejsca na dysku dla drugiej kopii pliku).
Odpowiedzi:
Moduł plików nie kopiuje plików w systemie zdalnym. Parametr src jest używany tylko przez moduł pliku podczas tworzenia dowiązania symbolicznego do pliku.
Jeśli chcesz przenieść / zmienić nazwę pliku w całości na zdalnym systemie, najlepiej jest użyć modułu poleceń, aby po prostu wywołać odpowiednie polecenie:
Jeśli chcesz się spodobać, możesz najpierw użyć modułu statystyk, aby sprawdzić, czy foo faktycznie istnieje:
źródło
removes
opcjicommand
modułu ( tutaj udokumentowane )? Wygląda na to, że ta opcja sprawi, że najpierw sprawdzimy Ansible.removes: /path/to/foo
icreates: /path/to/bar
. @Fonant już wspomniał o tym jako komentarz do innej odpowiedzi, ale ponieważ jest to zaakceptowana, chcę to jeszcze raz podkreślić.Od wersji 2.0 w module kopiowania można użyć
remote_src
parametru.Jeśli
True
przejdzie do zdalnego / docelowego komputera dla src.Jeśli chcesz przenieść plik, musisz usunąć stary plik za pomocą modułu plików
Od wersji 2.8 moduł kopiowania
remote_src
obsługuje kopiowanie rekurencyjne.źródło
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Uważam, że opcja create w module poleceń jest przydatna. Co powiesz na to:
Kiedyś stosowałem podejście z dwoma zadaniami, używając statystyk, jak sugeruje Bruce P. Teraz robię to jako jedno zadanie z tworzeniem. Myślę, że jest to o wiele wyraźniejsze.
źródło
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Inną opcją, która działała dla mnie dobrze, jest użycie modułu synchronizacji . Następnie usuń oryginalny katalog za pomocą modułu plików.
Oto przykład z dokumentów:
źródło
dest
jest dostępne przez SSH, nawet jeśli katalog znajduje się na tym samym komputerze.Innym sposobem na osiągnięcie tego jest użycie
file
zstate: hard
.Oto przykład, który mam do pracy:
Testowany tylko na localhost (OSX), ale powinien również działać na Linuksie. Nie mogę powiedzieć dla Windows.
Pamiętaj, że potrzebne są ścieżki bezwzględne. W przeciwnym razie nie pozwoli mi to utworzyć linku. Nie można także krzyżować systemów plików, więc praca z dowolnym zamontowanym nośnikiem może się nie powieść.
Hardlink jest bardzo podobny do przenoszenia, jeśli później usuniesz plik źródłowy:
Kolejną korzyścią jest to, że zmiany są utrzymywane, gdy jesteś w trakcie gry. Jeśli więc ktoś zmieni źródło, każda zmiana zostanie odzwierciedlona w pliku docelowym.
Możesz sprawdzić liczbę linków do pliku poprzez
ls -l
. Liczba twardych dowiązań jest pokazana obok trybu (np. Rwxr-xr-x 2, gdy plik ma 2 dowiązania).źródło
Bruce nie próbował statystykować miejsca docelowego, aby sprawdzić, czy przenieść plik, jeśli już tam był; upewniał się, że plik, który ma zostać przeniesiony, faktycznie istniał przed próbą wykonania mv.
Jeśli twoim zainteresowaniem, podobnie jak Toma, jest przeniesienie się tylko wtedy, gdy plik jeszcze nie istnieje, myślę, że nadal powinniśmy zintegrować czek Bruce'a z miksem:
źródło
Oto jak działam dla mnie:
powyższy podręcznik sprawdzi, czy plik abc.xts istnieje przed przeniesieniem pliku do folderu tmp.
źródło
when: stat_result.stat.exists == True
. Samo używaniewhen: stat_result.stat.exists
jest wystarczająco dobre.== True
ponieważ zawsze coś robię, gdy nie można znaleźć pliku lub== False
.stat
exists
właściwości modułu zwracaboolean
wartość. Tak więc, jeśli wstawiszwhen: stat_result.stat.exists
, spełni warunek, jeśli plik jest obecny, który jest identyczny,when: stat_result.stat.exists == True
ale zawiera więcej tekstów i niepotrzebne sprawdzenie warunkowe.Może się to wydawać przesadą, ale jeśli chcesz uniknąć używania modułu poleceń (co robię, ponieważ użycie polecenia nie jest idempotentne), możesz użyć kombinacji kopiowania i archiwizacji.
źródło
Możesz to zrobić przez -
Za pomocą polecenia Ad Hoc
Lub Ty, jeśli chcesz to zrobić, korzystając z poradnika
źródło
Wiem, że to stary LATOWY temat, ale denerwowałem się i stworzyłem dla siebie rolę, aby robić to dokładnie na dowolnej liście plików. Rozszerz według własnego uznania:
main.yml
move.yml
Pamiętaj, że twarde linkowanie jest lepsze niż kopiowanie tutaj, ponieważ z natury zachowuje własność i uprawnienia (oprócz tego, że nie zajmuje więcej miejsca na dysku dla drugiej kopii pliku).
źródło
W systemie Windows:
- name: Move old folder to backup win_command: "cmd.exe /c move /Y {{ sourcePath }} {{ destinationFolderPath }}"
Aby zmienić nazwę, użyj zamiast tego polecenia rename lub ren
źródło