1
- # Copyright 2019 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
#
3
- # Licensed under the Apache License, Version 2.0 (the ' License' );
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
3
+ # Licensed under the Apache License, Version 2.0 (the " License" );
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
6
#
7
- # http://www.apache.org/licenses/LICENSE-2.0
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
8
#
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an 'AS IS' BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
14
15
"""
15
16
Flask app to be used as an interactive demonstration of autohealing.
16
17
40
41
41
42
@app .before_first_request
42
43
def init ():
44
+ """Initialize the application."""
43
45
global _cpu_burner
44
46
_cpu_burner = CpuBurner ()
45
47
46
48
47
- @app .route ('/' )
49
+ @app .route ("/" )
48
50
def index ():
49
51
"""Returns the demo UI."""
50
52
global _cpu_burner , _is_healthy
51
- return render_template ('index.html' ,
52
- hostname = gethostname (),
53
- zone = _get_zone (),
54
- template = _get_template (),
55
- healthy = _is_healthy ,
56
- working = _cpu_burner .is_running ())
53
+ return render_template (
54
+ "index.html" ,
55
+ hostname = gethostname (),
56
+ zone = _get_zone (),
57
+ template = _get_template (),
58
+ healthy = _is_healthy ,
59
+ working = _cpu_burner .is_running (),
60
+ )
57
61
58
62
59
- @app .route (' /health' )
63
+ @app .route (" /health" )
60
64
def health ():
61
65
"""Returns the simulated 'healthy'/'unhealthy' status of the server.
62
66
63
67
Returns:
64
68
HTTP status 200 if 'healthy', HTTP status 500 if 'unhealthy'
65
69
"""
66
70
global _is_healthy
67
- template = render_template (' health.html' , healthy = _is_healthy )
71
+ template = render_template (" health.html" , healthy = _is_healthy )
68
72
return make_response (template , 200 if _is_healthy else 500 )
69
73
70
74
71
- @app .route (' /makeHealthy' )
75
+ @app .route (" /makeHealthy" )
72
76
def make_healthy ():
73
77
"""Sets the server to simulate a 'healthy' status."""
74
78
global _cpu_burner , _is_healthy
75
79
_is_healthy = True
76
80
77
- template = render_template ('index.html' ,
78
- hostname = gethostname (),
79
- zone = _get_zone (),
80
- template = _get_template (),
81
- healthy = True ,
82
- working = _cpu_burner .is_running ())
81
+ template = render_template (
82
+ "index.html" ,
83
+ hostname = gethostname (),
84
+ zone = _get_zone (),
85
+ template = _get_template (),
86
+ healthy = True ,
87
+ working = _cpu_burner .is_running (),
88
+ )
83
89
response = make_response (template , 302 )
84
- response .headers [' Location' ] = '/'
90
+ response .headers [" Location" ] = "/"
85
91
return response
86
92
87
93
88
- @app .route (' /makeUnhealthy' )
94
+ @app .route (" /makeUnhealthy" )
89
95
def make_unhealthy ():
90
96
"""Sets the server to simulate an 'unhealthy' status."""
91
97
global _cpu_burner , _is_healthy
92
98
_is_healthy = False
93
99
94
- template = render_template ('index.html' ,
95
- hostname = gethostname (),
96
- zone = _get_zone (),
97
- template = _get_template (),
98
- healthy = False ,
99
- working = _cpu_burner .is_running ())
100
+ template = render_template (
101
+ "index.html" ,
102
+ hostname = gethostname (),
103
+ zone = _get_zone (),
104
+ template = _get_template (),
105
+ healthy = False ,
106
+ working = _cpu_burner .is_running (),
107
+ )
100
108
response = make_response (template , 302 )
101
- response .headers [' Location' ] = '/'
109
+ response .headers [" Location" ] = "/"
102
110
return response
103
111
104
112
105
- @app .route (' /startLoad' )
113
+ @app .route (" /startLoad" )
106
114
def start_load ():
107
115
"""Sets the server to simulate high CPU load."""
108
116
global _cpu_burner , _is_healthy
109
117
_cpu_burner .start ()
110
118
111
- template = render_template ('index.html' ,
112
- hostname = gethostname (),
113
- zone = _get_zone (),
114
- template = _get_template (),
115
- healthy = _is_healthy ,
116
- working = True )
119
+ template = render_template (
120
+ "index.html" ,
121
+ hostname = gethostname (),
122
+ zone = _get_zone (),
123
+ template = _get_template (),
124
+ healthy = _is_healthy ,
125
+ working = True ,
126
+ )
117
127
response = make_response (template , 302 )
118
- response .headers [' Location' ] = '/'
128
+ response .headers [" Location" ] = "/"
119
129
return response
120
130
121
131
122
- @app .route (' /stopLoad' )
132
+ @app .route (" /stopLoad" )
123
133
def stop_load ():
124
134
"""Sets the server to stop simulating CPU load."""
125
135
global _cpu_burner , _is_healthy
126
136
_cpu_burner .stop ()
127
137
128
- template = render_template ('index.html' ,
129
- hostname = gethostname (),
130
- zone = _get_zone (),
131
- template = _get_template (),
132
- healthy = _is_healthy ,
133
- working = False )
138
+ template = render_template (
139
+ "index.html" ,
140
+ hostname = gethostname (),
141
+ zone = _get_zone (),
142
+ template = _get_template (),
143
+ healthy = _is_healthy ,
144
+ working = False ,
145
+ )
134
146
response = make_response (template , 302 )
135
- response .headers [' Location' ] = '/'
147
+ response .headers [" Location" ] = "/"
136
148
return response
137
149
138
150
@@ -143,13 +155,14 @@ def _get_zone():
143
155
str: The name of the zone if the zone was successfully determined.
144
156
Empty string otherwise.
145
157
"""
146
- r = get ('http://metadata.google.internal/'
147
- 'computeMetadata/v1/instance/zone' ,
148
- headers = {'Metadata-Flavor' : 'Google' })
158
+ r = get (
159
+ "http://metadata.google.internal/" "computeMetadata/v1/instance/zone" ,
160
+ headers = {"Metadata-Flavor" : "Google" },
161
+ )
149
162
if r .status_code == 200 :
150
- return sub (r' .+zones/(.+)' , r'\1' , r .text )
163
+ return sub (r" .+zones/(.+)" , r"\1" , r .text )
151
164
else :
152
- return ''
165
+ return ""
153
166
154
167
155
168
def _get_template ():
@@ -160,20 +173,23 @@ def _get_template():
160
173
determined and this instance was built using an instance template.
161
174
Empty string otherwise.
162
175
"""
163
- r = get ('http://metadata.google.internal/'
164
- 'computeMetadata/v1/instance/attributes/instance-template' ,
165
- headers = {'Metadata-Flavor' : 'Google' })
176
+ r = get (
177
+ "http://metadata.google.internal/"
178
+ "computeMetadata/v1/instance/attributes/instance-template" ,
179
+ headers = {"Metadata-Flavor" : "Google" },
180
+ )
166
181
if r .status_code == 200 :
167
- return sub (r' .+instanceTemplates/(.+)' , r'\1' , r .text )
182
+ return sub (r" .+instanceTemplates/(.+)" , r"\1" , r .text )
168
183
else :
169
- return ''
184
+ return ""
170
185
171
186
172
187
class CpuBurner :
173
188
"""
174
189
Object to asynchronously burn CPU cycles to simulate high CPU load.
175
190
Burns CPU in a separate process and can be toggled on and off.
176
191
"""
192
+
177
193
def __init__ (self ):
178
194
self ._toggle = Value (c_bool , False , lock = True )
179
195
self ._process = Process (target = self ._burn_cpu )
@@ -194,7 +210,7 @@ def is_running(self):
194
210
def _burn_cpu (self ):
195
211
"""Burn CPU cycles if work is toggled, otherwise sleep."""
196
212
while True :
197
- random ()* random () if self ._toggle .value else sleep (1 )
213
+ random () * random () if self ._toggle .value else sleep (1 )
198
214
199
215
200
216
if __name__ == "__main__" :
0 commit comments