blob: 4342bf23fd444fc23cf453c96030fb5f773f4c3c [file] [log] [blame]
Chris Sosa47a7d4e2012-03-28 11:26:55 -07001# Copyright (c) 2012 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"""Module containing gsutil helper methods."""
6
7import subprocess
Chris Sosa101fd862012-06-12 17:44:53 -07008import time
Chris Sosa47a7d4e2012-03-28 11:26:55 -07009
10GSUTIL_ATTEMPTS = 5
11
12
13class GSUtilError(Exception):
14 """Exception raises when we run into an error running gsutil."""
15 pass
16
17
18def GSUtilRun(cmd, err_msg):
19 """Runs a GSUTIL command up to GSUTIL_ATTEMPTS number of times.
20
Chris Sosa101fd862012-06-12 17:44:53 -070021 Attempts are tried with exponential backoff.
22
Chris Sosa47a7d4e2012-03-28 11:26:55 -070023 Returns:
24 stdout of the called gsutil command.
25 Raises:
26 subprocess.CalledProcessError if all attempt to run gsutil cmd fails.
27 """
28 proc = None
Chris Sosa101fd862012-06-12 17:44:53 -070029 sleep_timeout = 1
Chris Sosa47a7d4e2012-03-28 11:26:55 -070030 for _attempt in range(GSUTIL_ATTEMPTS):
31 # Note processes can hang when capturing from stderr. This command
32 # specifically doesn't pipe stderr.
33 proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
34 stdout, _stderr = proc.communicate()
35 if proc.returncode == 0:
36 return stdout
Chris Sosa101fd862012-06-12 17:44:53 -070037
38 time.sleep(sleep_timeout)
39 sleep_timeout *= 2
40
Chris Sosa47a7d4e2012-03-28 11:26:55 -070041 else:
42 raise GSUtilError('%s GSUTIL cmd %s failed with return code %d' % (
43 err_msg, cmd, proc.returncode))
44
45
46def DownloadFromGS(src, dst):
47 """Downloads object from gs_url |src| to |dst|.
48
49 Raises:
50 GSUtilError: if an error occurs during the download.
51 """
52 cmd = 'gsutil cp %s %s' % (src, dst)
53 msg = 'Failed to download "%s".' % src
54 GSUtilRun(cmd, msg)