如果尚未创建父目录,则Ansible同步失败

Ansible synchronise fails if parent directories are not already created

我在Ansible中有一个同步任务:

1
2
3
4
5
---
- name: Copy over code - lib
  synchronize:
    src: ../lib/some/parent/directories/
    dest: ~/project/lib/some/parent/directories/

这失败了,因为目的地缺少~/project/lib/some/parent/,但成功了。我做了以下工作:

1
2
3
4
5
6
7
8
9
10
11
---
- set_fact:
    directory_lib_dest: ~/project/lib/some/parent/directories/
- name: Create directories
  file: path={{ item }} state=directory
  with_items:
    -"{{ directory_lib_dest }}"
- name: Copy over code - lib
  synchronize:
    src: ../lib/some/parent/directories/
    dest:"{{ directory_lib_dest }}"

有没有更好的解决方案可以使用soley的ansible synchronize模块来完成,或者避免我使用set_fact,同时保持它的干燥和变量声明在同一个角色中。YML正在消费它?


这就是rsync的工作原理。但是你可以在这里读到解决方法。

如果你要采用点斜线技巧的relative行为,记住你应该在ansible中通过完整路径到达src(否则ansible将自己扩展它,你的/./技巧将被消除)。

如果您需要重新创建lib/some/parent/directories/,您的任务可能如下所示:

在实际使用前进行测试!

1
2
3
4
5
- synchronize:
    src: '{{ playbook_dir }}/./lib/some/parent/directories/'
    dest: ~/project/
    rsync_opts:
      - '--relative'

正如我所说,src: .././lib/some/parent/dir将不起作用,我们需要完整的路径(所以我使用playbook_dir魔法变量)。

摘自rsync手册页关于relative的内容:

To limit the amount of path information that is sent, you have a couple options: (1) With
a modern rsync on the sending side (beginning with 2.6.7), you can insert a dot and a slash into the
source path, like this: rsync -avR /foo/./bar/baz.c remote:/tmp/


非常感谢康斯坦丁的回答,我最终使用了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
- name: Set name of local and remote project directory
  set_fact:
    LOCAL_PROJECT_DIRECTORY: "{{ playbook_dir | dirname }}"
    REMOTE_PROJECT_DIRECTORY:"{{ ansible_env.HOME }}/project-remote-dir/"
- name: Create remote project directory {{ REMOTE_PROJECT_DIRECTORY }}
  file: path={{ REMOTE_PROJECT_DIRECTORY }} state=directory
- name: Copy over code
  synchronize:
    src:"{{ LOCAL_PROJECT_DIRECTORY }}/./{{ item }}"
    dest:"{{ REMOTE_PROJECT_DIRECTORY }}"
    rsync_opts:
      -"--relative"
  with_items:
    - lib/some/parent/directories/
    - src/some/other/directories/

LOCAL_PROJECT_DIRECTORYplaybook_dirdirname作为项目结构如下:

1
2
3
4
5
6
7
8
9
myproject
    deploy
        playbook.yml
        roles
             etc...
    lib
        etc...
    src
        etc...

这是双重的好处,因为它消除了重复的some/parent/directories,使一切更加明确。