auto_delete_nightly_test_data.py revision 37828578795f39daadcebe05cacc522d629b5c9c
1#!/usr/bin/python
2
3"""A crontab script to delete night test data."""
4__author__ = 'shenhan@google.com (Han Shen)'
5
6import datetime
7import optparse
8import os
9import re
10import sys
11
12from utils import command_executer
13from utils import constants
14from utils import misc
15
16DIR_BY_WEEKDAY = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
17
18
19def CleanNumberedDir(s, dry_run=False):
20  """Deleted directories under each dated_dir."""
21  chromeos_dirs = [os.path.join(s, x) for x in os.listdir(s)
22                   if misc.IsChromeOsTree(os.path.join(s, x))]
23  ce = command_executer.GetCommandExecuter(log_level="none")
24  all_succeeded = True
25  for cd in chromeos_dirs:
26    if misc.DeleteChromeOsTree(cd, dry_run=dry_run):
27      print 'Successfully removed chromeos tree "{0}".'.format(cd)
28    else:
29      all_succeeded = False
30      print 'Failed to remove chromeos tree "{0}", please check.'.format(cd)
31
32  if not all_succeeded:
33    print 'Failed to delete at least one chromeos tree, please check.'
34    return False
35
36  ## Now delete the numbered dir Before forcibly removing the directory, just
37  ## check 's' to make sure it is sane.  A valid dir to be removed must be
38  ## '/usr/local/google/crostc/(SUN|MON|TUE...|SAT)'.
39  valid_dir_pattern = ('^' + constants.CROSTC_WORKSPACE + '/(' +
40                       '|'.join(DIR_BY_WEEKDAY) + ')')
41  if not re.search(valid_dir_pattern, s):
42    print ('Trying to delete an invalid dir "{0}" (must match "{1}"), '
43           'please check.'.format(s, valid_dir_pattern))
44    return False
45
46  cmd = 'rm -fr {0}'.format(s)
47  if dry_run:
48    print cmd
49  else:
50    if ce.RunCommand(cmd, return_output=False, print_to_console=True,
51                     terminated_timeout=480) == 0:
52      print 'Successfully removed "{0}".'.format(s)
53    else:
54      all_succeeded = False
55      print 'Failed to remove "{0}", please check.'.format(s)
56  return all_succeeded
57
58
59def CleanDatedDir(dated_dir, dry_run=False):
60  # List subdirs under dir
61  subdirs = [os.path.join(dated_dir, x) for x in os.listdir(dated_dir)
62             if os.path.isdir(os.path.join(dated_dir, x))]
63  all_succeeded = True
64  for s in subdirs:
65    if not CleanNumberedDir(s, dry_run):
66      all_succeeded = False
67  return all_succeeded
68
69
70def ProcessArguments(argv):
71  """Process arguments."""
72  parser = optparse.OptionParser(
73      description='Automatically delete nightly test data directories.',
74      usage='auto_delete_nightly_test_data.py options')
75  parser.add_option('-d', '--dry_run', dest='dry_run',
76                    default=False, action='store_true',
77                    help='Only print command line, do not execute anything.')
78  parser.add_option('--days_to_perserve', dest='days_to_preserve', default=3,
79                    help=('Specify the number of days (not including today), '
80                          'test data generated on these days will *NOT* be '
81                          'deleted. Defaults to 3.'))
82  options, _ = parser.parse_args(argv)
83  return options
84
85
86def Main(argv):
87  """Delete nightly test data directories."""
88  options = ProcessArguments(argv)
89  # Function 'isoweekday' returns 1(Monday) - 7 (Sunday).
90  d = datetime.datetime.today().isoweekday()
91  # We go back 1 week, delete from that day till we are
92  # options.days_to_preserve away from today.
93  s = d - 7
94  e = d - int(options.days_to_preserve)
95  rv = 0
96  for i in range(s + 1, e):
97    if i <= 0:
98      ## Wrap around if index is negative.  6 is from i + 7 - 1, because
99      ## DIR_BY_WEEKDAY starts from 0, while isoweekday is from 1-7.
100      dated_dir = DIR_BY_WEEKDAY[i+6]
101    else:
102      dated_dir = DIR_BY_WEEKDAY[i-1]
103    rv += 0 if CleanDatedDir(os.path.join(
104        constants.CROSTC_WORKSPACE, dated_dir), options.dry_run) else 1
105  return rv
106
107
108if __name__ == '__main__':
109  retval = Main(sys.argv)
110  sys.exit(retval)
111