@@ -81,6 +81,8 @@ def sftp_read(self, source, destination=None):
81
81
"""read a remote file into a local destination"""
82
82
if not destination :
83
83
destination = source
84
+ elif destination .endswith ("/" ):
85
+ destination = destination + Path (source ).name
84
86
# create the destination path if it doesn't exist
85
87
destination = Path (destination )
86
88
destination .parent .mkdir (parents = True , exist_ok = True )
@@ -94,30 +96,38 @@ def sftp_read(self, source, destination=None):
94
96
for size , data in remote :
95
97
local .write (data )
96
98
97
- def sftp_write (self , source , destination = None ):
99
+ def sftp_write (self , source , destination = None , ensure_dir = True ):
98
100
"""sftp write a local file to a remote destination"""
99
101
if not destination :
100
102
destination = source
103
+ elif destination .endswith ("/" ):
104
+ destination = destination + Path (source ).name
101
105
data = Path (source ).read_bytes ()
106
+ if ensure_dir :
107
+ self .run (f"mkdir -p { Path (destination ).absolute ().parent } " )
102
108
sftp = self .session .sftp_init ()
103
109
with sftp .open (destination , FILE_FLAGS , SFTP_MODE ) as remote :
104
110
remote .write (data )
105
111
106
- def remote_copy (self , source , dest_host ):
112
+ def remote_copy (self , source , dest_host , ensure_dir = True ):
107
113
"""Copy a file from this host to another"""
108
114
sftp_down = self .session .sftp_init ()
109
115
sftp_up = dest_host .session .session .sftp_init ()
116
+ if ensure_dir :
117
+ dest_host .run (f"mkdir -p { Path (source ).absolute ().parent } " )
110
118
with sftp_down .open (
111
119
source , ssh2_sftp .LIBSSH2_FXF_READ , ssh2_sftp .LIBSSH2_SFTP_S_IRUSR
112
120
) as download :
113
121
with sftp_up .open (source , FILE_FLAGS , SFTP_MODE ) as upload :
114
122
for size , data in download :
115
123
upload .write (data )
116
124
117
- def scp_write (self , source , destination = None ):
125
+ def scp_write (self , source , destination = None , ensure_dir = True ):
118
126
"""scp write a local file to a remote destination"""
119
127
if not destination :
120
128
destination = source
129
+ elif destination .endswith ("/" ):
130
+ destination = destination + Path (source ).name
121
131
fileinfo = os .stat (source )
122
132
chan = self .session .scp_send64 (
123
133
destination ,
@@ -126,6 +136,8 @@ def scp_write(self, source, destination=None):
126
136
fileinfo .st_mtime ,
127
137
fileinfo .st_atime ,
128
138
)
139
+ if ensure_dir :
140
+ self .run (f"mkdir -p { Path (destination ).absolute ().parent } " )
129
141
with open (source , "rb" ) as local :
130
142
for data in local :
131
143
chan .write (data )
@@ -221,7 +233,7 @@ def disconnect(self):
221
233
"""Needed for simple compatability with Session"""
222
234
pass
223
235
224
- def sftp_write (self , source , destination = None ):
236
+ def sftp_write (self , source , destination = None , ensure_dir = True ):
225
237
"""Add one of more files to the container"""
226
238
# ensure source is a list of Path objects
227
239
if not isinstance (source , list ):
@@ -232,15 +244,17 @@ def sftp_write(self, source, destination=None):
232
244
for src in source :
233
245
if not Path (src ).exists ():
234
246
raise FileNotFoundError (src )
235
- destination = Path ( destination ) or source [0 ].parent
247
+ destination = destination or f" { source [0 ].parent } /"
236
248
# Files need to be added to a tarfile
237
249
with helpers .temporary_tar (source ) as tar :
238
250
logger .debug (
239
251
f"{ self ._cont_inst .hostname } adding file(s) { source } to { destination } "
240
252
)
241
- # if the destination is a file, create the parent path
242
- if destination .is_file ():
243
- self .execute (f"mkdir -p { destination .parent } " )
253
+ if ensure_dir :
254
+ if destination .endswith ("/" ):
255
+ self .run (f"mkdir -m 666 -p { destination } " )
256
+ else :
257
+ self .run (f"mkdir -m 666 -p { Path (destination ).parent } " )
244
258
self ._cont_inst ._cont_inst .put_archive (str (destination ), tar .read_bytes ())
245
259
246
260
def sftp_read (self , source , destination = None ):
0 commit comments