• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# Copyright (C) 2017 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17import logging
18import os
19import re
20import zipfile
21
22from host_controller.build import build_provider
23from host_controller.utils.gcp import gcs_utils
24from vts.utils.python.common import cmd_utils
25
26_GCLOUD_AUTH_ENV_KEY = "run_gcs_key"
27
28
29class BuildProviderGCS(build_provider.BuildProvider):
30    """A build provider for GCS (Google Cloud Storage)."""
31
32    def __init__(self):
33        super(BuildProviderGCS, self).__init__()
34        if _GCLOUD_AUTH_ENV_KEY in os.environ:
35            gcloud_path = BuildProviderGCS.GetGcloudPath()
36            if gcloud_path is not None:
37                auth_cmd = "%s auth activate-service-account --key-file=%s" % (
38                    gcloud_path, os.environ[_GCLOUD_AUTH_ENV_KEY])
39                _, stderr, ret_code = cmd_utils.ExecuteOneShellCommand(
40                    auth_cmd)
41                if ret_code == 0:
42                    logging.info(stderr)
43                else:
44                    logging.error(stderr)
45
46    @staticmethod
47    def GetGcloudPath():
48        """Returns the gcloud file path if found; None otherwise."""
49        sh_stdout, _, ret_code = cmd_utils.ExecuteOneShellCommand(
50            "which gcloud")
51        if ret_code == 0:
52            return sh_stdout.strip()
53        else:
54            logging.error("`gcloud` doesn't exist on the host; "
55                          "please install Google Cloud SDK before retrying.")
56            return None
57
58    def Fetch(self, path, full_device_images=False, set_suite_as=None):
59        """Fetches Android device artifact file(s) from GCS.
60
61        Args:
62            path: string, the path of a directory which keeps artifacts.
63            set_suite_as: string, the test suite name to use for the given
64                          artifact. Used when the file name does not follow
65                          the standard "android-*ts.zip" file name pattern.
66
67        Returns:
68            a dict containing the device image info.
69            a dict containing the test suite package info.
70            a dict containing the info about custom tool files.
71        """
72        if not path.startswith("gs://"):
73            path = "gs://" + re.sub("^/*", "", path)
74        path = re.sub("/*$", "", path)
75        gsutil_path = gcs_utils.GetGsutilPath()
76        if gsutil_path:
77            temp_dir_path = self.CreateNewTmpDir()
78            # IsGcsFile returns False if path is directory or doesn't exist.
79            # cp command returns non-zero if path doesn't exist.
80            if not gcs_utils.IsGcsFile(gsutil_path, path):
81                dest_path = temp_dir_path
82                if "latest.zip" in path:
83                    gsutil_ls_path = re.sub("latest.zip", "*.zip", path)
84                    lines_gsutil_ls = gcs_utils.List(gsutil_path, gsutil_ls_path)
85                    if lines_gsutil_ls:
86                        lines_gsutil_ls.sort()
87                        path = lines_gsutil_ls[-1]
88                        copy_command = "%s cp %s %s" % (gsutil_path, path,
89                                                        temp_dir_path)
90                    else:
91                        logging.error(
92                            "There is no file(s) that matches the URL %s.",
93                            path)
94                        return (self.GetDeviceImage(),
95                                self.GetTestSuitePackage(),
96                                self.GetAdditionalFile())
97                else:
98                    copy_command = "%s cp -r %s/* %s" % (gsutil_path, path,
99                                                         temp_dir_path)
100            else:
101                dest_path = os.path.join(temp_dir_path, os.path.basename(path))
102                copy_command = "%s cp %s %s" % (gsutil_path, path,
103                                                temp_dir_path)
104
105            _, _, ret_code = cmd_utils.ExecuteOneShellCommand(copy_command)
106            if ret_code == 0:
107                self.SetFetchedFile(dest_path, temp_dir_path,
108                                    full_device_images, set_suite_as)
109            else:
110                logging.error("Error in copy file from GCS (code %s).",
111                              ret_code)
112        return (self.GetDeviceImage(), self.GetTestSuitePackage(),
113                self.GetAdditionalFile())
114