|
2 | 2 | import os |
3 | 3 | import uuid |
4 | 4 | import re |
| 5 | +import tarfile |
| 6 | +import shutil |
5 | 7 |
|
6 | 8 | from io import BytesIO |
7 | 9 |
|
8 | 10 | import requests |
9 | 11 |
|
10 | | -from flask import g, abort, Response, send_file, request |
| 12 | +from flask import g, abort, Response, send_file, request, after_this_request |
11 | 13 | from flask_restplus import Resource, fields |
12 | 14 |
|
13 | | -from pyinfraboxutils import get_logger |
| 15 | +from pyinfraboxutils import get_logger, get_env |
14 | 16 | from pyinfraboxutils.ibflask import OK |
15 | 17 | from pyinfraboxutils.ibrestplus import api, response_model |
16 | 18 | from pyinfraboxutils.storage import storage |
@@ -444,6 +446,62 @@ def get(self, project_id, job_id): |
444 | 446 | return result['archive'] |
445 | 447 |
|
446 | 448 |
|
| 449 | +@ns.route('/<job_id>/archive/download/all') |
| 450 | +@api.response(403, 'Not Authorized') |
| 451 | +class ArchiveDownloadAll(Resource): |
| 452 | + |
| 453 | + def get(self, project_id, job_id): |
| 454 | + ''' |
| 455 | + Returns all archives |
| 456 | + ''' |
| 457 | + result = g.db.execute_one_dict(''' |
| 458 | + SELECT archive |
| 459 | + FROM job |
| 460 | + WHERE id = %s |
| 461 | + AND project_id = %s |
| 462 | + ''', [job_id, project_id]) |
| 463 | + |
| 464 | + if not result or not result['archive']: |
| 465 | + abort(404) |
| 466 | + |
| 467 | + base_path = os.path.join('/tmp', str(uuid.uuid4())) |
| 468 | + archive_dir = os.path.join(base_path, 'archive') |
| 469 | + os.mkdir(base_path) |
| 470 | + os.mkdir(archive_dir) |
| 471 | + |
| 472 | + @after_this_request |
| 473 | + def _remove_file(response): |
| 474 | + if os.path.exists(base_path): |
| 475 | + shutil.rmtree(base_path) |
| 476 | + return response |
| 477 | + |
| 478 | + for item in result['archive']: |
| 479 | + filename = item['filename'] |
| 480 | + url = "%s/api/v1/projects/%s/jobs/%s/archive/download?filename=%s" % \ |
| 481 | + (get_env('INFRABOX_ROOT_URL'), project_id, job_id, filename) |
| 482 | + try: |
| 483 | + token = encode_user_token(g.token['user']['id']) |
| 484 | + except Exception: |
| 485 | + #public project has no token here. |
| 486 | + token = "" |
| 487 | + headers = {'Authorization': 'bearer ' + token} |
| 488 | + |
| 489 | + r = requests.get(url, headers=headers, timeout=120, verify=False) |
| 490 | + if r.status_code != 200: |
| 491 | + continue |
| 492 | + |
| 493 | + with open(os.path.join(archive_dir, os.path.basename(filename)), 'w') as f: |
| 494 | + f.write(r.content) |
| 495 | + |
| 496 | + if not os.listdir(archive_dir): |
| 497 | + abort(404) |
| 498 | + |
| 499 | + tar_file = os.path.join(base_path, 'archive_%s' % job_id +'.tar.gz') |
| 500 | + with tarfile.open(tar_file, mode='w:gz') as archive: |
| 501 | + archive.add(archive_dir, arcname='archive') |
| 502 | + |
| 503 | + return send_file(tar_file, as_attachment=True, attachment_filename=os.path.basename(tar_file)) |
| 504 | + |
447 | 505 | @ns.route('/<job_id>/console') |
448 | 506 | @api.response(403, 'Not Authorized') |
449 | 507 | class Console(Resource): |
|
0 commit comments