1# Copyright 2015 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5# TODO(dtu): Merge this file with its counterparts in catapult_build/ when 6# dashboard and PI migrate to Google Cloud SDK. 7 8import contextlib 9import os 10import re 11import shutil 12import subprocess 13import tempfile 14import sys 15 16sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) 17from base import constants 18 19 20def Modules(root_dir): 21 """Yields module names in root_dir.""" 22 for root, _, files in os.walk(root_dir): 23 for file_name in files: 24 if os.path.splitext(file_name)[1] == '.yaml': 25 yield os.path.basename(root) 26 break 27 28 29def Yamls(root_dir): 30 """Yields yaml files in root_dir.""" 31 for root, _, files in os.walk(root_dir): 32 for file_name in files: 33 if os.path.splitext(file_name)[1] == '.yaml': 34 yield os.path.join(root, file_name) 35 36 37@contextlib.contextmanager 38def TempAppDir(root_dir, symlinks): 39 """Sets up and tears down a directory for deploying or running an app. 40 41 Args: 42 root_dir: The root directory of the app. 43 symlinks: If true, use symbolic links instead of copying files. This allows 44 the dev server to detect file changes in the repo, and is faster. 45 46 Yields: 47 The path to the temporary directory. 48 """ 49 if symlinks: 50 link = os.symlink 51 else: 52 def Link(src, dest): 53 if os.path.isdir(src): 54 return shutil.copytree(src, dest) 55 else: 56 return shutil.copy2(src, dest) 57 link = Link 58 59 gcloud_lib_dir = _GcloudLibDir() 60 temp_app_dir = tempfile.mkdtemp(prefix='app-') 61 try: 62 for module in Modules(root_dir): 63 module_source_dir = os.path.join(root_dir, module) 64 module_dest_dir = os.path.join(temp_app_dir, module) 65 os.mkdir(module_dest_dir) 66 67 # Copy/symlink module into app directory. 68 for node in os.listdir(module_source_dir): 69 link(os.path.join(module_source_dir, node), 70 os.path.join(module_dest_dir, node)) 71 72 # Copy/symlink base/ into module directory. 73 link(os.path.join(root_dir, 'base'), 74 os.path.join(module_dest_dir, 'base')) 75 76 # Copy/symlink Gcloud library dependencies into module directory. 77 third_party_dest_dir = os.path.join(module_dest_dir, 'third_party') 78 os.mkdir(third_party_dest_dir) 79 open(os.path.join(third_party_dest_dir, '__init__.py'), 'w').close() 80 for library in constants.GCLOUD_THIRD_PARTY_LIBRARIES: 81 link(os.path.join(gcloud_lib_dir, library), 82 os.path.join(third_party_dest_dir, library)) 83 84 yield temp_app_dir 85 finally: 86 shutil.rmtree(temp_app_dir) 87 88 89def _GcloudLibDir(): 90 process = subprocess.Popen(['gcloud', 'info'], stdout=subprocess.PIPE) 91 stdout, _ = process.communicate() 92 gcloud_root_dir = re.search(r'^Installation Root: \[(.*)\]$', stdout, 93 flags=re.MULTILINE).groups()[0] 94 return os.path.join(gcloud_root_dir, 'lib', 'third_party') 95