Scott Zawalski | 20a9b58 | 2011-11-21 11:49:40 -0800 | [diff] [blame] | 1 | #!/usr/bin/python |
| 2 | # |
| 3 | # Copyright 2010 Google Inc. All Rights Reserved. |
| 4 | |
| 5 | """Script to clear lock directories for latest builds; rescheduling tests. |
| 6 | |
| 7 | Running this script will remove all test locks for the latest builds of every |
| 8 | board. Which will cause all tests whose locks were removed to be rescheduled the |
| 9 | next time Test Scheduler runs. The latest build is determined by the contents of |
| 10 | the LATEST file in each board directory. |
| 11 | |
| 12 | By default the script will process all boards under DEFAULT_IMAGES_PATH. To |
| 13 | process only specific boards and/or a different images directory, use the -b |
| 14 | and/or -i options. |
| 15 | |
| 16 | Expected images directory structure looks like: |
| 17 | |
| 18 | <board_0>\LATEST |
| 19 | <board_0>\<build_0>\netbook_<test_0> |
| 20 | <board_0>\<build_0>\netbook_<test_1> |
| 21 | . |
| 22 | . |
| 23 | . |
| 24 | <board_0>\<build_0>\netbook_<test_n> |
| 25 | . |
| 26 | . |
| 27 | . |
| 28 | <board_n>\LATEST |
| 29 | <board_n>\<build_0>\netbook_<test_0> |
| 30 | <board_n>\<build_0>\netbook_<test_n> |
| 31 | """ |
| 32 | |
| 33 | __author__ = 'dalecurtis@google.com (Dale Curtis)' |
| 34 | |
| 35 | import optparse |
| 36 | import os |
| 37 | |
| 38 | |
| 39 | # Path to Dev Server's images directory. |
| 40 | DEFAULT_IMAGES_PATH = '/usr/local/google/images' |
| 41 | |
| 42 | |
| 43 | def ParseOptions(): |
| 44 | """Parse command line options. Returns options structure.""" |
| 45 | |
| 46 | parser = optparse.OptionParser('usage: %prog [options]') |
| 47 | |
| 48 | parser.add_option('-b', '--boards', dest='boards', |
| 49 | help='Comma separated list of boards to process. By default' |
| 50 | ' all boards in the images directory will be processed.') |
| 51 | parser.add_option('-i', '--images', dest='images', |
| 52 | help='Path to Dev Server images directory. Defaults to %s' % |
| 53 | DEFAULT_IMAGES_PATH, default=DEFAULT_IMAGES_PATH) |
| 54 | |
| 55 | options = parser.parse_args()[0] |
| 56 | |
| 57 | if not os.path.exists(options.images): |
| 58 | parser.error('The specified images directory (%s) does not exist. Please ' |
| 59 | 'specify another.' % options.images) |
| 60 | |
| 61 | if options.boards: |
| 62 | options.boards = options.boards.split(',') |
| 63 | |
| 64 | return options |
| 65 | |
| 66 | |
| 67 | def main(): |
| 68 | options = ParseOptions() |
| 69 | |
| 70 | os.chdir(options.images) |
| 71 | |
| 72 | # Build board listing. |
| 73 | if options.boards: |
| 74 | boards = options.boards |
| 75 | else: |
| 76 | boards = [board for board in os.listdir('.') if os.path.isdir(board)] |
| 77 | |
| 78 | for board in boards: |
| 79 | latest_path = os.path.join(board, 'LATEST') |
| 80 | |
| 81 | # Make sure directory contains a LATEST file. |
| 82 | if not os.path.exists(latest_path): |
| 83 | continue |
| 84 | |
| 85 | build_path = os.path.join(board, open(latest_path, 'r').read().strip()) |
| 86 | |
| 87 | # Make sure LATEST file points to a valid build. |
| 88 | if not os.path.exists(build_path): |
| 89 | continue |
| 90 | |
| 91 | # Remove test locks in latest build directory. |
| 92 | for test in os.listdir(build_path): |
| 93 | test_path = os.path.join(build_path, test) |
| 94 | |
| 95 | # Only remove directories we know (well, pretty sure) are test locks. |
| 96 | if not os.path.isdir(test_path) or not test.startswith('netbook_'): |
| 97 | continue |
| 98 | |
| 99 | print 'Removing lock %s' % test_path |
| 100 | os.rmdir(test_path) |
| 101 | |
| 102 | |
| 103 | if __name__ == '__main__': |
| 104 | main() |