@@ -946,6 +946,19 @@ def _validate_path(path):
946
946
raise OperationTypeError ('`path` must be a string or `os.PathLike` object' )
947
947
948
948
949
+ def _raise_or_remove_invalid_path (fs_type , path , force , force_backup , force_backup_dir ):
950
+ if force :
951
+ if force_backup :
952
+ backup_path = '{0}.{1}' .format (path , get_timestamp ())
953
+ if force_backup_dir :
954
+ backup_path = '{0}/{1}' .format (force_backup_dir , backup_path )
955
+ yield 'mv {0} {1}' .format (path , backup_path )
956
+ else :
957
+ yield 'rm -rf {0}' .format (path )
958
+ else :
959
+ raise OperationError ('{0} exists and is not a {1}' .format (path , fs_type ))
960
+
961
+
949
962
@operation (pipeline_facts = {
950
963
'link' : 'path' ,
951
964
})
@@ -954,6 +967,7 @@ def link(
954
967
target = None , present = True , assume_present = False ,
955
968
user = None , group = None , symbolic = True ,
956
969
create_remote_dir = True ,
970
+ force = False , force_backup = True , force_backup_dir = None ,
957
971
state = None , host = None ,
958
972
):
959
973
'''
@@ -967,6 +981,9 @@ def link(
967
981
+ group: group to own the link
968
982
+ symbolic: whether to make a symbolic link (vs hard link)
969
983
+ create_remote_dir: create the remote directory if it doesn't exist
984
+ + force: if the target exists and is not a file, move or remove it and continue
985
+ + force_backup: set to ``False`` to remove any existing non-file when ``force=True``
986
+ + force_backup_dir: directory to move any backup to when ``force=True``
970
987
971
988
``create_remote_dir``:
972
989
If the remote directory does not exist it will be created using the same
@@ -1014,7 +1031,10 @@ def link(
1014
1031
1015
1032
# Not a link?
1016
1033
if info is False :
1017
- raise OperationError ('{0} exists and is not a link' .format (path ))
1034
+ yield _raise_or_remove_invalid_path (
1035
+ 'link' , path , force , force_backup , force_backup_dir ,
1036
+ )
1037
+ info = None
1018
1038
1019
1039
add_args = ['ln' ]
1020
1040
if symbolic :
@@ -1097,6 +1117,7 @@ def file(
1097
1117
present = True , assume_present = False ,
1098
1118
user = None , group = None , mode = None , touch = False ,
1099
1119
create_remote_dir = True ,
1120
+ force = False , force_backup = True , force_backup_dir = None ,
1100
1121
state = None , host = None ,
1101
1122
):
1102
1123
'''
@@ -1110,6 +1131,9 @@ def file(
1110
1131
+ mode: permissions of the files as an integer, eg: 755
1111
1132
+ touch: whether to touch the file
1112
1133
+ create_remote_dir: create the remote directory if it doesn't exist
1134
+ + force: if the target exists and is not a file, move or remove it and continue
1135
+ + force_backup: set to ``False`` to remove any existing non-file when ``force=True``
1136
+ + force_backup_dir: directory to move any backup to when ``force=True``
1113
1137
1114
1138
``create_remote_dir``:
1115
1139
If the remote directory does not exist it will be created using the same
@@ -1139,7 +1163,10 @@ def file(
1139
1163
1140
1164
# Not a file?!
1141
1165
if info is False :
1142
- raise OperationError ('{0} exists and is not a file' .format (path ))
1166
+ yield _raise_or_remove_invalid_path (
1167
+ 'file' , path , force , force_backup , force_backup_dir ,
1168
+ )
1169
+ info = None
1143
1170
1144
1171
# Doesn't exist & we want it
1145
1172
if not assume_present and info is None and present :
@@ -1206,6 +1233,7 @@ def directory(
1206
1233
path ,
1207
1234
present = True , assume_present = False ,
1208
1235
user = None , group = None , mode = None , recursive = False ,
1236
+ force = False , force_backup = True , force_backup_dir = None ,
1209
1237
_no_check_owner_mode = False ,
1210
1238
_no_fail_on_link = False ,
1211
1239
state = None , host = None ,
@@ -1220,6 +1248,9 @@ def directory(
1220
1248
+ group: group to own the folder
1221
1249
+ mode: permissions of the folder
1222
1250
+ recursive: recursively apply user/group/mode
1251
+ + force: if the target exists and is not a file, move or remove it and continue
1252
+ + force_backup: set to ``False`` to remove any existing non-file when ``force=True``
1253
+ + force_backup_dir: directory to move any backup to when ``force=True``
1223
1254
1224
1255
Examples:
1225
1256
@@ -1257,7 +1288,10 @@ def directory(
1257
1288
if _no_fail_on_link and host .get_fact (Link , path = path ):
1258
1289
host .noop ('directory {0} already exists (as a link)' .format (path ))
1259
1290
return
1260
- raise OperationError ('{0} exists and is not a directory' .format (path ))
1291
+ yield _raise_or_remove_invalid_path (
1292
+ 'directory' , path , force , force_backup , force_backup_dir ,
1293
+ )
1294
+ info = None
1261
1295
1262
1296
# Doesn't exist & we want it
1263
1297
if not assume_present and info is None and present :
0 commit comments