Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: infra/tools/restart/restart.py

Issue 1233243007: Ask for confirmation before committing. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase onto latest master. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « infra/tools/restart/__main__.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import contextlib 5 import contextlib
6 import datetime 6 import datetime
7 import distutils.util
7 import json 8 import json
8 import logging 9 import logging
9 import os 10 import os
10 import re 11 import re
11 import shutil 12 import shutil
12 import subprocess 13 import subprocess
13 import sys 14 import sys
14 import tempfile 15 import tempfile
15 16
16 17
17 from infra.libs.time_functions import zulu 18 from infra.libs.time_functions import zulu
18 19
19 20
20 LOGGER = logging.getLogger(__name__) 21 LOGGER = logging.getLogger(__name__)
21 22
23 MM_REPO = 'https://chrome-internal.googlesource.com/infradata/master-manager'
24
22 25
23 class MasterNotFoundException(Exception): 26 class MasterNotFoundException(Exception):
24 pass 27 pass
25 28
26 29
27 def add_argparse_options(parser): 30 def add_argparse_options(parser):
28 parser.add_argument( 31 parser.add_argument(
29 'masters', type=str, nargs='+', 32 'masters', type=str, nargs='+',
30 help='Master(s) to restart. "master." prefix can be omitted.') 33 help='Master(s) to restart. "master." prefix can be omitted.')
31 parser.add_argument( 34 parser.add_argument(
32 '-m', '--minutes-in-future', default=15, type=int, 35 '-m', '--minutes-in-future', default=15, type=int,
33 help='how many minutes in the future to schedule the restart. ' 36 help='how many minutes in the future to schedule the restart. '
34 'use 0 for "now." default %(default)d') 37 'use 0 for "now." default %(default)d')
35 parser.add_argument('-b', '--bug', default=None, type=str, 38 parser.add_argument('-b', '--bug', default=None, type=str,
36 help='Bug containing master restart request.') 39 help='Bug containing master restart request.')
40 parser.add_argument(
41 '-f', '--force', action='store_true',
42 help='don\'t ask for confirmation, just commit')
37 43
38 44
39 def get_restart_time(delta): 45 def get_restart_time(delta):
40 """Returns a zulu time string of when to restart a master, now + delta.""" 46 """Returns a zulu time string of when to restart a master, now + delta."""
41 restart_time = datetime.datetime.utcnow() + delta 47 restart_time = datetime.datetime.utcnow() + delta
42 return zulu.to_zulu_string(restart_time) 48 return zulu.to_zulu_string(restart_time)
43 49
44 50
45 @contextlib.contextmanager 51 @contextlib.contextmanager
46 def get_master_state_checkout(): 52 def get_master_state_checkout():
47 target_dir = tempfile.mkdtemp() 53 target_dir = tempfile.mkdtemp()
48 mm_repo = 'https://chrome-internal.googlesource.com/infradata/master-manager'
49 try: 54 try:
50 LOGGER.info('Cloning %s into %s' % (mm_repo, target_dir)) 55 LOGGER.info('Cloning %s into %s' % (MM_REPO, target_dir))
51 subprocess.call(['git', 'clone', mm_repo, target_dir]) 56 subprocess.call(['git', 'clone', MM_REPO, target_dir])
52 LOGGER.info('done') 57 LOGGER.info('done')
53 yield target_dir 58 yield target_dir
54 finally: 59 finally:
55 shutil.rmtree(target_dir) 60 shutil.rmtree(target_dir)
56 61
57 62
58 def commit(target, masters, bug): 63 def commit(target, masters, bug, timestring, delta, force):
59 """Commits the local CL via the CQ.""" 64 """Commits the local CL via the CQ."""
60 desc = 'Restarting master(s) %s' % ', '.join(masters) 65 desc = 'Restarting master(s) %s' % ', '.join(masters)
61 if bug: 66 if bug:
62 desc = '%s\nBUG=%s' % (desc, bug) 67 desc = '%s\nBUG=%s' % (desc, bug)
63 subprocess.check_call( 68 subprocess.check_call(
64 ['git', 'commit', '--all', '--message', desc], cwd=target) 69 ['git', 'commit', '--all', '--message', desc], cwd=target)
70
71 print
72 print 'Restarting the following masters in %d minutes (%s)' % (
73 delta.total_seconds() / 60, timestring)
74 for master in sorted(masters):
75 print ' %s' % master
76 print
77
78 print "This will upload a CL for master_manager.git, TBR an owner, and "
79 print "commit the CL through the CQ."
80 print
81
82 if not force:
83 print 'Commit? [Y/n]:',
84 input_string = raw_input()
85 if input_string != '' and not distutils.util.strtobool(input_string):
86 print 'Aborting.'
87 return
88
89 print 'To cancel, edit desired_master_state.json in %s.' % MM_REPO
90 print
91
65 LOGGER.info('Uploading to Rietveld and CQ.') 92 LOGGER.info('Uploading to Rietveld and CQ.')
66 subprocess.check_call( 93 subprocess.check_call(
67 ['git', 'cl', 'upload', '-m', desc, '-t', desc, 94 ['git', 'cl', 'upload', '-m', desc, '-t', desc,
68 '--tbr-owners', '-c', '-f'], cwd=target) 95 '--tbr-owners', '-c', '-f'], cwd=target)
69 96
70 97
71 def run(masters, delta, bug): 98 def run(masters, delta, bug, force):
72 """Restart all the masters in the list of masters. 99 """Restart all the masters in the list of masters.
73 100
74 Schedules the restart for now + delta. 101 Schedules the restart for now + delta.
75 """ 102 """
76 # Step 1: Acquire a clean master state checkout. 103 # Step 1: Acquire a clean master state checkout.
77 # This repo is too small to consider caching. 104 # This repo is too small to consider caching.
78 with get_master_state_checkout() as master_state_dir: 105 with get_master_state_checkout() as master_state_dir:
79 master_state_json = os.path.join( 106 master_state_json = os.path.join(
80 master_state_dir, 'desired_master_state.json') 107 master_state_dir, 'desired_master_state.json')
81 restart_time = get_restart_time(delta) 108 restart_time = get_restart_time(delta)
(...skipping 16 matching lines...) Expand all
98 'desired_state': 'running', 'transition_time_utc': restart_time 125 'desired_state': 'running', 'transition_time_utc': restart_time
99 }) 126 })
100 127
101 LOGGER.info('Writing back to JSON file, %d new entries' % len(master_state)) 128 LOGGER.info('Writing back to JSON file, %d new entries' % len(master_state))
102 with open(master_state_json, 'w') as f: 129 with open(master_state_json, 'w') as f:
103 json.dump( 130 json.dump(
104 master_state, f, sort_keys=True, indent=2, separators=(',', ':')) 131 master_state, f, sort_keys=True, indent=2, separators=(',', ':'))
105 132
106 # Step 3: Send the patch to Rietveld and commit it via the CQ. 133 # Step 3: Send the patch to Rietveld and commit it via the CQ.
107 LOGGER.info('Committing back into repository') 134 LOGGER.info('Committing back into repository')
108 commit(master_state_dir, masters, bug) 135 commit(master_state_dir, masters, bug, restart_time, delta, force)
OLDNEW
« no previous file with comments | « infra/tools/restart/__main__.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698