使用ansible-python模块运行playbook时,'NoneType'对象没有属性'upper'?

时间:2017-09-07 13:49:11

标签: python python-2.7 ansible

这是代码,

task

输出就像:

class AnsibleRunner:

    def __init__(self):
        self.variable_manager = VariableManager()
        self.loader = DataLoader()
        self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager)
        Options = namedtuple('Options', ['listtags', 'listtasks', 'listhosts', 'syntax', 'connection','module_path', 'forks', 'remote_user', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args', 'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check'])
        self.options = Options(listtags=False, listtasks=False, listhosts=True, syntax=False, connection='ssh', module_path=None, forks=100, remote_user='ubuntu', private_key_file=os.getcwd()+"/private-key.pem", ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=False, become_method=None, become_user='root', verbosity=None, check=False)


    def execute_playbook(self, playbook, host, scriptname=None, command=None,
                         path=None, username=None, password=None, key=None):
        playbook_path = os.getcwd() + '/playbooks/'+playbook

        if not os.path.exists(playbook_path):
            print '[INFO] The playbook does not exist'
            sys.exit()

        script_path = None
        if scriptname is not None:
            script_path = os.getcwd() + '/' + scriptname
            if not os.path.exists(script_path):
                print '[INFO] The script does not exist'
                sys.exit()
        play_source = self.loader.load_from_file(playbook_path)
        play = Play().load(play_source[0], self.variable_manager, self.loader)
        self.variable_manager.extra_vars = {'scriptname': script_path,
                            'host': host, 'command': command, 'path': path} 

        passwords = {}
        if password is not None:
            self.loader.set_vault_password(password)

        callback = CallbackModule()
        tqm = TaskQueueManager(
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            options=self.options,
            passwords=passwords,
            stdout_callback=callback
        )

        result = tqm.run(play)
        print result

我尝试调试代码,因此会因为我问的原因而放置主机失败的位置。

PLAY [110.110.112.139]

TASK [Gathering Facts]

AttributeError: 'NoneType' object has no attribute 'upper'

fatal: [110.110.112.139]: FAILED! => {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""}

/usr/lib/python2.7/dist-packages/ansible/plugins/strategy/linear.py(387)运行()

 display.debug("checking for any_errors_fatal")

/usr/lib/python2.7/dist-packages/ansible/plugins/strategy/linear.py(388)运行()

failed_hosts = []

/usr/lib/python2.7/dist-packages/ansible/plugins/strategy/linear.py(389)运行()

unreachable_hosts = []

/usr/lib/python2.7/dist-packages/ansible/plugins/strategy/linear.py(390)运行()

for res in results:

/usr/lib/python2.7/dist-packages/ansible/plugins/strategy/linear.py(391)运行()

failed_hosts.append(res._host.name)

if res.is_failed() and iterator.is_failed(res._host):

res.is_failed()
True

iterator.is_failed(res._host)
True

我尝试从失败的主机列表中打印主机值。

由于NoneType异常,主机存储为失败的主机。你能现在查一下吗?

这是我试图执行的样本剧本,

res._host.name
u'110.110.112.139'

输出 callback._display.verbosity = 3

后的输出
---
- hosts: 110.110.112.139
  user: ubuntu
  gather_facts: no
  connection: ssh
  become: yes
  tasks:
  - name: "run shell script on host"
    shell: /bin/true

2 个答案:

答案 0 :(得分:0)

我猜这个错误不是在跑步者中,而是在Ansible playbook本身:在一项任务中,你试图使用{{ somevar.upper }}somevarNone

首先,您需要使用jinja过滤器upper,而不是调用upper method{{ somevar | upper }}
其次,检查变量的值,最后使用jinja过滤器default回退到默认值:{{ somevar | default('undefined') | upper }}

答案 1 :(得分:0)

最后,我只找到了解决方案 更改选项对象中的become_method值。

become_method="sudo" 

self.options = Options(listtags=False, listtasks=False, listhosts=True, syntax=False, connection='ssh', module_path=None, forks=100, remote_user='ubuntu', private_key_file=os.getcwd()+"/private-key.pem", ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=False, become_method="sudo", become_user='root', verbosity=None, check=False)

这是最终的解决方案,谢谢大家研究这个问题。