Open drewp opened 2 years ago
I thought this would be a workaround:
server.shell(["[[ -L /etc/resolv.conf ]] && rm /etc/resolv.conf"])
--> Starting operation: Server/Shell (['[[ -L /etc/passwd ]] && rm /etc/resolv.conf'])
[dash] sh: 1: [[: not found
[dash] Error
I think you want the force
option. You should be able to only have one operation when using force
.
So you should be able to get away with doing:
from pyinfra.operations import files
files.file(path='/tmp/resolv.conf', present=False, force=True)
And this should work for both symlink and regular files.
The downside of doing this is the file is renamed, instead of fully being deleted.
I think this is correct - by default the files.[link|directory|file]
operations will raise these errors if the path exists and doesn't match the desired type. The force=True
argument can be used to rename before creating the expected path. There is also a force_backup
(default True
) that can be set to False
to remove the path without backup.
The files.template
operation does not check anything about the target path which is why it'll work whether the path is a link or a file. I think this makes sense so a template could be written to a link directly?
So I'm not sure there's a bug to fix except maybe the error messages need improvement, something like:
--> pyinfra error: path /etc/resolv.conf already exists as a
, use force=True
to move theand create the (<include call location here)
If I run 1,2,3 I get
--> pyinfra error: /etc/resolv.conf exists and is not a file
If I run just 2,3 I get (on another host)
--> pyinfra error: /etc/resolv.conf exists and is not a link
If I run just 3 I get no errors, but I'm left with some hosts having a symlink and some having a file.
I expected just 3 to work and replace symlinks with the templated file.
May be related to #791
Meta