blob: 33bf5dd2efb7ea7f1747a6ed5e42e3c5738256c8 [file] [log] [blame]
# -*- coding: utf-8 -*-
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Interface to the AFE RPC server for all moblab code."""
import logging
# pylint: disable=no-name-in-module, import-error
from google.cloud.storage import Client as GcsClient
from moblab_common.moblab_build_connector import exception_handler
# pylint: disable=no-name-in-module, import-error
from google.auth import exceptions as auth_exceptions
class MoblabBuildConnectorException(Exception):
pass
class MoblabBuildConnector(object):
"""
Contains logic for fetching build information from partner Google storage
bucket.
"""
def __init__(self, moblab_bucket_name, storage_client=None):
if not moblab_bucket_name:
raise MoblabBuildConnectorException("Missing bucket name")
self.moblab_bucket_name = moblab_bucket_name
if storage_client:
self.storage_client = storage_client
else:
try:
self.storage_client = GcsClient()
except auth_exceptions.DefaultCredentialsError as e:
logging.info("No credentials loaded")
raise MoblabBuildConnectorException("Invalid Credentials")
@exception_handler(unhandled_exception_message="Encountered API error when getting partial object path.")
def _get_partial_object_path(self, prefix, delimiter):
blob_itr = self.storage_client.bucket(
self.moblab_bucket_name
).list_blobs(prefix=prefix, delimiter=delimiter)
# pylint: disable=pointless-statement
[None for _ in blob_itr]
return [partial_path for partial_path in blob_itr.prefixes]
def get_boards_available(self):
"""Lists the available boards, aka build targets, in the partner bucket.
Returns:
List of strings representing boards.
"""
possible_boards = self._get_partial_object_path(None, "/")
possible_boards = [
board for board in possible_boards if board.endswith("-release/")
]
available_boards = [
board[: -len("-release/")] for board in possible_boards
]
available_boards.sort(key=lambda x: x)
return available_boards
def get_milestones_available(self, board):
"""Lists the available milestones in the partner bucket.
Args:
board (str): Build target name.
Returns:
List of strings representing build versions.
"""
prefix = "%s-release/R" % board
milestones = self._get_partial_object_path(prefix, "-")
milestones = [milestone[len(prefix) : -1] for milestone in milestones]
milestones.sort(key=lambda x: x)
return milestones
def get_builds_for_milestone(self, board, milestone):
"""Lists the available build versions in the partner bucket.
Args:
board (str): Build target name.
milestone (str): The milestone number.
Returns:
List of strings representing build versions.
"""
prefix = "%s-release/%s-" % (board, "R%s" % milestone)
builds = self._get_partial_object_path(prefix, "/")
builds = [build[len(prefix) : -1] for build in builds]
builds.sort(key=lambda x: x)
# local builds are advised to be kept in separate folder
# {board}-local/*
local_prefix = "%s-local/%s-" % (board, "R%s" % milestone)
local_builds = self._get_partial_object_path(local_prefix, "/")
local_builds = [
local_build[len(local_prefix) : -1] for local_build in local_builds
]
return builds + local_builds
@exception_handler(unhandled_exception_message="Encountered API error when checking moblab bucket is in asia.")
def is_moblab_bucket_in_asia(self, bucket_name: str) -> bool:
"""Check the bucket is in Asia.
Args:
bucket_name(str): Bucket name.
Returns:
Boolean
"""
if not bucket_name:
raise ArgumentException("Missing the bucket name")
bucket = GcsClient().bucket(bucket_name)
bucket.reload()
return "asia" in bucket.location.lower()