|
28 | 28 | from __future__ import print_function
|
29 | 29 |
|
30 | 30 | import argparse
|
31 |
| -import ast |
32 | 31 | import base64
|
33 | 32 | import contextlib
|
34 | 33 | import json
|
35 | 34 | import os
|
36 |
| -import platform |
37 | 35 | import re
|
38 | 36 | import shutil
|
39 | 37 | import subprocess
|
40 | 38 | import sys
|
41 | 39 | import tempfile
|
42 | 40 | import time
|
43 | 41 | import uuid
|
| 42 | +from distutils.spawn import find_executable |
44 | 43 |
|
45 | 44 | from cryptography import fernet
|
46 | 45 | import google.auth
|
|
53 | 52 | from six.moves import configparser
|
54 | 53 |
|
55 | 54 | DEFAULT_SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]
|
| 55 | +EXECUTABLES = ['gcsfuse', 'cloud_sql_proxy', 'mysql', 'gcloud', 'gsutil'] |
56 | 56 |
|
57 | 57 |
|
58 | 58 | def parse_args():
|
@@ -295,7 +295,7 @@ def create_service_account_key(iam_client, project, service_account_name):
|
295 | 295 | )
|
296 | 296 | .execute()
|
297 | 297 | )
|
298 |
| - service_account_key_decoded = ast.literal_eval( |
| 298 | + service_account_key_decoded = json.loads( |
299 | 299 | base64.b64decode(service_account_key.get("privateKeyData", ""))
|
300 | 300 | .decode("utf-8")
|
301 | 301 | )
|
@@ -335,16 +335,10 @@ def get_sql_instance_service_account(sql_client, project, instance):
|
335 | 335 |
|
336 | 336 |
|
337 | 337 | def grant_rw_permissions(gcs_bucket, service_account):
|
338 |
| - if subprocess.call( |
339 |
| - [ |
340 |
| - "gsutil", |
341 |
| - "acl", |
342 |
| - "ch", |
343 |
| - "-u", |
344 |
| - service_account + ":O", |
345 |
| - "gs://" + gcs_bucket.name, |
346 |
| - ] |
347 |
| - ): |
| 338 | + try: |
| 339 | + gcs_bucket.acl.user(service_account).grant_owner() |
| 340 | + gcs_bucket.acl.save() |
| 341 | + except Exception: |
348 | 342 | print(
|
349 | 343 | "Failed to set acls for service account {} on bucket {}.".format(
|
350 | 344 | service_account, gcs_bucket.name
|
@@ -544,11 +538,10 @@ def import_data(
|
544 | 538 | if proxy_subprocess:
|
545 | 539 | proxy_subprocess.kill()
|
546 | 540 | if fuse_dir:
|
547 |
| - if platform.system().lower().startswith('darwin'): |
548 |
| - # Mac OSX does not have fusermount |
549 |
| - subprocess.call(["umount", fuse_dir]) |
550 |
| - else: |
| 541 | + try: |
551 | 542 | subprocess.call(["fusermount", "-u", fuse_dir])
|
| 543 | + except OSError: |
| 544 | + subprocess.call(["umount", fuse_dir]) |
552 | 545 | if tmp_dir_name:
|
553 | 546 | shutil.rmtree(tmp_dir_name)
|
554 | 547 |
|
@@ -577,7 +570,9 @@ def copy_database(project, existing_env, new_env, running_as_service_account):
|
577 | 570 | try:
|
578 | 571 | # create default creds clients
|
579 | 572 | default_credentials, _ = google.auth.default(scopes=DEFAULT_SCOPES)
|
580 |
| - storage_client = storage.Client(credentials=default_credentials) |
| 573 | + storage_client = storage.Client( |
| 574 | + project=project, credentials=default_credentials |
| 575 | + ) |
581 | 576 | iam_client = discovery.build(
|
582 | 577 | "iam", "v1", credentials=default_credentials
|
583 | 578 | )
|
@@ -723,8 +718,19 @@ def clone_environment(
|
723 | 718 | )
|
724 | 719 |
|
725 | 720 |
|
| 721 | +def check_executables(): |
| 722 | + not_found = [ |
| 723 | + executable for executable in EXECUTABLES |
| 724 | + if not find_executable(executable) |
| 725 | + ] |
| 726 | + if not_found: |
| 727 | + print('Required executables not found: {}'.format(' '.join(not_found))) |
| 728 | + sys.exit(1) |
| 729 | + |
| 730 | + |
726 | 731 | if __name__ == "__main__":
|
727 | 732 | args = parse_args()
|
| 733 | + check_executables() |
728 | 734 | clone_environment(
|
729 | 735 | args.project,
|
730 | 736 | args.location,
|
|
0 commit comments