FileNotFoundError:[错误2]没有这样的文件或目录:Ansible

问题描述

我是Ansible的新手,在这里我创建了一个将CSV作为参数的模块,如下所示:但是它不断抛出错误,即找不到CSV_TEST.csv文件。我是否可以在ansible模块中以正确的方式创建它作为变量?

module.py

def main():
    field = dict(
        csv=dict(type='str',required=True)
    )

    result = dict(
        changed=False,response='')

    module = AnsibleModule(argument_spec=field)

    csvFile = module.params['csv']

    listFinal = list()
    final = list()

    if csvFile:
        with open(csvFile,"r",newline='',encoding='utf-8-sig') as csvImport:
            reader = csv.DictReader(csvImport)
            for row in reader:
                newDict = dict({
                    'name': row.get("Name"),'address': row.get("Address")
                    'val': row.get("Val")
                })
                listFinal.append(newDict)


    if listFinal:
        for entry in listFinal:
            if entry.get("val") == "Incorrect":
                name = entry.get('name')
                add = entry.get('address')
                update = f'set add {add} of {name}'

                final.append(update)

        result['final'] = final

    module.exit_json(changed=False,Meta=result)


if __name__ == '__main__':
    main()

Playbook.yml

---
- name: Test Variables with Ansible
  hosts: localhost
  vars:
    x: 30
    xName: "Sai"
  gather_facts: false
  become: false
  tasks:
    - name: Test Device Validation
      portDescription:
        csv: CSV_TEST.csv
      register: result

    - debug: var=result

错误是:

***
FileNotFoundError: [Errno 2] No such file or directory: 'CSV_TEST.csv'
fatal: [localhost]: Failed! => {
    "changed": false,"module_stderr": "Shared connection to localhost closed.\r\n",***

有人可以建议我在这里做错什么吗? CSV_TEST.csv与Playbook.yml位于同一树形结构(父文件夹)下

解决方法

我认为,如果您在Ansible中有一个相对的文件路径,则Ansible首先会在本地目录中查找(如果您从ansible运行则输出该目录),然后它将在其他位置查找(请查看{ {3}},以获取更多信息。

所以在我看来,您的目录结构就像

WorkingDir
|- playbook.yml
|- Ansible
   |- CSV_TEST.csv

我认为您在ansible-playbook playbook.yml内部像WorkingDir一样运行ansible。它找不到CSV_TEST.csv,因为它在WorkingDir中寻找。

如果在python内部,您必须放置Ansible/CSV_TEST.csv到您的剧本中。所以

Ansible/CSV_TEST.csv

如果这无济于事,那么您能以文本格式写出目录结构并显示所有内容从何处执行以及python在何处运行(--- - name: Test Variables with Ansible hosts: localhost vars: x: 30 xName: "Sai" gather_facts: false become: false tasks: - name: Test Device Validation portDescription: csv: Ansible/CSV_TEST.csv register: result - debug: var=result 输出什么)?

,

一旦我修正了以上评论中报告的问题,您的代码就不会再出现其他问题。可能存在逻辑问题(但我不知道确切的期望是什么)。目前,这是一个证明运行,它可以按照我在您的模块代码中可以读取的预期运行。下面的路径都与我从中启动剧本的当前工作目录有关。

存储在./library/port_description.py

中的模块
#!/usr/bin/python
from ansible.module_utils.basic import *
import csv

def main():
    field = dict(
        csv=dict(type='str',required=True)
    )

    result = dict(
        changed=False,response='')

    module = AnsibleModule(argument_spec=field)

    csvFile = module.params['csv']

    listFinal = list()
    final = list()

    if csvFile:
        with open(csvFile,"r",newline='',encoding='utf-8-sig') as csvImport:
            module.debug("csv openned")
            reader = csv.DictReader(csvImport)
            for row in reader:
                newDict = dict({
                    'name': row.get("Name"),'address': row.get("Address"),'val': row.get("Val")
                })
                listFinal.append(newDict)

    if listFinal:
        for entry in listFinal:
            if entry.get("val") == "Incorrect":
                name = entry.get('name')
                add = entry.get('address')
                update = f'set add {add} of {name}'

                final.append(update)

        result['final'] = final

    module.exit_json(changed=False,meta=result)


if __name__ == '__main__':
    main()

存储在./CSV_TEST.csv中的csv文件(试图创建与预期名称和python代码对齐的文件...)

Name,Address,Val
toto,127.0.0.1,3
titi,192.168.0.1,Incorrect

该剧本存储在./test.yml

---
- name: Use a custom module reading csv file
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Use our module and register result
      port_description:
        csv: CSV_TEST.csv
      register: port_result

    - name: Show the result
      debug:
        var: port_result

结果:

$ ansible-playbook test.yml 

PLAY [Use a custom module reading csv file] ********************************************************************************************************************************************************************************************

TASK [Use our module and register result] **********************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show the result] *****************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "port_result": {
        "changed": false,"failed": false,"meta": {
            "changed": false,"final": [
                "set add 192.168.0.1 of titi"
            ],"response": ""
        }
    }
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

请注意,如果我从预期位置删除给定的CSV文件,则可以轻松重现您的确切问题:

$ mv CSV_TEST.csv CSV_TEST.csv.BAK
$ ansible-playbook test.yml 

PLAY [Use a custom module reading csv file] ********************************************************************************************************************************************************************************************

TASK [Use our module and register result] **********************************************************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback,use -vvv. The error was: FileNotFoundError: [Errno 2] No such file or directory: 'CSV_TEST.csv'
fatal: [localhost]: FAILED! => {"changed": false,"module_stderr": "Traceback (most recent call last):\n  File \"/home/user/.ansible/tmp/ansible-tmp-1602932173.7323837-24457-268203592954263/AnsiballZ_port_description.py\",line 102,in <module>\n    _ansiballz_main()\n  File \"/home/user/.ansible/tmp/ansible-tmp-1602932173.7323837-24457-268203592954263/AnsiballZ_port_description.py\",line 94,in _ansiballz_main\n    invoke_module(zipped_mod,temp_path,ANSIBALLZ_PARAMS)\n  File \"/home/user/.ansible/tmp/ansible-tmp-1602932173.7323837-24457-268203592954263/AnsiballZ_port_description.py\",line 40,in invoke_module\n    runpy.run_module(mod_name='ansible.modules.port_description',init_globals=None,run_name='__main__',alter_sys=True)\n  File \"/usr/lib/python3.6/runpy.py\",line 205,in run_module\n    return _run_module_code(code,init_globals,run_name,mod_spec)\n  File \"/usr/lib/python3.6/runpy.py\",line 96,in _run_module_code\n    mod_name,mod_spec,pkg_name,script_name)\n  File \"/usr/lib/python3.6/runpy.py\",line 85,in _run_code\n    exec(code,run_globals)\n  File \"/tmp/ansible_port_description_payload_6v82vnu_/ansible_port_description_payload.zip/ansible/modules/port_description.py\",line 48,in <module>\n  File \"/tmp/ansible_port_description_payload_6v82vnu_/ansible_port_description_payload.zip/ansible/modules/port_description.py\",line 22,in main\nFileNotFoundError: [Errno 2] No such file or directory: 'CSV_TEST.csv'\n","module_stdout": "","msg": "MODULE FAILURE\nSee stdout/stderr for the exact error","rc": 1}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0