blob: 6d7670b8aa5d4d0fcdfce99635290bfd4eb2b6b6 [file] [log] [blame]
Michael Tang97d188c2016-06-25 11:18:42 -07001# Copyright 2016 The Chromium OS 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"""Script to archive old Autotest results to Google Storage.
6
7Uses gsutil to archive files to the configured Google Storage bucket.
8Upon successful copy, the local results directory is deleted.
9"""
10
Michael Tang0f553bd2017-06-16 17:38:45 -070011from __future__ import print_function
12
Michael Tang97d188c2016-06-25 11:18:42 -070013import os
14
15from apiclient import discovery
Michael Tang0f553bd2017-06-16 17:38:45 -070016from apiclient import errors
Michael Tang97d188c2016-06-25 11:18:42 -070017from oauth2client.client import ApplicationDefaultCredentialsError
18from oauth2client.client import GoogleCredentials
Michael Tang0f553bd2017-06-16 17:38:45 -070019from chromite.lib import cros_logging as logging
Michael Tang97d188c2016-06-25 11:18:42 -070020
21# Cloud service
Michael Tang97d188c2016-06-25 11:18:42 -070022PUBSUB_SERVICE_NAME = 'pubsub'
23PUBSUB_VERSION = 'v1beta2'
24PUBSUB_SCOPES = ['https://www.googleapis.com/auth/pubsub']
25# number of retry to publish an event.
Michael Tang0f553bd2017-06-16 17:38:45 -070026DEFAULT_PUBSUB_NUM_RETRIES = 3
Michael Tang97d188c2016-06-25 11:18:42 -070027
Michael Tang56cbe942017-05-19 09:30:49 -070028class PubSubException(Exception):
29 """Exception to be raised when the test to push to prod failed."""
30 pass
Michael Tang97d188c2016-06-25 11:18:42 -070031
32
Michael Tang56cbe942017-05-19 09:30:49 -070033class PubSubClient(object):
Michael Tang0f553bd2017-06-16 17:38:45 -070034 """A generic pubsub client."""
35 def __init__(self, credential_file=None):
Michael Tang56cbe942017-05-19 09:30:49 -070036 """Constructor for PubSubClient.
Michael Tang97d188c2016-06-25 11:18:42 -070037
Michael Tang0f553bd2017-06-16 17:38:45 -070038 Args:
39 credential_file: The credential filename.
40
41 Raises:
42 PubSubException if the credential file does not exist or corrupted.
Michael Tang56cbe942017-05-19 09:30:49 -070043 """
Michael Tang0f553bd2017-06-16 17:38:45 -070044 if not credential_file:
45 raise PubSubException('You need to specify a credential file.')
Michael Tang56cbe942017-05-19 09:30:49 -070046 self.credential_file = credential_file
47 self.credential = self._get_credential()
Michael Tang97d188c2016-06-25 11:18:42 -070048
Michael Tang56cbe942017-05-19 09:30:49 -070049 def _get_credential(self):
50 """Gets the pubsub service api handle."""
51 if not os.path.isfile(self.credential_file):
52 logging.error('No credential file found')
Michael Tang0f553bd2017-06-16 17:38:45 -070053 raise PubSubException('Credential file does not exist:' +
54 self.credential_file)
Michael Tang56cbe942017-05-19 09:30:49 -070055 try:
56 credential = GoogleCredentials.from_stream(self.credential_file)
57 if credential.create_scoped_required():
58 credential = credential.create_scoped(PUBSUB_SCOPES)
59 return credential
60 except ApplicationDefaultCredentialsError as ex:
Michael Tang0f553bd2017-06-16 17:38:45 -070061 logging.exception('Failed to get credential:%s', ex)
62 except errors.Error as e:
63 logging.exception('Failed to get the pubsub service handle:%s', e)
Michael Tang56cbe942017-05-19 09:30:49 -070064
Michael Tang0f553bd2017-06-16 17:38:45 -070065 raise PubSubException('Credential file %s does not exists:' %
66 self.credential_file)
Michael Tang56cbe942017-05-19 09:30:49 -070067
68 def _get_pubsub_service(self):
69 try:
70 return discovery.build(PUBSUB_SERVICE_NAME, PUBSUB_VERSION,
71 credentials=self.credential)
Michael Tang0f553bd2017-06-16 17:38:45 -070072 except errors.Error as e:
73 logging.exception('Failed to get pubsub resource object:%s', e)
74 raise PubSubException('Failed to get pubsub resource object')
Michael Tang56cbe942017-05-19 09:30:49 -070075
Michael Tang0f553bd2017-06-16 17:38:45 -070076 def publish_notifications(self, topic, messages=None):
Michael Tang56cbe942017-05-19 09:30:49 -070077 """Publishes a test result notification to a given pubsub topic.
78
79 @param topic: The Cloud pubsub topic.
80 @param messages: A list of notification messages.
81
82 @returns A list of pubsub message ids, and empty if fails.
83
84 @raises PubSubException if failed to publish the notification.
85 """
Michael Tang0f553bd2017-06-16 17:38:45 -070086 if not messages:
87 return None
88
Michael Tang56cbe942017-05-19 09:30:49 -070089 pubsub = self._get_pubsub_service()
Michael Tang97d188c2016-06-25 11:18:42 -070090 try:
91 body = {'messages': messages}
Michael Tang0f553bd2017-06-16 17:38:45 -070092 resp = pubsub.projects().topics().publish(
93 topic=topic, body=body).execute(
94 num_retries=DEFAULT_PUBSUB_NUM_RETRIES)
95 msgIds = []
Michael Tang97d188c2016-06-25 11:18:42 -070096 if resp:
97 msgIds = resp.get('messageIds')
98 if msgIds:
99 logging.debug('Published notification message')
Michael Tang0f553bd2017-06-16 17:38:45 -0700100 else:
101 logging.error('Failed to published notification message')
102 return msgIds
103 except errors.Error as e:
104 logging.exception('Failed to publish test result notification:%s',
105 e)
106 raise PubSubException('Failed to publish the notification')