程序在mac上报错:you must install the sshpass program

来源:7-19 pymongo执行基础的CURD操作

404_

2019-10-29

老师,您好!
我的程序在centos6上跑,没有问题;但是在mac上跑,就报错,让我安装sshpass。我已经在mac上安装了sshpass了。但是还是报这个错。
{‘success’: {}, ‘failed’: {‘192_168_2_112’: {‘failed’: True, ‘msg’: “to use the ‘ssh’ connection type with passwords, you must install the sshpass program”}}, ‘unreachable’: {}}

老师,我已经安装了sshpass
图片描述

如下是我的代码

#!/usr/bin/env python
# -*- coding=utf-8 -*-
import os,sys

from ansible import constants

PROJECT_ROOT = '/opt/imoocc_py3_online'
sys.path.insert(0,PROJECT_ROOT)
os.environ["DJANGO_SETTINGS_MODULE"] = 'admin.settings.settings'
import django
django.setup()

from collections import namedtuple

from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.inventory.group import Group
#from ansible.inventory.host import Group
from ansible.inventory.host import Host, Group
from ansible.inventory.manager import InventoryManager
from ansible.plugins.callback import CallbackBase
from ansible.parsing.dataloader import DataLoader
from ansible.playbook.play import Play

from ansible.vars.manager import VariableManager

from admin.settings.settings import BASE_DIR


class MyInventory():
    """this is IOPS ansible inventory object."""
    def __init__(self, resource,loader,variable_manager):
        self.resource = resource
        self.loader = DataLoader()
        #self.inventory = InventoryManager(loader=self.loader)
        self.inventory = InventoryManager(loader=self.loader, sources='/tmp/hots')
        self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)


        self.dynamic_inventory()

    def add_dynamic_group(self, hosts, groupname, groupvars=None):
        self.inventory.add_group(groupname)
        mygroup = Group(name=groupname)

        if groupvars:
            for k,v in groupvars.items():
                mygroup.set_variable(k,v)

        for host in hosts:
            print("hosts: ",host)
            hostname = host.get("hostname")
            hostip = host.get('ip')
            hostport = host.get('port')
            username = host.get('username')
            password = host.get('password')
            #myhost = Host(name=hostname, port=hostname)
            #myhost = Host(name=hostname, port=hostport)
            myhost = Host(name=hostip, port=hostport)
            self.variable_manager.set_host_variable(host=myhost, varname='ansible_ssh_host', value=hostip)
            self.variable_manager.set_host_variable(host=myhost, varname='ansible_ssh_port', value=hostport)
            self.variable_manager.set_host_variable(host=myhost, varname='ansible_ssh_user', value=username)
            self.variable_manager.set_host_variable(host=myhost, varname='ansible_ssh_pass', value=password)

            for key, value in host.items():
                if key not in ["hostname", "port", "username", "password"]:
                    self.variable_manager.set_host_variable(host=myhost,varname=key,value=value)

            self.inventory.add_host(host=hostname, group=groupname, port=hostport)

            #print("self.inventory.add_host: ", self.inventory.groups)




    def dynamic_inventory(self):
        """
            add hosts to inventory.
        """
        print('ninhao',self.resource.items())
        if isinstance(self.resource, list):
            print('list')
        elif isinstance(self.resource, dict):
            for groupname, hosts_and_vars in self.resource.items():
                print("for:",groupname, hosts_and_vars)
                #self.add_dynamic_group(hosts_and_vars['hosts'], groupname, hosts_and_vars['vars'])
                self.add_dynamic_group(hosts_and_vars.get("hosts"),groupname, hosts_and_vars.get("vars"))

        #if isinstance(self.resource, list):
            #self.add_dynamic_group(self.resource, 'default_group')
        #elif isinstance(self.resource, dict):
            #for groupname, hosts_and_vars in self.resource.iteritems():
            #for groupname, hosts_and_vars in self.resource.items():
                #self.add_dynamic_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars"))

class ModelResultsCollector(CallbackBase):

    def __init__(self, *args, **kwargs):
        super(ModelResultsCollector, self).__init__(*args, **kwargs)
        self.host_ok = {}
        self.host_unreachable = {}
        self.host_failed = {}

    def v2_runner_on_unreachable(self, result):
        self.host_unreachable[result._host.get_name()] = result

    def v2_runner_on_ok(self, result,  *args, **kwargs):
        self.host_ok[result._host.get_name()] = result

    def v2_runner_on_failed(self, result,  *args, **kwargs):
        self.host_failed[result._host.get_name()] = result


class ANSRunner(object):
    def __init__(self,resource,*args, **kwargs):
        self.resource = resource
        self.inventory = None
        self.variable_manager = None
        self.loader = None
        self.options = None
        self.passwords = None
        self.callback = None
        self.__initializeData()
        self.results_raw = {}

    def __initializeData(self):
        """ 初始化ansible """
        Options = namedtuple('Options',
                             [
                                 'connection',
                                 'module_path',
                                 'forks',
                                 'timeout',
                                 'remote_user',
                                 'ask_pass',
                                 'private_key_file',
                                 'ssh_common_args',
                                 'ssh_extra_args',
                                 'sftp_extra_args',
                                 'scp_extra_args',
                                 'become',
                                 'become_method',
                                 'become_user',
                                 'ask_value_pass',
                                 'verbosity',
                                 'check',
                                 'listhosts',
                                 'listtasks',
                                 'listtags',
                                 'syntax',
                                 'diff'
                             ])
        self.loader = DataLoader()
        self.options = Options(
            connection='smart',
            module_path=None,
            forks=100,
            timeout=10,
            remote_user='root',
            ask_pass=False,
            private_key_file=None,
            ssh_common_args=None,
            ssh_extra_args=None,
            sftp_extra_args=None,
            scp_extra_args=None,
            become=None,
            become_method=None,
            become_user='root',
            ask_value_pass=False,
            verbosity=None,
            check=False,
            listhosts=False,
            listtasks=False,
            listtags=False,
            syntax=False,
            diff=True
        )

        self.passwords = dict(sshpass=None, becomepass=None)
        myinvent = MyInventory(self.resource, self.loader, self.variable_manager)
        #print("self.resource:",self.resource) #{'dynamic_host_test': {'hosts': [{'username': 'user', 'password': 'p#sswS0816Hrd#', 'ip': '10.54.70.129', 'hostname': 'zhoushuyu', 'port': '22'}], 'vars': {'var1': 'ansible'}}}
        #print("self.inventory", self.inventory) #None
        #print("self.variable_manager", self.variable_manager) #None
        self.inventory = myinvent.inventory
        self.variable_manager = myinvent.variable_manager

    def run_model(self, host_list, module_name, module_args):
        play_source = dict(
            name="Ansible ad-hoc",
            hosts=host_list,
            gather_facts='no',
            tasks=[dict(action=dict(module=module_name, args=module_args))]
        )

        play = Play().load(play_source,variable_manager=self.variable_manager,loader=self.loader)
        tqm = None
        self.callback = ModelResultsCollector()
        tqm = TaskQueueManager(
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            options=self.options,
            passwords=self.passwords,
            stdout_callback="minimal",
        )
        tqm._stdout_callback = self.callback
        constants.HOST_KEY_CHECKING = False
        tqm.run(play)

    def get_model_result(self):
        self.results_raw = {'success':{}, 'failed':{}, 'unreachable':{}}
        for host, result in self.callback.host_ok.items():
            hostvisiable = host.replace('.','_')
            self.results_raw['success'][hostvisiable] = result._result


        for host, result in self.callback.host_failed.items():
            hostvisiable = host.replace('.','_')
            self.results_raw['failed'][hostvisiable] = result._result


        for host, result in self.callback.host_unreachable.items():
            hostvisiable = host.replace('.','_')
            self.results_raw['unreachable'][hostvisiable]= result._result

        # return json.dumps(self.results_raw)
        return self.results_raw


if __name__ == '__main__':
    resource = {
        "dynamic_host_test": {
            "hosts": [
                {'username': 'root', 'password': 'password', 'ip': '192.168.2.112', 'hostname': 'zoushuyu',
                 'port': '22'}
            ],
            "vars": {
                "var1": "ansible",
            }
        }
    }

    rbt = ANSRunner(resource)
    rbt.run_model(host_list=['192.168.2.112'], module_name='shell', module_args="uname -a")
    print(rbt.get_model_result())

完整报错如下:
{‘success’: {}, ‘failed’: {‘192_168_2_112’: {‘failed’: True, ‘msg’: “to use the ‘ssh’ connection type with passwords, you must install the sshpass program”}}, ‘unreachable’: {}}

并且,我是可以从mac上ssh到192.168.2.112这台服务器上的
图片描述

请问老师这是为什么呢?

写回答

1回答

Jeson

2019-10-30

问题的意思还是没有安装sshpass.

如果你源码的方式安装了,需要检查下sshpass命令在系统上是否能真正得到执行。可以执行下sshpass命令测试下。

mac下,可以参考用如下方式安装:

brew create https://sourceforge.net/projects/sshpass/files/sshpass/1.06/sshpass-1.06.tar.gz --force

0
0

Python+Django+Ansible Playbook自动化运维项目实战

【课程升级3.6版本】大牛全面践行DevOps,运维与开发间高效协作

861 学习 · 326 问题

查看课程