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

Add state=present to file module (rather than state=touch) #7490

Closed
hjwp opened this issue May 22, 2014 · 18 comments
Closed

Add state=present to file module (rather than state=touch) #7490

hjwp opened this issue May 22, 2014 · 18 comments

Comments

@hjwp
Copy link

hjwp commented May 22, 2014

Issue Type: Feature Idea
Ansible Version: ansible 1.5.5
Environment: Linux
Summary:

cf discussion on #4097. Although state=touch works pretty well, something called state=present would be more useful for (what I think is) a very common use case.

Steps To Reproduce: n/a
Expected Results: n/a
Actual Results: n/a

The example is: making sure that a log file is present, and has the correct perms to be written to by a program.

What's desired is that ansible should create the file, and give it the correct permissions, if it doesn't exist. This is already achieved by the state=touch option.

However, touch has a couple of undesirable side-effects in this use case. Firstly, it does a touch even when the file does already exist and has the correct perms, which causes spurious updates to the log files last modified & accessed perms. Secondly, ansible registers the step as "changed" every time it's run, even though, as far as I cared, there was nothing that needed to be done. This makes it hard to, eg, drive a correct handler notification from the step.

So, a minor enhancement proposal, but a useful one I think.

@mpdehaan
Copy link
Contributor

This can be done with:

copy: content="" dest=/path/to/file force=no # plus optional args like mode, etc

@hjwp
Copy link
Author

hjwp commented May 22, 2014

Is there a way of specifying owner and permissions with copy? It doesn't look like it from the docs

@jimi-c
Copy link
Member

jimi-c commented May 22, 2014

All of the files/ modules (file, copy, template, etc.) take the owner and other parameters as defined in the file module itself. There is an open issue to address showing that information on those module docs pages as well.

@illenseer
Copy link
Contributor

@mpdehaan but copy with force=no does not ensure correct owner, group and mode for the file, when the file is already present, then you still need file to do that. And IMO it is better to just declare it once and not twice. Also if you have to declare it twice there is potential space for mistakes and inconsistencies when someone updates it.

@jimi-c
Copy link
Member

jimi-c commented May 22, 2014

@illenseer copy also takes those same owner/permissions/etc. attributes. As I noted above, there is an open issue to reflect that in the documentation.

@illenseer
Copy link
Contributor

@jimi-c yes, I know, but with force=no it won't enforce owner/permissions/etc. If the file is present copy does nothing at all.

@bencord0
Copy link

bencord0 commented Jan 9, 2015

It appears that I'm late to this discussion.

My current workaround is to combine the command and file modules. (This is with ansible-1.8.2, latest in pypi.)

  • command: touch /var/log/something.log creates=/var/log/something.log
  • file: path=/var/log/something.log state=file owner=someone group=collective mode=0644

Which would be much nicer if there was a file: state=present.

Requirements:

  • If the log file doesn't exist, doesn't have the right permissions, the daemon can't run (and the daemon can't create the log file).
  • If the file exists, the permissions should be checked and corrected if necessary (triggering changed=true). If permissions are correct, no action should be taken and changed=false.
  • If the file doesn't exist, creating an empty file if fine. But always creating an empty file is bad in all other cases, as that would wiped the log.
  • I don't care about the timestamps. Setting changed=true because of timestamps is a stupid behaviour in this case. That behaviour immediately causes the entire host to be marked as changed and could trigger further hooks! The host will never converge.

I believe that this is much closer to the state=file behaviour, except that the outcome isn't dependent on the prior existence (or not) of the path.

@jnojr
Copy link

jnojr commented May 7, 2015

I have to agree... state=present would be nice. I'm using state=touch, but that always shows as "changed" in the output, when nothing useful has actually changed. touching when not necessary isn't clean, and neither is stringing other commands together to wind up with the result you could (and should be able to) get from one.

Please do add this.

@holms
Copy link

holms commented Jun 1, 2015

@mpdehaan I'd vote for that too =/ I mean your described method is a hack.

@assarbad
Copy link

assarbad commented Jun 2, 2015

Same here: +1 for the state=present proposal.

@nethernet
Copy link

+ 1. I would love to see that option available 'out-of-the-box' rather than implementing 'ugly' hacks.

@deltaraven
Copy link

+1. I too am implementing @bencord0's hack.

@dave-kong
Copy link

+1 to state=present. ensuring the existence of some file is very much a common operation.

@jpbarbosa
Copy link

+1 to state=present (linked issue: ansible/ansible-modules-core#170)

@jacobweber
Copy link
Contributor

Any way to get this re-opened? This seems like a pretty common need, and using "copy" doesn't ensure that the mode/owner is set correctly.

awailly added a commit to awailly/cis-ubuntu-ansible that referenced this issue Oct 18, 2015
- As suggested in ansible/ansible#7490
- file: state=present would be better
@Petrox
Copy link
Contributor

Petrox commented Nov 5, 2015

@mpdehaan:

Could you please tell me what is the current official solution (not hack), if someone wants

  • a logfile to exist with zero or more bytes in it (starts with zero, but it should not be enforced / truncated)
  • given ownership and rights (even with correct acl setting copy module ignores ACL when creating file ansible-modules-core#192)
  • change only when the file ownership or rights needs to be changed, or create if missing (see: copy with force=no does not ensure correct owner)
  • no touching (no changed state report) if no change needed to those rights or ownership and the file exists

This should be a oneliner I believe, but we've only got closed issues and no correct, full, official solution.

Thank you.

@jimi-c
Copy link
Member

jimi-c commented Nov 5, 2015

@Petrox, mpdehaan is no longer affiliated with the project. The official method is still state=touch. If you do not want the task to show up as changed use changed_when: false on the task as well.

I am going to go ahead and lock this thread. If anyone has any further questions, please direct them to the mailing list.

@ansible ansible locked and limited conversation to collaborators Nov 5, 2015
emanuelis added a commit to geerlingguy/ansible-role-mysql that referenced this issue Feb 12, 2016
@samdoran
Copy link
Contributor

This can be done in Ansible >= 2.7.0 by preserving both modification and access time:

- file:
    path: /tmp/empty
    state: touch
    modification_time: preserve
    access_time: preserve

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests