Ansible Playbook解压归档后自定义目录或获取动态目录方法问询
解决Ansible解压动态命名目录后的路径问题
这问题我之前在部署类似版本化归档包时也碰到过,给你三个实用的解决方案,按推荐优先级排序:
1. 直接指定自定义目标目录(最省心)
如果你的需求只是让解压后的目录名称固定,完全可以在解压时通过unarchive模块的extra_opts参数,利用tar的--transform选项重命名目录。这样后续任务直接用固定路径就行,不用处理变量。
示例Playbook:
- name: Unarchive Installation with fixed directory name become: yes unarchive: src: "/opt/dist-{{ version }}.tar" dest: /opt/ remote_src: yes # 使用tar的--transform参数重命名解压后的目录 extra_opts: - "--transform" - "s/^oa-{{ version }}-.*/oa-{{ version }}/" when: inventory_hostname == ip_address - name: Run Installation with fixed path become: yes command: 'python install.py --modules="Platform" --username admin --password pass --repo-base-url="http://download.com/oa/{{ version }}/repo"' args: chdir: "/opt/oa-{{ version }}/"
解释:--transform是tar的内置选项,这里用正则把解压出来的oa-{{ version }}-xxxx目录统一重命名为oa-{{ version }},完全避开动态数字的问题。
2. 动态查找并注册解压后的目录路径
如果不能修改解压后的目录名称,可以在解压完成后用find模块查找目标目录,把路径注册为变量供后续任务使用。
示例Playbook:
- name: Unarchive Installation become: yes unarchive: src: "/opt/dist-{{ version }}.tar" dest: /opt/ remote_src: yes when: inventory_hostname == ip_address - name: Find the extracted OA directory become: yes find: path: /opt/ patterns: "oa-{{ version }}-*" file_type: directory recurse: no register: oa_directory_result when: inventory_hostname == ip_address - name: Run Installation with dynamic path become: yes command: 'python install.py --modules="Platform" --username admin --password pass --repo-base-url="http://download.com/oa/{{ version }}/repo"' args: chdir: "{{ oa_directory_result.files[0].path }}" when: inventory_hostname == ip_address and oa_directory_result.files | length > 0
解释:find模块会查找/opt下所有以oa-{{ version }}-开头的目录,结果存在oa_directory_result里,后续任务直接取第一个匹配的目录路径即可。加上length > 0的判断是为了避免找不到目录时报错。
3. 利用unarchive模块的返回结果提取路径(Ansible 2.10+)
如果你用的是Ansible 2.10及以上版本,unarchive模块会返回解压后的所有文件/目录列表。可以通过过滤这个结果提取目标目录的路径,不需要额外执行find任务。
示例Playbook:
- name: Unarchive Installation and get directory path become: yes unarchive: src: "/opt/dist-{{ version }}.tar" dest: /opt/ remote_src: yes register: unarchive_result when: inventory_hostname == ip_address - name: Set extracted OA directory path as variable become: yes set_fact: oa_install_dir: "{{ unarchive_result.files | selectattr('path', 'search', '^/opt/oa-' ~ version ~ '-') | selectattr('isdir', 'equalto', true) | map(attribute='path') | first }}" when: inventory_hostname == ip_address and unarchive_result.files | length > 0 - name: Run Installation with extracted path become: yes command: 'python install.py --modules="Platform" --username admin --password pass --repo-base-url="http://download.com/oa/{{ version }}/repo"' args: chdir: "{{ oa_install_dir }}" when: inventory_hostname == ip_address and oa_install_dir is defined
解释:unarchive_result.files包含了所有解压出来的条目,我们用selectattr过滤出符合命名规则的目录,再提取路径作为变量。这个方法少执行一次远程任务,效率更高,但依赖较新的Ansible版本。
内容的提问来源于stack exchange,提问作者overflowed
相关产品推荐
相关产品推荐

