Как можно переместить / переименовать файл / каталог с помощью модуля Ansible в удаленной системе? Я не хочу использовать задачи команды / оболочки и не хочу копировать файл из локальной системы в удаленную систему.
Как можно переместить / переименовать файл / каталог с помощью модуля Ansible в удаленной системе? Я не хочу использовать задачи команды / оболочки и не хочу копировать файл из локальной системы в удаленную систему.
Ответы:
Файловый модуль не копирует файлы в удаленной системе. Параметр src используется файловым модулем только при создании символической ссылки на файл.
Если вы хотите переместить / переименовать файл полностью в удаленной системе, тогда вам лучше всего использовать командный модуль, чтобы просто вызвать соответствующую команду:
- name: Move foo to bar
command: mv /path/to/foo /path/to/bar
Если вы хотите получить фантазию, вы можете сначала использовать модуль stat, чтобы убедиться, что foo действительно существует:
- 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
removes
опцию для command
модуля (задокументировано здесь )? Похоже, что эта опция сначала сделает проверку Ansible.
removes: /path/to/foo
и creates: /path/to/bar
. @Fonant уже упомянул это как комментарий к другому ответу, но так как он принят, я хочу еще раз указать на это.
Начиная с версии 2.0 , в модуле копирования вы можете использовать remote_src
параметр.
Если True
это пойдет на удаленный / целевой компьютер для src.
- name: Copy files from foo to bar
copy: remote_src=True src=/path/to/foo dest=/path/to/bar
Если вы хотите переместить файл, вам нужно удалить старый файл с файловым модулем
- name: Remove old files foo
file: path=/path/to/foo state=absent
Начиная с версии 2.8 модуль копирования remote_src
поддерживает рекурсивное копирование.
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Я нашел параметр create в командном модуле полезным. Как насчет этого:
- name: Move foo to bar
command: creates="path/to/bar" mv /path/to/foo /path/to/bar
Я использовал подход с двумя задачами, используя stat, как предлагает Брюс П. Теперь я делаю это как одно задание с create. Я думаю, что это намного понятнее.
command: mv /path/to/foo /path/to/bar creates=/path/to/bar removes=/path/to/foo
Еще один вариант, который хорошо работает для меня, - это использование модуля синхронизации . Затем удалите исходный каталог с помощью файлового модуля.
Вот пример из документации:
- synchronize:
src: /first/absolute/path
dest: /second/absolute/path
archive: yes
delegate_to: "{{ inventory_hostname }}"
dest
доступ через SSH, даже если каталог находится на той же машине.
Еще один способ добиться этого - использовать file
с state: hard
.
Это пример, который я получил на работу:
- name: Link source file to another destination
file:
src: /path/to/source/file
path: /target/path/of/file
state: hard
Только проверено на localhost (OSX), но должно работать и на Linux. Я не могу сказать для Windows.
Обратите внимание, что необходимы абсолютные пути. Иначе это не позволило бы мне создать ссылку. Также вы не можете пересекать файловые системы, поэтому работа с любым подключенным носителем может не получиться.
Жесткая ссылка очень похожа на перемещение, если впоследствии удалить исходный файл:
- name: Remove old file
file:
path: /path/to/source/file
state: absent
Еще одним преимуществом является то, что изменения сохраняются, когда вы находитесь в середине игры. Поэтому, если кто-то изменяет источник, любое изменение отражается в целевом файле.
Вы можете проверить количество ссылок на файл через ls -l
. Количество жестких ссылок отображается рядом с режимом (например, rwxr-xr-x 2, когда файл имеет 2 ссылки).
Брюс не пытался определить пункт назначения, чтобы проверить, перемещать ли файл, если он уже был там; он следил за тем, чтобы файл, который нужно переместить, действительно существовал, прежде чем пытаться запустить mv.
Если ваш интерес, как и у Тома, состоит в том, чтобы перемещаться, только если файл еще не существует, я думаю, что мы все равно должны интегрировать чек Брюса в микс:
- 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
Вот так у меня это получилось:
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, проверит, существует ли файл abc.xts, перед тем как переместить файл в папку tmp.
when: stat_result.stat.exists == True
. Просто использовать when: stat_result.stat.exists
достаточно хорошо.
== True
потому что я всегда что-то делаю, когда файл не найден или == False
.
stat
exists
свойства модуля возвращают boolean
значение. Таким образом, если вы только поставите, when: stat_result.stat.exists
это будет удовлетворять условию, если файл присутствует, который также идентичен, when: stat_result.stat.exists == True
но с большим количеством текстов и ненужной условной проверкой.
Это может показаться излишним, но если вы хотите избежать использования командного модуля (что я и делаю, потому что использование команды не идемпотентно), вы можете использовать комбинацию копирования и разархивирования.
Вы можете сделать это путем -
Использование специальной команды
ansible all -m command -a" mv /path/to/foo /path/to/bar"
Или вы, если вы хотите сделать это с помощью playbook
- name: Move File foo to destination bar
command: mv /path/to/foo /path/to/bar
Я знаю, что это старая тема ЛЕТ , но я разочаровался и создал для себя роль, которая сделает именно это для произвольного списка файлов. Расширьте, как считаете нужным:
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
Обратите внимание, что жесткое связывание здесь предпочтительнее, чем копирование, поскольку оно по своей природе сохраняет владение и разрешения (в дополнение к тому, что не занимает больше места на диске для второй копии файла).