简体   繁体   中英

Argument must be str not bytes

I'm running Ansible 2.2.0.0 from Travis-CI in order to install a common shared version of Terraform that we are using in our project.

I can run it locally without issues, but when I run it in Travis, it seems to fail on some encoding of a string sourced from a variable:

[WARNING]: Host file not found: /etc/ansible/hosts

[WARNING]: provided hosts list is empty, only localhost is available

PLAY [localhost] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [terraform : create terraform directory] **********************************
changed: [localhost]

TASK [terraform : install terraform] *******************************************
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "Failure downloading https://releases.hashicorp.com/terraform/0.7.13/terraform_0.7.13_linux_amd64.zip, write() argument must be str, not bytes"}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=1

Host Ansible and Python versions:

vagrant@ubuntu-14:/vagrant/ansible$ python3 --version
Python 3.4.3
vagrant@ubuntu-14:/vagrant/ansible$ ansible --version
ansible 2.2.0.0
  config file = /vagrant/ansible/ansible.cfg
  configured module search path = Default w/o overrides

Travis Ansible and Python versions:

$ python --version
Python 3.4.2
$ ansible --version
ansible 2.2.0.0
  config file = 
  configured module search path = Default w/o overrides

I have validated that LANG is en_US.UTF-8 in both places.

Here is my playbook:

---
  - hosts: localhost
    roles:
      - role: terraform
        terraform_install_root: "{{ ansible_env.HOME }}/terraform/"
        bin_dir: "{{ ansible_env.HOME }}/.local/bin"

Here is roles/terraform/tasks/main.yml :

---
 - name: create terraform directory
   file: path={{ terraform_install_root }}/{{ terraform_version }} state=directory

 - name: install terraform
   unarchive:
     copy: no
     src: "https://releases.hashicorp.com/terraform/{{ terraform_version }}/terraform_{{ terraform_version }}_linux_amd64.zip"
     dest: "{{ terraform_install_root }}/{{ terraform_version }}"
     creates: "{{ terraform_install_root }}/{{ terraform_version }}/terraform"

 - name: ensure bin directory exists
   file: path={{ bin_dir }} state=directory

 - name: create terraform symlink
   file: src={{ terraform_install_root }}/{{ terraform_version }}/terraform dest={{ bin_dir }}/terraform state=link

Here is roles/terraform/vars/main.yml :

---
terraform_version: "0.7.13"
terraform_install_root: /opt/terraform/
bin_dir: /usr/local/bin

It appears that for some reason, Ansible is failing to convert something into UTF-8, even though I'm not doing anything strange, and what runs locally just fine does not run on Travis.

Furthermore, it appears that there are no non-ASCII characters in any of these files:

$ file -i ansible/roles/terraform/tasks/main.yml
ansible/roles/terraform/tasks/main.yml: text/plain; charset=us-ascii
$ file -i ansible/roles/terraform/vars/main.yml
ansible/roles/terraform/vars/main.yml: text/plain; charset=us-ascii
$ file -i ansible/travis-playbook.yml
ansible/travis-playbook.yml: text/plain; charset=us-ascii

Any ideas?

Use the quotes around src of this task:

 - name: install terraform
   unarchive:
     copy: no
     src: "https://releases.hashicorp.com/terraform/{{ terraform_version }}/terraform_{{ terraform_version }}_linux_amd64.zip"
     dest: "{{ terraform_install_root }}/{{ terraform_version }}"
     creates: "{{ terraform_install_root }}/{{ terraform_version }}/terraform"

Then run it:

ansible-playbook -i 192.168.33.33, terraform.yml                                                               2 ↵

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [192.168.33.33]

TASK [terraform-stackoverflow : create terraform directory] ********************
ok: [192.168.33.33]

TASK [terraform-stackoverflow : install terraform] *****************************
changed: [192.168.33.33]

TASK [terraform-stackoverflow : ensure bin directory exists] *******************
changed: [192.168.33.33]

TASK [terraform-stackoverflow : create terraform symlink] **********************
changed: [192.168.33.33]

PLAY RECAP *********************************************************************
192.168.33.33              : ok=5    changed=3    unreachable=0    failed=0

As much of a cop-out as this is, I updated to use Travis' trusty (Ubuntu 14.04) image beta and the problem went away.

It should be noted that precise is Ubuntu 12.04, which is four, coming on five years old.

It's a known Ansible bug ( #5791 ) and has been fixed in develop , although it is not in a release yet ( commit ansible/ansible@1963e50 ).

Perhaps you can install a separate 2.7 Python on the target host just for the use of Ansible? (You can configure the interpreter to use with ansible_python_interpreter in the inventory .) I found trying to use Python3 with Ansible is a never-ending game of whack-a-bug, although in all fairness the Ansible is actively working on fixing that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM