|
169 | 169 | - name: ansible_persistent_log_messages
|
170 | 170 | """
|
171 | 171 |
|
| 172 | +import os |
172 | 173 | from io import BytesIO
|
173 | 174 |
|
174 | 175 | from ansible.errors import AnsibleConnectionFailure
|
@@ -337,6 +338,45 @@ def send(self, path, data, **kwargs):
|
337 | 338 |
|
338 | 339 | return response, response_buffer
|
339 | 340 |
|
| 341 | + def send_file(self, path, filename, chunk_size=-1, retries=0, **kwargs): |
| 342 | + start = 0 |
| 343 | + tries = 0 |
| 344 | + total_size = os.stat(filename).st_size |
| 345 | + with open(filename, "rb") as fileobj: |
| 346 | + while True: |
| 347 | + if retries > tries: |
| 348 | + raise ConnectionError( |
| 349 | + "Failed to upload file too many times." |
| 350 | + ) |
| 351 | + |
| 352 | + file_slice = fileobj.read(chunk_size) |
| 353 | + if not file_slice: |
| 354 | + break |
| 355 | + |
| 356 | + slice_size = len(file_slice) |
| 357 | + end = start + slice_size |
| 358 | + headers = { |
| 359 | + "Content-Range": "{0}-{1}/{2}".format( |
| 360 | + start, end - 1, total_size |
| 361 | + ), |
| 362 | + "Content-Type": kwargs.pop( |
| 363 | + "Content-Type", "application/octet-stream" |
| 364 | + ), |
| 365 | + } |
| 366 | + try: |
| 367 | + response, response_data = self.send( |
| 368 | + path, file_slice, headers=headers, **kwargs |
| 369 | + ) |
| 370 | + except HTTPError: |
| 371 | + # Try that again |
| 372 | + start = 0 |
| 373 | + fileobj.seek(0) |
| 374 | + tries += 1 |
| 375 | + continue |
| 376 | + start = end |
| 377 | + |
| 378 | + return True |
| 379 | + |
340 | 380 | def transport_test(self, connect_timeout):
|
341 | 381 | """This method enables wait_for_connection to work.
|
342 | 382 |
|
|
0 commit comments