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

Side by Side Diff: infra/tools/master_manager/__main__.py

Issue 1114303002: Abort master management if the current hostname doesn't match the master's. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase onto latest master. Created 5 years, 7 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/libs/buildbot/master.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 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright 2015 Google Inc. All Rights Reserved. 2 # Copyright 2015 Google Inc. All Rights Reserved.
3 # pylint: disable=F0401 3 # pylint: disable=F0401
4 4
5 """Start, restart and shut down masters as needed.""" 5 """Start, restart and shut down masters as needed."""
6 6
7 import argparse 7 import argparse
8 import logging 8 import logging
9 import os 9 import os
10 import socket
10 import subprocess 11 import subprocess
11 import sys 12 import sys
12 13
13 from functools import partial 14 from functools import partial
14 15
15 from infra.libs import logs 16 from infra.libs import logs
16 from infra.libs.buildbot import master 17 from infra.libs.buildbot import master
17 from infra.libs.service_utils import daemon 18 from infra.libs.service_utils import daemon
18 from infra.libs.service_utils import outer_loop 19 from infra.libs.service_utils import outer_loop
19 from infra.services.master_lifecycle import buildbot_state 20 from infra.services.master_lifecycle import buildbot_state
(...skipping 11 matching lines...) Expand all
31 parser.add_argument('transition_time_utc', nargs='?', type=float, 32 parser.add_argument('transition_time_utc', nargs='?', type=float,
32 help='seconds since the UTC epoch to trigger the state') 33 help='seconds since the UTC epoch to trigger the state')
33 parser.add_argument('--list-all-states', action='store_true', 34 parser.add_argument('--list-all-states', action='store_true',
34 help='list all states with their actions and exit') 35 help='list all states with their actions and exit')
35 parser.add_argument('--enable-gclient-sync', action='store_true', 36 parser.add_argument('--enable-gclient-sync', action='store_true',
36 help='perform a gclient sync before every master start') 37 help='perform a gclient sync before every master start')
37 parser.add_argument('--emergency-file', 38 parser.add_argument('--emergency-file',
38 default='.stop_master_lifecycle', 39 default='.stop_master_lifecycle',
39 help='filename of the emergency stop file. if this file is found in the ' 40 help='filename of the emergency stop file. if this file is found in the '
40 'master directory, exit immediately') 41 'master directory, exit immediately')
42 parser.add_argument('--hostname',
43 default=socket.getfqdn(),
44 help='override local hostname (currently %defaults)')
agable 2015/05/05 18:58:29 %defaults? I think you need parens "%(default)s".
ghost stip (do not use) 2015/05/05 23:41:34 yes I did! thanks
41 parser.add_argument('--prod', action='store_true', 45 parser.add_argument('--prod', action='store_true',
42 help='actually run commands instead of printing them.') 46 help='actually run commands instead of printing them.')
43 parser.add_argument('--loop', action='store_true', 47 parser.add_argument('--loop', action='store_true',
44 help='repeatedly run the state machine. will not terminate unless killed') 48 help='repeatedly run the state machine. will not terminate unless killed')
45 parser.add_argument('--loop-sleep-secs', type=int, default=5, 49 parser.add_argument('--loop-sleep-secs', type=int, default=5,
46 help='how many seconds to wait between loop runs. default %(default)s') 50 help='how many seconds to wait between loop runs. default %(default)s')
47 parser.add_argument('--connection-timeout', type=int, default=30, 51 parser.add_argument('--connection-timeout', type=int, default=30,
48 help='how many seconds to wait for a master http request before timing ' 52 help='how many seconds to wait for a master http request before timing '
49 'out.') 53 'out.')
50 outer_loop.add_argparse_options(parser) 54 outer_loop.add_argparse_options(parser)
51 logs.add_argparse_options(parser) 55 logs.add_argparse_options(parser)
52 56
53 args = parser.parse_args() 57 args = parser.parse_args()
54 logs.process_argparse_options(args) 58 logs.process_argparse_options(args)
55 59
56 if not args.list_all_states: 60 if not args.list_all_states:
57 if not args.directory: 61 if not args.directory:
58 parser.error('A master directory must be specified.') 62 parser.error('A master directory must be specified.')
59 if not args.transition_time_utc: 63 if not args.transition_time_utc:
60 parser.error('A transition time must be specified.') 64 parser.error('A transition time must be specified.')
61 if not args.desired_state: 65 if not args.desired_state:
62 parser.error('A desired state must be specified.') 66 parser.error('A desired state must be specified.')
63 return args 67 return args
64 68
65 69
70 def master_hostname_is_valid(local_hostname, abs_master_directory, logger):
71 master_hostname = master.get_mastermap_data(
72 abs_master_directory)['fullhost']
73 if master_hostname != local_hostname:
74 logger.error('%s does not match %s, aborting. use --hostname to override.',
75 local_hostname, master_hostname)
76 return False
77 return True
78
79
66 def run_state_machine_pass( 80 def run_state_machine_pass(
67 logger, matchlist, abs_master_directory, emergency_file, desired_state, 81 logger, matchlist, abs_master_directory, emergency_file, desired_state,
68 transition_time_utc, enable_gclient_sync, prod, connection_timeout): 82 transition_time_utc, enable_gclient_sync, prod, connection_timeout,
83 hostname):
69 # pragma: no cover 84 # pragma: no cover
70 if os.path.exists(os.path.join(abs_master_directory, emergency_file)): 85 if os.path.exists(os.path.join(abs_master_directory, emergency_file)):
71 logger.error('%s detected in %s, aborting!', 86 logger.error('%s detected in %s, aborting!',
72 emergency_file, abs_master_directory) 87 emergency_file, abs_master_directory)
73 return 1 88 return 1
74 89
90 if not master_hostname_is_valid(hostname, abs_master_directory, logger):
91 return 1
92
75 evidence = buildbot_state.collect_evidence( 93 evidence = buildbot_state.collect_evidence(
76 abs_master_directory, connection_timeout=connection_timeout) 94 abs_master_directory, connection_timeout=connection_timeout)
77 evidence['desired_buildbot_state'] = { 95 evidence['desired_buildbot_state'] = {
78 'desired_state': desired_state, 96 'desired_state': desired_state,
79 'transition_time_utc': transition_time_utc, 97 'transition_time_utc': transition_time_utc,
80 } 98 }
81 99
82 state, action_name, action_items = matchlist.execution_list(evidence) 100 state, action_name, action_items = matchlist.execution_list(evidence)
83 execution_list = list( 101 execution_list = list(
84 master.convert_action_items_to_cli( 102 master.convert_action_items_to_cli(
(...skipping 28 matching lines...) Expand all
113 131
114 if args.list_all_states: 132 if args.list_all_states:
115 matchlist.print_all_states() 133 matchlist.print_all_states()
116 return 0 134 return 0
117 135
118 abs_master_directory = os.path.abspath(args.directory) 136 abs_master_directory = os.path.abspath(args.directory)
119 137
120 state_machine = partial(run_state_machine_pass, logger, 138 state_machine = partial(run_state_machine_pass, logger,
121 matchlist, abs_master_directory, args.emergency_file, 139 matchlist, abs_master_directory, args.emergency_file,
122 args.desired_state, args.transition_time_utc, args.enable_gclient_sync, 140 args.desired_state, args.transition_time_utc, args.enable_gclient_sync,
123 args.prod, args.connection_timeout) 141 args.prod, args.connection_timeout, args.hostname)
124 142
125 if args.loop: 143 if args.loop:
126 loop_opts = outer_loop.process_argparse_options(args) 144 loop_opts = outer_loop.process_argparse_options(args)
127 outer_loop.loop( 145 outer_loop.loop(
128 state_machine, lambda: args.loop_sleep_secs, **loop_opts) 146 state_machine, lambda: args.loop_sleep_secs, **loop_opts)
129 else: 147 else:
130 return state_machine() 148 return state_machine()
131 149
132 return 0 150 return 0
133 151
134 152
135 if __name__ == '__main__': # pragma: no cover 153 if __name__ == '__main__': # pragma: no cover
136 sys.exit(main()) 154 sys.exit(main())
OLDNEW
« no previous file with comments | « infra/libs/buildbot/master.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698