"Cannot set fs attributes on a non-existent symlink target" error on symlink Ansible creation

5k views Asked by At

I am trying to set a symlink from source to destination, but keep hitting

fatal: [default]: FAILED! => {"changed": false, "failed": true, "msg":
"Error while linking: [Errno 2] No such file or directory", "path":
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/include/ruby-2.0.0/ruby/config.h",
"state": "absent"}

Observed that it shows state absent even though state is given as link.

This is the executed task:

- name: "Create ruby config.h symlink"
  file:
    src: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/include/ruby-2.0.0/universal-darwin15/ruby/config.h"
    dest: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/include/ruby-2.0.0/ruby/config.h"
    state: link
    force: yes 
  when: xcode_version != "8.0"

The target file exists:

ls -l /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/include/ruby-2.0.0/universal-darwin15/ruby/config.h
    -rw-r--r--  2 root  wheel  7805 Jan 31  2016 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/include/ruby-2.0.0/universal-darwin15/ruby/config.h

Note: Included force yes based on discussion here: GitHub | Ansible Issue #7627

Any help is appreciated!

3

There are 3 answers

1
Pasi H On

I'm not sure if a missing directory is the cause of the problem here but it's a good practice to ensure that the destination directory exists before creating a link that points to that directory:

- name: Ensure that the directory exist
  file:
    path: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/include/ruby-2.0.0/ruby"
    state: directory
    mode: 0755
    owner: root
    group: wheel

- name: "Create ruby config.h symlink"
  file:
  ...
0
Eddie C. On

When creating a symlink using force: true, you should also add the option follow:false to let it work. So, your code should be changed the following way:

- name: "Create ruby config.h symlink"
  file:
    src: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/include/ruby-2.0.0/universal-darwin15/ruby/config.h"
    dest: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/include/ruby-2.0.0/ruby/config.h"
    state: link
    force: yes 
    follow: false  #   <-- Note this addition
  when: xcode_version != "8.0"

Credits: Davide Del Vento's reply

2
cognophile On

My answer may not address the OP question, but it certainly does cause this issue and so might explain another person running into this issue. I've often found such an error can be caused by a trailing / in the link name.

For example, a task to create a directory as below will succeed.

- name: ensure foobar directory exists
  file: 
    state: directory
    path: '/tmp/foobar/'
    owner: 'foo'    
    group: 'bar'
    mode: 0777

However, the subsequent link creation task, if written as below, will result in the error you're experiencing.

- name: Establish link to foobar
  file:
    src: '/tmp/foobar/'
    dest: '/local/baz/'
    state: link

Results in the below error.

fatal: [default]: FAILED! => {"changed": false, "failed": true, "msg": "Error while linking: [Errno 2] No such file or directory", "path": "...", "state": "absent"}

Removing the / as per below, can resolve this.

- name: Establish link to foobar
  file:
    src: '/tmp/foobar/'
    dest: '/local/baz'
    state: link