Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: get_url, copy with become: root when nonexistent file: "Destination /etc does not exist" #14534

Closed
nhooey opened this issue Feb 17, 2016 · 3 comments
Labels
net_tools Net-tools category

Comments

@nhooey
Copy link

nhooey commented Feb 17, 2016

Issue Type:
  • Bug Report
Ansible Version:

The results shown are from Ansible 2.0.0.2, but I get similar results with Ansible 1.9.4.

ansible 2.0.0.2
  config file = ${HOME}/.ansible.cfg
  configured module search path = Default w/o overrides
ansible 1.9.4
  configured module search path = None
Ansible Configuration:
$ cat ~/.ansible.cfg
[ssh_connection]
control_path = %(directory)s/%%h-%%p-%%r
Environment:
  • Using ansible-playbook -c local on Mac OS Yosemite 10.10.5 (14F1509)
Summary:

When either the copy or get_url are used with the following conditions:

  1. Used with become: root instead of sudo: yes
  2. Have their dest set to a file that doesn't exist
  3. Have their dest's directory set to a directory writable only by root

They emit this error:

Destination /etc not writable

If any of those conditions are the opposite, there is no error.

Steps To Reproduce:

Create this YAML file:

# test.yaml

---

- hosts: localhost
  tasks:
    - name: "Make file with `copy` module and `become: root` set"
      copy: content="" dest=/etc/publicip force=no
      become: root
      become_method: sudo
      ignore_errors: yes

- hosts: localhost
  tasks:
    - name: "Make file with `get_url` module and `become: root` set"
      get_url: url="http://icanhazip.com" dest=/etc/publicip
      become: root
      become_method: sudo
      ignore_errors: yes

- hosts: localhost
  tasks:
    - name: "Make file with `copy` module and `sudo: yes` set"
      copy: content="" dest=/etc/publicip force=no
      sudo: yes
      ignore_errors: yes

- hosts: localhost
  tasks:
    - name: "Make file with `get_url` module and `sudo: yes` set"
      get_url: url="http://icanhazip.com" dest=/etc/publicip
      sudo: yes
      ignore_errors: yes

Then run these these commands:

Ansible fails when the /etc/publicip file does not exist:
$ sudo rm -f /etc/publicip && ansible-playbook -c local test.yaml -v
Ansible succeeds when the /etc/publicip file does exist:
$ sudo rm -f /etc/publicip && sudo touch /etc/publicip && ansible-playbook -c local test.yaml -v
Expected Results:

Both the copy and get_url modules should succeed without error in writing /etc/publicip with become: root set and when the file doesn't exist and when /etc is only writable by root.

Actual Results:
Ansible fails when the /etc/publicip file does not exist:
$ sudo rm -f /etc/publicip && ansible-playbook -c local test.yaml -v
Using /Users/nhooey/.ansible.cfg as config file
 [WARNING]: provided hosts list is empty, only localhost is available

[DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo'
(default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.

PLAY ***************************************************************************

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

TASK [Make file with `copy` module and `become: root` set] *********************
fatal: [localhost]: FAILED! => {"changed": false, "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "failed": true, "msg": "Destination /etc not writable"}
...ignoring

PLAY ***************************************************************************

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

TASK [Make file with `get_url` module and `become: root` set] ******************
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "Destination /etc not writable"}
...ignoring

PLAY ***************************************************************************

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

TASK [Make file with `copy` module and `sudo: yes` set] ************************
changed: [localhost] => {"changed": true, "checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709", "dest": "/etc/publicip", "gid": 0, "group": "wheel", "md5sum": "d41d8cd98f00b204e9800998ecf8427e", "mode": "0644", "owner": "root", "size": 0, "src": "/Users/nhooey/.ansible/tmp/ansible-tmp-1455732839.53-84039304168530/source", "state": "file", "uid": 0}

PLAY ***************************************************************************

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

TASK [Make file with `get_url` module and `sudo: yes` set] *********************
ok: [localhost] => {"changed": false, "dest": "/etc/publicip", "gid": 0, "group": "wheel", "mode": "0644", "msg": "file already exists", "owner": "root", "size": 0, "state": "file", "uid": 0, "url": "http://icanhazip.com"}

PLAY RECAP *********************************************************************
localhost                  : ok=8    changed=1    unreachable=0    failed=0
Ansible succeeds when the /etc/publicip file does exist:
$ sudo rm -f /etc/publicip && sudo touch /etc/publicip && ansible-playbook -c local test.yaml -v
Using /Users/nhooey/.ansible.cfg as config file
 [WARNING]: provided hosts list is empty, only localhost is available

[DEPRECATION WARNING]: Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo'
(default). This feature will be removed in a future release. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.

PLAY ***************************************************************************

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

TASK [Make file with `copy` module and `become: root` set] *********************
ok: [localhost] => {"changed": false, "dest": "/etc/publicip", "src": "/var/folders/m6/fwg0yy9956l_45ypwfx8v86r0000gp/T/tmpcpHClk"}

PLAY ***************************************************************************

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

TASK [Make file with `get_url` module and `become: root` set] ******************
ok: [localhost] => {"changed": false, "dest": "/etc/publicip", "gid": 0, "group": "wheel", "mode": "0644", "msg": "file already exists", "owner": "root", "size": 0, "state": "file", "uid": 0, "url": "http://icanhazip.com"}

PLAY ***************************************************************************

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

TASK [Make file with `copy` module and `sudo: yes` set] ************************
ok: [localhost] => {"changed": false, "dest": "/etc/publicip", "src": "/var/folders/m6/fwg0yy9956l_45ypwfx8v86r0000gp/T/tmpC11QFj"}

PLAY ***************************************************************************

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

TASK [Make file with `get_url` module and `sudo: yes` set] *********************
ok: [localhost] => {"changed": false, "dest": "/etc/publicip", "gid": 0, "group": "wheel", "mode": "0644", "msg": "file already exists", "owner": "root", "size": 0, "state": "file", "uid": 0, "url": "http://icanhazip.com"}

PLAY RECAP *********************************************************************
localhost                  : ok=8    changed=0    unreachable=0    failed=0
@sivel
Copy link
Member

sivel commented Feb 18, 2016

become: root is not a thing. become is a Boolean field and should be given true or false. Also root is the default for become_user, and sudo is the default for become_method so you should only need to supply become: true

@jimi-c
Copy link
Member

jimi-c commented Feb 24, 2016

As @sivel indicated, you're using the option slightly incorrectly. When the string root is converted to a boolean, it will be converted to False, so it will in effect disable escalated privileges. Changing to become: yes should resolve the issue.

If you continue seeing any problems related to this issue, or if you have any further questions, please let us know by stopping by one of the two mailing lists, as appropriate:

Because this project is very active, we're unlikely to see comments made on closed tickets, but the mailing list is a great way to ask questions, or post if you don't think this particular issue is resolved.

Thank you!

@jimi-c jimi-c closed this as completed Feb 24, 2016
@adampbrush
Copy link

Ref: Destination /etc not writable errors, its worth just double checking the dest file permissions. You could try creating the destination file as an empty file and them chmod'ing it to appropriate levels. This worked for me.

@dagwieers dagwieers added the net_tools Net-tools category label Mar 3, 2019
@ansible ansible locked and limited conversation to collaborators Apr 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
net_tools Net-tools category
Projects
None yet
Development

No branches or pull requests

5 participants