OLD | NEW |
1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package main | 5 package main |
6 | 6 |
7 import ( | 7 import ( |
8 "io/ioutil" | 8 "io/ioutil" |
9 "os" | 9 "os" |
10 "path/filepath" | 10 "path/filepath" |
(...skipping 24 matching lines...) Expand all Loading... |
35 } | 35 } |
36 | 36 |
37 // pathTo resolves a path, p, specified in a directory with source-root-relative | 37 // pathTo resolves a path, p, specified in a directory with source-root-relative |
38 // path relpath. | 38 // path relpath. |
39 // | 39 // |
40 // - If the path begins with "/", it is taken relative to the source root. | 40 // - If the path begins with "/", it is taken relative to the source root. |
41 // - If the path does not begin with "/", it is taken relative to "relpath" | 41 // - If the path does not begin with "/", it is taken relative to "relpath" |
42 // within the source root (e.g., "relpath" is prepended to it). | 42 // within the source root (e.g., "relpath" is prepended to it). |
43 func (s *layoutSource) pathTo(p, relpath string) string { | 43 func (s *layoutSource) pathTo(p, relpath string) string { |
44 if s.Relpath == "" { | 44 if s.Relpath == "" { |
45 » » panic(errors.Reason("source %(source)q is not checked out").D("s
ource", s).Err()) | 45 » » panic(errors.Reason("source %q is not checked out", s).Err()) |
46 } | 46 } |
47 | 47 |
48 // If this is absolute, take it relative to source root. | 48 // If this is absolute, take it relative to source root. |
49 if strings.HasPrefix(p, "/") { | 49 if strings.HasPrefix(p, "/") { |
50 relpath = "" | 50 relpath = "" |
51 } | 51 } |
52 | 52 |
53 // Convert "p" to a source-relative absolute path. | 53 // Convert "p" to a source-relative absolute path. |
54 p = strings.Trim(p, "/") | 54 p = strings.Trim(p, "/") |
55 if relpath != "" { | 55 if relpath != "" { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // cloudProject is the deployment cloud project, if one is specified. | 120 // cloudProject is the deployment cloud project, if one is specified. |
121 cloudProject *layoutDeploymentCloudProject | 121 cloudProject *layoutDeploymentCloudProject |
122 } | 122 } |
123 | 123 |
124 func (d *layoutDeployment) String() string { return string(d.title) } | 124 func (d *layoutDeployment) String() string { return string(d.title) } |
125 | 125 |
126 // substituteParams applies parameter substitution to the supplied string in a | 126 // substituteParams applies parameter substitution to the supplied string in a |
127 // left-to-right manner. | 127 // left-to-right manner. |
128 func (d *layoutDeployment) substituteParams(vp *string) error { | 128 func (d *layoutDeployment) substituteParams(vp *string) error { |
129 if err := substitute(vp, d.Parameter); err != nil { | 129 if err := substitute(vp, d.Parameter); err != nil { |
130 » » return errors.Annotate(err).Err() | 130 » » return errors.Annotate(err, "").Err() |
131 } | 131 } |
132 return nil | 132 return nil |
133 } | 133 } |
134 | 134 |
135 type layoutDeploymentComponent struct { | 135 type layoutDeploymentComponent struct { |
136 deploy.Component | 136 deploy.Component |
137 | 137 |
138 // reldir is the source-relative directory that relative paths in this | 138 // reldir is the source-relative directory that relative paths in this |
139 // component will reference. This will be the parent directory of the | 139 // component will reference. This will be the parent directory of the |
140 // component's configuration file. | 140 // component's configuration file. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 } | 172 } |
173 | 173 |
174 func (comp *layoutDeploymentComponent) pathTo(relpath string) string { | 174 func (comp *layoutDeploymentComponent) pathTo(relpath string) string { |
175 return comp.source().pathTo(relpath, comp.reldir) | 175 return comp.source().pathTo(relpath, comp.reldir) |
176 } | 176 } |
177 | 177 |
178 func (comp *layoutDeploymentComponent) buildPath(bp *deploy.BuildPath) (string,
error) { | 178 func (comp *layoutDeploymentComponent) buildPath(bp *deploy.BuildPath) (string,
error) { |
179 if path, ok := comp.buildPathMap[bp]; ok { | 179 if path, ok := comp.buildPathMap[bp]; ok { |
180 return path, nil | 180 return path, nil |
181 } | 181 } |
182 » return "", errors.Reason("no build path resolved for: %(bp)+v").D("bp",
bp, "%+v").Err() | 182 » return "", errors.Reason("no build path resolved for: %+v", bp).Err() |
183 } | 183 } |
184 | 184 |
185 func (comp *layoutDeploymentComponent) loadSourceComponent(reg componentRegistra
r) error { | 185 func (comp *layoutDeploymentComponent) loadSourceComponent(reg componentRegistra
r) error { |
186 if err := unmarshalTextProtobuf(comp.source().pathTo(comp.comp.Path, "")
, &comp.Component); err != nil { | 186 if err := unmarshalTextProtobuf(comp.source().pathTo(comp.comp.Path, "")
, &comp.Component); err != nil { |
187 » » return errors.Annotate(err).Reason("failed to load source compon
ent %(component)q").D("component", comp).Err() | 187 » » return errors.Annotate(err, "failed to load source component %q"
, comp).Err() |
188 } | 188 } |
189 | 189 |
190 // Referenced build paths. | 190 // Referenced build paths. |
191 for i, p := range comp.BuildPath { | 191 for i, p := range comp.BuildPath { |
192 var msg deploy.Component_Build | 192 var msg deploy.Component_Build |
193 if err := unmarshalTextProtobuf(comp.pathTo(p), &msg); err != ni
l { | 193 if err := unmarshalTextProtobuf(comp.pathTo(p), &msg); err != ni
l { |
194 » » » return errors.Annotate(err).Reason("failed to load compo
nent Build #%(index)d from [%(path)s]"). | 194 » » » return errors.Annotate(err, "failed to load component Bu
ild #%d from [%s]", i, p).Err() |
195 » » » » D("index", i).D("path", p).Err() | |
196 } | 195 } |
197 comp.Build = append(comp.Build, &msg) | 196 comp.Build = append(comp.Build, &msg) |
198 } | 197 } |
199 | 198 |
200 // Load any referenced data and normalize it for internal usage. | 199 // Load any referenced data and normalize it for internal usage. |
201 dep := comp.dep | 200 dep := comp.dep |
202 switch t := comp.GetComponent().(type) { | 201 switch t := comp.GetComponent().(type) { |
203 case *deploy.Component_AppengineModule: | 202 case *deploy.Component_AppengineModule: |
204 // Normalize AppEngine module: | 203 // Normalize AppEngine module: |
205 // - Modules explicitly named "default" will have their ModuleNa
me changed | 204 // - Modules explicitly named "default" will have their ModuleNa
me changed |
206 // to the empty string. | 205 // to the empty string. |
207 // - All referenced path parameters will be loaded and appended
onto their | 206 // - All referenced path parameters will be loaded and appended
onto their |
208 // non-path members. | 207 // non-path members. |
209 if dep.cloudProject == nil { | 208 if dep.cloudProject == nil { |
210 » » » return errors.Reason("AppEngine module %(comp)q requires
a cloud project"). | 209 » » » return errors.Reason("AppEngine module %q requires a clo
ud project", comp).Err() |
211 » » » » D("comp", comp).Err() | |
212 } | 210 } |
213 | 211 |
214 aem := t.AppengineModule | 212 aem := t.AppengineModule |
215 if aem.ModuleName == "default" { | 213 if aem.ModuleName == "default" { |
216 aem.ModuleName = "" | 214 aem.ModuleName = "" |
217 } | 215 } |
218 | 216 |
219 module := layoutDeploymentGAEModule{ | 217 module := layoutDeploymentGAEModule{ |
220 AppEngineModule: aem, | 218 AppEngineModule: aem, |
221 comp: comp, | 219 comp: comp, |
222 } | 220 } |
223 | 221 |
224 // Referenced handler paths. | 222 // Referenced handler paths. |
225 for i, p := range aem.HandlerPath { | 223 for i, p := range aem.HandlerPath { |
226 var msg deploy.AppEngineModule_HandlerSet | 224 var msg deploy.AppEngineModule_HandlerSet |
227 if err := unmarshalTextProtobuf(comp.pathTo(p), &msg); e
rr != nil { | 225 if err := unmarshalTextProtobuf(comp.pathTo(p), &msg); e
rr != nil { |
228 » » » » return errors.Annotate(err).Reason("failed to lo
ad HandlerSet #%(index)d for %(component)q"). | 226 » » » » return errors.Annotate(err, "failed to load Hand
lerSet #%d for %q", i, comp).Err() |
229 » » » » » D("index", i).D("component", comp).Err() | |
230 } | 227 } |
231 module.Handlers.Handler = append(module.Handlers.Handler
, msg.Handler...) | 228 module.Handlers.Handler = append(module.Handlers.Handler
, msg.Handler...) |
232 } | 229 } |
233 | 230 |
234 // If the module specifies a direct "index.yaml" path, load inde
x entries | 231 // If the module specifies a direct "index.yaml" path, load inde
x entries |
235 // from there and translate them to resources. | 232 // from there and translate them to resources. |
236 if p := module.IndexYamlPath; p != "" { | 233 if p := module.IndexYamlPath; p != "" { |
237 path := module.comp.pathTo(p) | 234 path := module.comp.pathTo(p) |
238 res, err := loadIndexYAMLResource(path) | 235 res, err := loadIndexYAMLResource(path) |
239 if err != nil { | 236 if err != nil { |
240 » » » » return errors.Annotate(err).Reason("failed to lo
ad 'index.yaml' from [%(path)s]"). | 237 » » » » return errors.Annotate(err, "failed to load 'ind
ex.yaml' from [%s]", path).Err() |
241 » » » » » D("path", path).Err() | |
242 } | 238 } |
243 dep.cloudProject.appendResources(res, &module) | 239 dep.cloudProject.appendResources(res, &module) |
244 } | 240 } |
245 | 241 |
246 // Append GAE Resources. | 242 // Append GAE Resources. |
247 if r := module.Resources; r != nil { | 243 if r := module.Resources; r != nil { |
248 dep.cloudProject.appendResources(r, &module) | 244 dep.cloudProject.appendResources(r, &module) |
249 } | 245 } |
250 | 246 |
251 for i, p := range module.ResourcePath { | 247 for i, p := range module.ResourcePath { |
252 if err := comp.dep.substituteParams(&p); err != nil { | 248 if err := comp.dep.substituteParams(&p); err != nil { |
253 » » » » return errors.Annotate(err).Reason("failed to su
bstitute parameters for resource path"). | 249 » » » » return errors.Annotate(err, "failed to substitut
e parameters for resource path"). |
254 » » » » » D("path", p).Err() | 250 » » » » » InternalReason("path(%s)", p).Err() |
255 } | 251 } |
256 | 252 |
257 var res deploy.AppEngineResources | 253 var res deploy.AppEngineResources |
258 if err := unmarshalTextProtobuf(comp.pathTo(p), &res); e
rr != nil { | 254 if err := unmarshalTextProtobuf(comp.pathTo(p), &res); e
rr != nil { |
259 » » » » return errors.Annotate(err).Reason("failed to lo
ad Resources #%(index)d for %(component)"). | 255 » » » » return errors.Annotate(err, "failed to load Reso
urces #%d for %q", i, comp). |
260 » » » » » D("index", i).D("path", p).D("component"
, comp).Err() | 256 » » » » » InternalReason("path(%s)", p).Err() |
261 } | 257 } |
262 dep.cloudProject.appendResources(&res, &module) | 258 dep.cloudProject.appendResources(&res, &module) |
263 } | 259 } |
264 | 260 |
265 // Add this module to our cloud project's AppEngine modules list
. | 261 // Add this module to our cloud project's AppEngine modules list
. |
266 dep.cloudProject.appEngineModules = append(dep.cloudProject.appE
ngineModules, &module) | 262 dep.cloudProject.appEngineModules = append(dep.cloudProject.appE
ngineModules, &module) |
267 if reg != nil { | 263 if reg != nil { |
268 reg.addGAEModule(&module) | 264 reg.addGAEModule(&module) |
269 } | 265 } |
270 | 266 |
271 case *deploy.Component_GkePod: | 267 case *deploy.Component_GkePod: |
272 if len(comp.gkePods) == 0 { | 268 if len(comp.gkePods) == 0 { |
273 » » » return errors.Reason("GKE Container %(comp)q is not boun
d to a GKE cluster"). | 269 » » » return errors.Reason("GKE Container %q is not bound to a
GKE cluster", comp).Err() |
274 » » » » D("comp", comp.String()).Err() | |
275 } | 270 } |
276 | 271 |
277 comp.gkePod = &layoutDeploymentGKEPod{ | 272 comp.gkePod = &layoutDeploymentGKEPod{ |
278 ContainerEnginePod: t.GkePod, | 273 ContainerEnginePod: t.GkePod, |
279 comp: comp, | 274 comp: comp, |
280 } | 275 } |
281 | 276 |
282 // None of the labels may use our "deploytool" prefix. | 277 // None of the labels may use our "deploytool" prefix. |
283 var invalidLabels []string | 278 var invalidLabels []string |
284 for k := range comp.gkePod.KubePod.Labels { | 279 for k := range comp.gkePod.KubePod.Labels { |
285 if isKubeDeployToolKey(k) { | 280 if isKubeDeployToolKey(k) { |
286 invalidLabels = append(invalidLabels, k) | 281 invalidLabels = append(invalidLabels, k) |
287 } | 282 } |
288 } | 283 } |
289 if len(invalidLabels) > 0 { | 284 if len(invalidLabels) > 0 { |
290 sort.Strings(invalidLabels) | 285 sort.Strings(invalidLabels) |
291 return errors.Reason("user-supplied labels may not use d
eploytool prefix"). | 286 return errors.Reason("user-supplied labels may not use d
eploytool prefix"). |
292 » » » » D("labels", invalidLabels).Err() | 287 » » » » InternalReason("labels(%v)", invalidLabels).Err(
) |
293 } | 288 } |
294 | 289 |
295 for _, bp := range comp.gkePods { | 290 for _, bp := range comp.gkePods { |
296 bp.pod = comp.gkePod | 291 bp.pod = comp.gkePod |
297 if reg != nil { | 292 if reg != nil { |
298 reg.addGKEPod(bp) | 293 reg.addGKEPod(bp) |
299 } | 294 } |
300 } | 295 } |
301 } | 296 } |
302 | 297 |
303 return nil | 298 return nil |
304 } | 299 } |
305 | 300 |
306 // expandPaths iterates through the Component-defined directory fields and | 301 // expandPaths iterates through the Component-defined directory fields and |
307 // expands their paths into actual filesystem paths. | 302 // expands their paths into actual filesystem paths. |
308 // | 303 // |
309 // This must be performed after the build instructions have been executed so | 304 // This must be performed after the build instructions have been executed so |
310 // that the "build_dir" map will be available if needed by a Component. | 305 // that the "build_dir" map will be available if needed by a Component. |
311 func (comp *layoutDeploymentComponent) expandPaths() error { | 306 func (comp *layoutDeploymentComponent) expandPaths() error { |
312 resolveBuildPath := func(bp *deploy.BuildPath) error { | 307 resolveBuildPath := func(bp *deploy.BuildPath) error { |
313 if _, ok := comp.buildPathMap[bp]; ok { | 308 if _, ok := comp.buildPathMap[bp]; ok { |
314 // Already resolved. | 309 // Already resolved. |
315 return nil | 310 return nil |
316 } | 311 } |
317 | 312 |
318 var resolved string | 313 var resolved string |
319 if bp.DirKey != "" { | 314 if bp.DirKey != "" { |
320 dir, ok := comp.buildDirs[bp.DirKey] | 315 dir, ok := comp.buildDirs[bp.DirKey] |
321 if !ok { | 316 if !ok { |
322 » » » » return errors.Reason("Invalid `dir_key` value: %
(dirKey)q").D("dirKey", bp.DirKey).Err() | 317 » » » » return errors.Reason("Invalid `dir_key` value: %
q", bp.DirKey).Err() |
323 } | 318 } |
324 resolved = deployToNative(dir, bp.Path) | 319 resolved = deployToNative(dir, bp.Path) |
325 } else { | 320 } else { |
326 resolved = comp.pathTo(bp.Path) | 321 resolved = comp.pathTo(bp.Path) |
327 } | 322 } |
328 | 323 |
329 if comp.buildPathMap == nil { | 324 if comp.buildPathMap == nil { |
330 comp.buildPathMap = make(map[*deploy.BuildPath]string) | 325 comp.buildPathMap = make(map[*deploy.BuildPath]string) |
331 } | 326 } |
332 comp.buildPathMap[bp] = resolved | 327 comp.buildPathMap[bp] = resolved |
333 return nil | 328 return nil |
334 } | 329 } |
335 | 330 |
336 switch t := comp.Component.Component.(type) { | 331 switch t := comp.Component.Component.(type) { |
337 case *deploy.Component_AppengineModule: | 332 case *deploy.Component_AppengineModule: |
338 aem := t.AppengineModule | 333 aem := t.AppengineModule |
339 if aem.Handlers != nil { | 334 if aem.Handlers != nil { |
340 for _, handler := range aem.Handlers.Handler { | 335 for _, handler := range aem.Handlers.Handler { |
341 switch c := handler.Content.(type) { | 336 switch c := handler.Content.(type) { |
342 case *deploy.AppEngineModule_Handler_StaticFiles
_: | 337 case *deploy.AppEngineModule_Handler_StaticFiles
_: |
343 sf := c.StaticFiles | 338 sf := c.StaticFiles |
344 switch bd := sf.BaseDir.(type) { | 339 switch bd := sf.BaseDir.(type) { |
345 case *deploy.AppEngineModule_Handler_Sta
ticFiles_Path: | 340 case *deploy.AppEngineModule_Handler_Sta
ticFiles_Path: |
346 // Normalize our static files di
rectory to a BuildPath rooted at our | 341 // Normalize our static files di
rectory to a BuildPath rooted at our |
347 // source. | 342 // source. |
348 sf.BaseDir = &deploy.AppEngineMo
dule_Handler_StaticFiles_Build{ | 343 sf.BaseDir = &deploy.AppEngineMo
dule_Handler_StaticFiles_Build{ |
349 Build: &deploy.BuildPath
{Path: bd.Path}, | 344 Build: &deploy.BuildPath
{Path: bd.Path}, |
350 } | 345 } |
351 if err := resolveBuildPath(sf.Ge
tBuild()); err != nil { | 346 if err := resolveBuildPath(sf.Ge
tBuild()); err != nil { |
352 » » » » » » » return errors.Annotate(e
rr).Err() | 347 » » » » » » » return errors.Annotate(e
rr, "").Err() |
353 } | 348 } |
354 | 349 |
355 case *deploy.AppEngineModule_Handler_Sta
ticFiles_Build: | 350 case *deploy.AppEngineModule_Handler_Sta
ticFiles_Build: |
356 if err := resolveBuildPath(bd.Bu
ild); err != nil { | 351 if err := resolveBuildPath(bd.Bu
ild); err != nil { |
357 » » » » » » » return errors.Annotate(e
rr).Err() | 352 » » » » » » » return errors.Annotate(e
rr, "").Err() |
358 } | 353 } |
359 | 354 |
360 default: | 355 default: |
361 » » » » » » return errors.Reason("unknown `b
ase_dir` type %(type)T").D("type", bd).Err() | 356 » » » » » » return errors.Reason("unknown `b
ase_dir` type %T", bd).Err() |
362 } | 357 } |
363 | 358 |
364 case *deploy.AppEngineModule_Handler_StaticDir: | 359 case *deploy.AppEngineModule_Handler_StaticDir: |
365 // Normalize our static directory (sourc
e-relative) to a BuildPath | 360 // Normalize our static directory (sourc
e-relative) to a BuildPath |
366 // rooted at our source. | 361 // rooted at our source. |
367 handler.Content = &deploy.AppEngineModul
e_Handler_StaticBuildDir{ | 362 handler.Content = &deploy.AppEngineModul
e_Handler_StaticBuildDir{ |
368 StaticBuildDir: &deploy.BuildPat
h{Path: c.StaticDir}, | 363 StaticBuildDir: &deploy.BuildPat
h{Path: c.StaticDir}, |
369 } | 364 } |
370 if err := resolveBuildPath(handler.GetSt
aticBuildDir()); err != nil { | 365 if err := resolveBuildPath(handler.GetSt
aticBuildDir()); err != nil { |
371 » » » » » » return errors.Annotate(err).Err(
) | 366 » » » » » » return errors.Annotate(err, "").
Err() |
372 } | 367 } |
373 | 368 |
374 case *deploy.AppEngineModule_Handler_StaticBuild
Dir: | 369 case *deploy.AppEngineModule_Handler_StaticBuild
Dir: |
375 if err := resolveBuildPath(c.StaticBuild
Dir); err != nil { | 370 if err := resolveBuildPath(c.StaticBuild
Dir); err != nil { |
376 » » » » » » return errors.Annotate(err).Err(
) | 371 » » » » » » return errors.Annotate(err, "").
Err() |
377 } | 372 } |
378 } | 373 } |
379 } | 374 } |
380 } | 375 } |
381 | 376 |
382 case *deploy.Component_GkePod: | 377 case *deploy.Component_GkePod: |
383 for _, container := range t.GkePod.KubePod.Container { | 378 for _, container := range t.GkePod.KubePod.Container { |
384 switch df := container.Dockerfile.(type) { | 379 switch df := container.Dockerfile.(type) { |
385 case *deploy.KubernetesPod_Container_Path: | 380 case *deploy.KubernetesPod_Container_Path: |
386 // Convert to BuildPath. | 381 // Convert to BuildPath. |
387 container.Dockerfile = &deploy.KubernetesPod_Con
tainer_Build{ | 382 container.Dockerfile = &deploy.KubernetesPod_Con
tainer_Build{ |
388 Build: &deploy.BuildPath{Path: df.Path}, | 383 Build: &deploy.BuildPath{Path: df.Path}, |
389 } | 384 } |
390 if err := resolveBuildPath(container.GetBuild())
; err != nil { | 385 if err := resolveBuildPath(container.GetBuild())
; err != nil { |
391 » » » » » return errors.Annotate(err).Err() | 386 » » » » » return errors.Annotate(err, "").Err() |
392 } | 387 } |
393 | 388 |
394 case *deploy.KubernetesPod_Container_Build: | 389 case *deploy.KubernetesPod_Container_Build: |
395 if err := resolveBuildPath(df.Build); err != nil
{ | 390 if err := resolveBuildPath(df.Build); err != nil
{ |
396 » » » » » return errors.Annotate(err).Err() | 391 » » » » » return errors.Annotate(err, "").Err() |
397 } | 392 } |
398 | 393 |
399 default: | 394 default: |
400 » » » » return errors.Reason("unknown `dockerfile` type
%(type)T").D("type", df).Err() | 395 » » » » return errors.Reason("unknown `dockerfile` type
%T", df).Err() |
401 } | 396 } |
402 } | 397 } |
403 } | 398 } |
404 | 399 |
405 return nil | 400 return nil |
406 } | 401 } |
407 | 402 |
408 // layoutDeploymentCloudProject tracks a cloud project element, as well as | 403 // layoutDeploymentCloudProject tracks a cloud project element, as well as |
409 // any cloud project configurations referenced by this Deployment's Components. | 404 // any cloud project configurations referenced by this Deployment's Components. |
410 type layoutDeploymentCloudProject struct { | 405 type layoutDeploymentCloudProject struct { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 cloudProjects map[string]*layoutDeploymentCloudProject | 517 cloudProjects map[string]*layoutDeploymentCloudProject |
523 } | 518 } |
524 | 519 |
525 // workingFilesystem creates a new managed filesystem at our working directory | 520 // workingFilesystem creates a new managed filesystem at our working directory |
526 // root. | 521 // root. |
527 // | 522 // |
528 // This adds layout-defined components to the filesystem. | 523 // This adds layout-defined components to the filesystem. |
529 func (l *deployLayout) workingFilesystem() (*managedfs.Filesystem, error) { | 524 func (l *deployLayout) workingFilesystem() (*managedfs.Filesystem, error) { |
530 fs, err := managedfs.New(l.WorkingPath) | 525 fs, err := managedfs.New(l.WorkingPath) |
531 if err != nil { | 526 if err != nil { |
532 » » return nil, errors.Annotate(err).Err() | 527 » » return nil, errors.Annotate(err, "").Err() |
533 } | 528 } |
534 return fs, nil | 529 return fs, nil |
535 } | 530 } |
536 | 531 |
537 func (l *deployLayout) workingPathTo(relpath string) string { | 532 func (l *deployLayout) workingPathTo(relpath string) string { |
538 return filepath.Join(l.WorkingPath, relpath) | 533 return filepath.Join(l.WorkingPath, relpath) |
539 } | 534 } |
540 | 535 |
541 func (l *deployLayout) getDeploymentComponent(v string) (*layoutDeployment, *lay
outDeploymentComponent, error) { | 536 func (l *deployLayout) getDeploymentComponent(v string) (*layoutDeployment, *lay
outDeploymentComponent, error) { |
542 deployment, component := splitComponentPath(v) | 537 deployment, component := splitComponentPath(v) |
543 | 538 |
544 dep := l.deployments[deployment] | 539 dep := l.deployments[deployment] |
545 if dep == nil { | 540 if dep == nil { |
546 » » return nil, nil, errors.Reason("unknown Deployment %(dep)q"). | 541 » » return nil, nil, errors.Reason("unknown Deployment %q", deployme
nt). |
547 » » » D("value", v).D("dep", deployment).Err() | 542 » » » InternalReason("value(%s)", v).Err() |
548 } | 543 } |
549 | 544 |
550 // If a component was specified, only add that component. | 545 // If a component was specified, only add that component. |
551 if component != "" { | 546 if component != "" { |
552 comp := dep.components[component] | 547 comp := dep.components[component] |
553 if comp == nil { | 548 if comp == nil { |
554 » » » return nil, nil, errors.Reason("unknown Deployment Compo
nent %(value)q"). | 549 » » » return nil, nil, errors.Reason("unknown Deployment Compo
nent %q", v). |
555 » » » » D("value", v).D("dep", deployment).D("comp", com
ponent).Err() | 550 » » » » InternalReason("dep(%s)/comp(%s)", deployment, c
omponent).Err() |
556 } | 551 } |
557 return dep, comp, nil | 552 return dep, comp, nil |
558 } | 553 } |
559 return dep, nil, nil | 554 return dep, nil, nil |
560 } | 555 } |
561 | 556 |
562 func (l *deployLayout) matchDeploymentComponent(m string, cb func(*layoutDeploym
ent, *layoutDeploymentComponent)) error { | 557 func (l *deployLayout) matchDeploymentComponent(m string, cb func(*layoutDeploym
ent, *layoutDeploymentComponent)) error { |
563 for _, depName := range l.deploymentNames { | 558 for _, depName := range l.deploymentNames { |
564 dep := l.deployments[depName] | 559 dep := l.deployments[depName] |
565 | 560 |
566 matched, err := filepath.Match(m, dep.String()) | 561 matched, err := filepath.Match(m, dep.String()) |
567 if err != nil { | 562 if err != nil { |
568 » » » return errors.Annotate(err).Reason("failed to match %(pa
ttern)q").D("pattern", m).Err() | 563 » » » return errors.Annotate(err, "failed to match %q", m).Err
() |
569 } | 564 } |
570 if matched { | 565 if matched { |
571 // Matches entire deployment. | 566 // Matches entire deployment. |
572 cb(dep, nil) | 567 cb(dep, nil) |
573 continue | 568 continue |
574 } | 569 } |
575 | 570 |
576 // Try each of the deployment's components. | 571 // Try each of the deployment's components. |
577 for _, compName := range dep.componentNames { | 572 for _, compName := range dep.componentNames { |
578 comp := dep.components[compName] | 573 comp := dep.components[compName] |
579 | 574 |
580 matched, err := filepath.Match(m, comp.String()) | 575 matched, err := filepath.Match(m, comp.String()) |
581 if err != nil { | 576 if err != nil { |
582 » » » » return errors.Annotate(err).Reason("failed to ma
tch %(pattern)q").D("pattern", m).Err() | 577 » » » » return errors.Annotate(err, "failed to match %q"
, m).Err() |
583 } | 578 } |
584 if matched { | 579 if matched { |
585 cb(dep, comp) | 580 cb(dep, comp) |
586 } | 581 } |
587 } | 582 } |
588 } | 583 } |
589 | 584 |
590 return nil | 585 return nil |
591 } | 586 } |
592 | 587 |
593 func (l *deployLayout) load(c context.Context, path string) error { | 588 func (l *deployLayout) load(c context.Context, path string) error { |
594 if path == "" { | 589 if path == "" { |
595 wd, err := os.Getwd() | 590 wd, err := os.Getwd() |
596 if err != nil { | 591 if err != nil { |
597 return err | 592 return err |
598 } | 593 } |
599 path, err = findLayout(defaultLayoutFilename, wd) | 594 path, err = findLayout(defaultLayoutFilename, wd) |
600 if err != nil { | 595 if err != nil { |
601 return err | 596 return err |
602 } | 597 } |
603 } | 598 } |
604 | 599 |
605 if err := unmarshalTextProtobuf(path, &l.Layout); err != nil { | 600 if err := unmarshalTextProtobuf(path, &l.Layout); err != nil { |
606 return err | 601 return err |
607 } | 602 } |
608 | 603 |
609 // Load the user config, if available. | 604 // Load the user config, if available. |
610 if err := loadUserConfig(c, &l.user); err != nil { | 605 if err := loadUserConfig(c, &l.user); err != nil { |
611 » » return errors.Annotate(err).Reason("failed to load user config")
.Err() | 606 » » return errors.Annotate(err, "failed to load user config").Err() |
612 } | 607 } |
613 if len(l.user.SourceOverride) > 0 { | 608 if len(l.user.SourceOverride) > 0 { |
614 l.userSourceOverrides = make(map[string]*deploy.Source, len(l.us
er.SourceOverride)) | 609 l.userSourceOverrides = make(map[string]*deploy.Source, len(l.us
er.SourceOverride)) |
615 for k, v := range l.user.SourceOverride { | 610 for k, v := range l.user.SourceOverride { |
616 l.userSourceOverrides[k] = v | 611 l.userSourceOverrides[k] = v |
617 } | 612 } |
618 } | 613 } |
619 | 614 |
620 // Populate with defaults. | 615 // Populate with defaults. |
621 l.basePath = filepath.Dir(path) | 616 l.basePath = filepath.Dir(path) |
(...skipping 10 matching lines...) Expand all Loading... |
632 if l.WorkingPath == "" { | 627 if l.WorkingPath == "" { |
633 l.WorkingPath = filepath.Join(l.basePath, ".working") | 628 l.WorkingPath = filepath.Join(l.basePath, ".working") |
634 } else { | 629 } else { |
635 if !filepath.IsAbs(l.WorkingPath) { | 630 if !filepath.IsAbs(l.WorkingPath) { |
636 l.WorkingPath = filepath.Join(l.basePath, l.WorkingPath) | 631 l.WorkingPath = filepath.Join(l.basePath, l.WorkingPath) |
637 } | 632 } |
638 } | 633 } |
639 | 634 |
640 absWorkingPath, err := filepath.Abs(l.WorkingPath) | 635 absWorkingPath, err := filepath.Abs(l.WorkingPath) |
641 if err != nil { | 636 if err != nil { |
642 » » return errors.Annotate(err).Reason("failed to resolve absolute p
ath for %(path)q"). | 637 » » return errors.Annotate(err, "failed to resolve absolute path for
%q", l.WorkingPath).Err() |
643 » » » D("path", l.WorkingPath).Err() | |
644 } | 638 } |
645 l.WorkingPath = absWorkingPath | 639 l.WorkingPath = absWorkingPath |
646 return nil | 640 return nil |
647 } | 641 } |
648 | 642 |
649 func (l *deployLayout) initFrozenCheckout(c context.Context) (*deploy.FrozenLayo
ut, error) { | 643 func (l *deployLayout) initFrozenCheckout(c context.Context) (*deploy.FrozenLayo
ut, error) { |
650 fis, err := ioutil.ReadDir(l.SourcesPath) | 644 fis, err := ioutil.ReadDir(l.SourcesPath) |
651 if err != nil { | 645 if err != nil { |
652 » » return nil, errors.Annotate(err).Reason("failed to read director
y").Err() | 646 » » return nil, errors.Annotate(err, "failed to read directory").Err
() |
653 } | 647 } |
654 | 648 |
655 // Build internal and frozen layout in parallel. | 649 // Build internal and frozen layout in parallel. |
656 var frozen deploy.FrozenLayout | 650 var frozen deploy.FrozenLayout |
657 frozen.SourceGroup = make(map[string]*deploy.FrozenLayout_SourceGroup, l
en(fis)) | 651 frozen.SourceGroup = make(map[string]*deploy.FrozenLayout_SourceGroup, l
en(fis)) |
658 | 652 |
659 for _, fi := range fis { | 653 for _, fi := range fis { |
660 name := title(fi.Name()) | 654 name := title(fi.Name()) |
661 path := filepath.Join(l.SourcesPath, string(name)) | 655 path := filepath.Join(l.SourcesPath, string(name)) |
662 | 656 |
(...skipping 27 matching lines...) Expand all Loading... |
690 sg := deploy.FrozenLayout_SourceGroup{ | 684 sg := deploy.FrozenLayout_SourceGroup{ |
691 Source: make(map[string]*deploy.FrozenLayout_Source, len
(srcInfos)), | 685 Source: make(map[string]*deploy.FrozenLayout_Source, len
(srcInfos)), |
692 } | 686 } |
693 | 687 |
694 var srcBase deploy.Source | 688 var srcBase deploy.Source |
695 err = unmarshalTextProtobufDir(path, srcInfos, &srcBase, func(na
me string) error { | 689 err = unmarshalTextProtobufDir(path, srcInfos, &srcBase, func(na
me string) error { |
696 cpy := srcBase | 690 cpy := srcBase |
697 | 691 |
698 t, err := titleFromConfigPath(name) | 692 t, err := titleFromConfigPath(name) |
699 if err != nil { | 693 if err != nil { |
700 » » » » return errors.Annotate(err).Reason("invalid sour
ce title").Err() | 694 » » » » return errors.Annotate(err, "invalid source titl
e").Err() |
701 } | 695 } |
702 | 696 |
703 src := deploy.FrozenLayout_Source{ | 697 src := deploy.FrozenLayout_Source{ |
704 Source: &cpy, | 698 Source: &cpy, |
705 } | 699 } |
706 sg.Source[string(t)] = &src | 700 sg.Source[string(t)] = &src |
707 return nil | 701 return nil |
708 }) | 702 }) |
709 if err != nil { | 703 if err != nil { |
710 » » » return nil, errors.Annotate(err).Reason("failed to load
source group %(name)q from [%(path)s]"). | 704 » » » return nil, errors.Annotate(err, "failed to load source
group %q from [%s]", name, path).Err() |
711 » » » » D("name", name).D("path", path).Err() | |
712 } | 705 } |
713 | 706 |
714 frozen.SourceGroup[string(name)] = &sg | 707 frozen.SourceGroup[string(name)] = &sg |
715 } | 708 } |
716 | 709 |
717 return &frozen, nil | 710 return &frozen, nil |
718 } | 711 } |
719 | 712 |
720 func (l *deployLayout) loadFrozenLayout(c context.Context) error { | 713 func (l *deployLayout) loadFrozenLayout(c context.Context) error { |
721 // Load the frozen configuration file from disk. | 714 // Load the frozen configuration file from disk. |
722 frozen, err := checkoutFrozen(l) | 715 frozen, err := checkoutFrozen(l) |
723 if err != nil { | 716 if err != nil { |
724 » » return errors.Annotate(err).Reason("failed to load frozen checko
ut").Err() | 717 » » return errors.Annotate(err, "failed to load frozen checkout").Er
r() |
725 } | 718 } |
726 | 719 |
727 // Load our source groups and sources. | 720 // Load our source groups and sources. |
728 l.sourceGroups = make(map[title]*layoutSourceGroup, len(frozen.SourceGro
up)) | 721 l.sourceGroups = make(map[title]*layoutSourceGroup, len(frozen.SourceGro
up)) |
729 for sgName, fsg := range frozen.SourceGroup { | 722 for sgName, fsg := range frozen.SourceGroup { |
730 sg := layoutSourceGroup{ | 723 sg := layoutSourceGroup{ |
731 FrozenLayout_SourceGroup: fsg, | 724 FrozenLayout_SourceGroup: fsg, |
732 layout: l, | 725 layout: l, |
733 title: title(sgName), | 726 title: title(sgName), |
734 sources: make(map[title]*layoutSource, len(fsg.Source)), | 727 sources: make(map[title]*layoutSource, len(fsg.Source)), |
735 } | 728 } |
736 | 729 |
737 for srcName, fs := range fsg.Source { | 730 for srcName, fs := range fsg.Source { |
738 src := layoutSource{ | 731 src := layoutSource{ |
739 FrozenLayout_Source: fs, | 732 FrozenLayout_Source: fs, |
740 sg: &sg, | 733 sg: &sg, |
741 title: title(srcName), | 734 title: title(srcName), |
742 } | 735 } |
743 sg.sources[src.title] = &src | 736 sg.sources[src.title] = &src |
744 } | 737 } |
745 | 738 |
746 l.sourceGroups[sg.title] = &sg | 739 l.sourceGroups[sg.title] = &sg |
747 } | 740 } |
748 | 741 |
749 // Build our internally-connected structures from the frozen layout. | 742 // Build our internally-connected structures from the frozen layout. |
750 if err := l.loadApps(c); err != nil { | 743 if err := l.loadApps(c); err != nil { |
751 » » return errors.Annotate(err).Reason("failed to load applications
from [%(path)s]"). | 744 » » return errors.Annotate(err, "failed to load applications from [%
s]", l.ApplicationsPath).Err() |
752 » » » D("path", l.ApplicationsPath).Err() | |
753 } | 745 } |
754 if err := l.loadDeployments(c); err != nil { | 746 if err := l.loadDeployments(c); err != nil { |
755 » » return errors.Annotate(err).Reason("failed to load deployments f
rom [%(path)s]"). | 747 » » return errors.Annotate(err, "failed to load deployments from [%s
]", l.DeploymentsPath).Err() |
756 » » » D("path", l.DeploymentsPath).Err() | |
757 } | 748 } |
758 return nil | 749 return nil |
759 } | 750 } |
760 | 751 |
761 func (l *deployLayout) loadApps(c context.Context) error { | 752 func (l *deployLayout) loadApps(c context.Context) error { |
762 fis, err := ioutil.ReadDir(l.ApplicationsPath) | 753 fis, err := ioutil.ReadDir(l.ApplicationsPath) |
763 if err != nil { | 754 if err != nil { |
764 » » return errors.Annotate(err).Reason("failed to read directory").E
rr() | 755 » » return errors.Annotate(err, "failed to read directory").Err() |
765 } | 756 } |
766 apps := make(map[title]*deploy.Application, len(fis)) | 757 apps := make(map[title]*deploy.Application, len(fis)) |
767 var appBase deploy.Application | 758 var appBase deploy.Application |
768 err = unmarshalTextProtobufDir(l.ApplicationsPath, fis, &appBase, func(n
ame string) error { | 759 err = unmarshalTextProtobufDir(l.ApplicationsPath, fis, &appBase, func(n
ame string) error { |
769 cpy := appBase | 760 cpy := appBase |
770 | 761 |
771 t, err := titleFromConfigPath(name) | 762 t, err := titleFromConfigPath(name) |
772 if err != nil { | 763 if err != nil { |
773 » » » return errors.Annotate(err).Reason("invalid application
title").Err() | 764 » » » return errors.Annotate(err, "invalid application title")
.Err() |
774 } | 765 } |
775 | 766 |
776 apps[t] = &cpy | 767 apps[t] = &cpy |
777 return nil | 768 return nil |
778 }) | 769 }) |
779 if err != nil { | 770 if err != nil { |
780 return err | 771 return err |
781 } | 772 } |
782 | 773 |
783 l.apps = make(map[title]*layoutApp, len(apps)) | 774 l.apps = make(map[title]*layoutApp, len(apps)) |
784 for t, app := range apps { | 775 for t, app := range apps { |
785 proj := layoutApp{ | 776 proj := layoutApp{ |
786 Application: app, | 777 Application: app, |
787 title: t, | 778 title: t, |
788 components: make(map[title]*layoutAppComponent, len(app
.Component)), | 779 components: make(map[title]*layoutAppComponent, len(app
.Component)), |
789 } | 780 } |
790 | 781 |
791 // Initialize components. These can't actually be populated unti
l we have | 782 // Initialize components. These can't actually be populated unti
l we have |
792 // loaded our sources. | 783 // loaded our sources. |
793 for _, comp := range proj.Component { | 784 for _, comp := range proj.Component { |
794 compT := title(comp.Name) | 785 compT := title(comp.Name) |
795 if err := compT.validate(); err != nil { | 786 if err := compT.validate(); err != nil { |
796 » » » » return errors.Annotate(err).Reason("application
%(app)q component %(component)q is not a valid component title"). | 787 » » » » return errors.Annotate(err, "application %q comp
onent %q is not a valid component title", t, comp.Name).Err() |
797 » » » » » D("app", t).D("component", comp.Name).Er
r() | |
798 } | 788 } |
799 proj.components[compT] = &layoutAppComponent{ | 789 proj.components[compT] = &layoutAppComponent{ |
800 Application_Component: comp, | 790 Application_Component: comp, |
801 proj: &proj, | 791 proj: &proj, |
802 title: compT, | 792 title: compT, |
803 } | 793 } |
804 } | 794 } |
805 | 795 |
806 l.apps[t] = &proj | 796 l.apps[t] = &proj |
807 } | 797 } |
808 return nil | 798 return nil |
809 } | 799 } |
810 | 800 |
811 func (l *deployLayout) loadDeployments(c context.Context) error { | 801 func (l *deployLayout) loadDeployments(c context.Context) error { |
812 fis, err := ioutil.ReadDir(l.DeploymentsPath) | 802 fis, err := ioutil.ReadDir(l.DeploymentsPath) |
813 if err != nil { | 803 if err != nil { |
814 » » return errors.Annotate(err).Reason("failed to read directory").E
rr() | 804 » » return errors.Annotate(err, "failed to read directory").Err() |
815 } | 805 } |
816 deployments := make(map[title]*deploy.Deployment, len(fis)) | 806 deployments := make(map[title]*deploy.Deployment, len(fis)) |
817 var deploymentBase deploy.Deployment | 807 var deploymentBase deploy.Deployment |
818 err = unmarshalTextProtobufDir(l.DeploymentsPath, fis, &deploymentBase,
func(name string) error { | 808 err = unmarshalTextProtobufDir(l.DeploymentsPath, fis, &deploymentBase,
func(name string) error { |
819 cpy := deploymentBase | 809 cpy := deploymentBase |
820 | 810 |
821 t, err := titleFromConfigPath(name) | 811 t, err := titleFromConfigPath(name) |
822 if err != nil { | 812 if err != nil { |
823 » » » return errors.Annotate(err).Reason("invalid deployment t
itle").Err() | 813 » » » return errors.Annotate(err, "invalid deployment title").
Err() |
824 } | 814 } |
825 | 815 |
826 deployments[t] = &cpy | 816 deployments[t] = &cpy |
827 return nil | 817 return nil |
828 }) | 818 }) |
829 if err != nil { | 819 if err != nil { |
830 return err | 820 return err |
831 } | 821 } |
832 | 822 |
833 l.deployments = make(map[title]*layoutDeployment, len(deployments)) | 823 l.deployments = make(map[title]*layoutDeployment, len(deployments)) |
834 for t, d := range deployments { | 824 for t, d := range deployments { |
835 dep, err := l.loadDeployment(t, d) | 825 dep, err := l.loadDeployment(t, d) |
836 if err != nil { | 826 if err != nil { |
837 » » » return errors.Annotate(err).Reason("failed to load deplo
yment (%(deployment)q)"). | 827 » » » return errors.Annotate(err, "failed to load deployment (
%q)", t).Err() |
838 » » » » D("deployment", t).Err() | |
839 } | 828 } |
840 l.deployments[t] = dep | 829 l.deployments[t] = dep |
841 l.deploymentNames = append(l.deploymentNames, dep.title) | 830 l.deploymentNames = append(l.deploymentNames, dep.title) |
842 } | 831 } |
843 | 832 |
844 return nil | 833 return nil |
845 } | 834 } |
846 | 835 |
847 func (l *deployLayout) loadDeployment(t title, d *deploy.Deployment) (*layoutDep
loyment, error) { | 836 func (l *deployLayout) loadDeployment(t title, d *deploy.Deployment) (*layoutDep
loyment, error) { |
848 dep := layoutDeployment{ | 837 dep := layoutDeployment{ |
849 Deployment: d, | 838 Deployment: d, |
850 l: l, | 839 l: l, |
851 title: t, | 840 title: t, |
852 sg: l.sourceGroups[title(d.SourceGroup)], | 841 sg: l.sourceGroups[title(d.SourceGroup)], |
853 } | 842 } |
854 if dep.sg == nil { | 843 if dep.sg == nil { |
855 » » return nil, errors.Reason("unknown source group %(sourceGroup)q"
). | 844 » » return nil, errors.Reason("unknown source group %q", d.SourceGro
up).Err() |
856 » » » D("sourceGroup", d.SourceGroup).Err() | |
857 } | 845 } |
858 | 846 |
859 // Resolve our application. | 847 // Resolve our application. |
860 dep.app = l.apps[title(dep.Application)] | 848 dep.app = l.apps[title(dep.Application)] |
861 if dep.app == nil { | 849 if dep.app == nil { |
862 » » return nil, errors.Reason("unknown application %(app)q").D("app"
, dep.Application).Err() | 850 » » return nil, errors.Reason("unknown application %q", dep.Applicat
ion).Err() |
863 } | 851 } |
864 | 852 |
865 // Initialize our Components. Their protobufs cannot not be loaded until | 853 // Initialize our Components. Their protobufs cannot not be loaded until |
866 // we have a checkout. | 854 // we have a checkout. |
867 dep.components = make(map[title]*layoutDeploymentComponent, len(dep.app.
components)) | 855 dep.components = make(map[title]*layoutDeploymentComponent, len(dep.app.
components)) |
868 for compTitle, projComp := range dep.app.components { | 856 for compTitle, projComp := range dep.app.components { |
869 comp := layoutDeploymentComponent{ | 857 comp := layoutDeploymentComponent{ |
870 reldir: deployDirname(projComp.Path), | 858 reldir: deployDirname(projComp.Path), |
871 dep: &dep, | 859 dep: &dep, |
872 comp: projComp, | 860 comp: projComp, |
873 sources: []*layoutSource{dep.sg.sources[title(projComp.S
ource)]}, | 861 sources: []*layoutSource{dep.sg.sources[title(projComp.S
ource)]}, |
874 } | 862 } |
875 if comp.sources[0] == nil { | 863 if comp.sources[0] == nil { |
876 » » » return nil, errors.Reason("application references non-ex
istent source %(source)q"). | 864 » » » return nil, errors.Reason("application references non-ex
istent source %q", projComp.Source).Err() |
877 » » » » D("source", projComp.Source).Err() | |
878 } | 865 } |
879 for _, os := range projComp.OtherSource { | 866 for _, os := range projComp.OtherSource { |
880 src := dep.sg.sources[title(os)] | 867 src := dep.sg.sources[title(os)] |
881 if src == nil { | 868 if src == nil { |
882 » » » » return nil, errors.Reason("application reference
s non-existent other source %(source)q"). | 869 » » » » return nil, errors.Reason("application reference
s non-existent other source %q", os).Err() |
883 » » » » » D("source", os).Err() | |
884 } | 870 } |
885 comp.sources = append(comp.sources, src) | 871 comp.sources = append(comp.sources, src) |
886 } | 872 } |
887 | 873 |
888 dep.components[compTitle] = &comp | 874 dep.components[compTitle] = &comp |
889 dep.componentNames = append(dep.componentNames, compTitle) | 875 dep.componentNames = append(dep.componentNames, compTitle) |
890 } | 876 } |
891 | 877 |
892 // Build a map of cloud project names. | 878 // Build a map of cloud project names. |
893 if dep.CloudProject != nil { | 879 if dep.CloudProject != nil { |
894 cp := layoutDeploymentCloudProject{ | 880 cp := layoutDeploymentCloudProject{ |
895 Deployment_CloudProject: dep.CloudProject, | 881 Deployment_CloudProject: dep.CloudProject, |
896 dep: &dep, | 882 dep: &dep, |
897 } | 883 } |
898 if l.cloudProjects == nil { | 884 if l.cloudProjects == nil { |
899 l.cloudProjects = make(map[string]*layoutDeploymentCloud
Project) | 885 l.cloudProjects = make(map[string]*layoutDeploymentCloud
Project) |
900 } | 886 } |
901 if cur, ok := l.cloudProjects[cp.Name]; ok { | 887 if cur, ok := l.cloudProjects[cp.Name]; ok { |
902 » » » return nil, errors.Reason("cloud project %(name)q define
d by both %(curDep)q and %(thisDep)q"). | 888 » » » return nil, errors.Reason("cloud project %q defined by b
oth %q and %q", cp.Name, cur.dep.title, dep.title).Err() |
903 » » » » D("name", cp.Name).D("curDep", cur.dep.title).D(
"thisDep", dep.title).Err() | |
904 } | 889 } |
905 l.cloudProjects[cp.Name] = &cp | 890 l.cloudProjects[cp.Name] = &cp |
906 | 891 |
907 if len(dep.CloudProject.GkeCluster) > 0 { | 892 if len(dep.CloudProject.GkeCluster) > 0 { |
908 cp.gkeClusters = make(map[string]*layoutDeploymentGKEClu
ster, len(dep.CloudProject.GkeCluster)) | 893 cp.gkeClusters = make(map[string]*layoutDeploymentGKEClu
ster, len(dep.CloudProject.GkeCluster)) |
909 for _, gke := range dep.CloudProject.GkeCluster { | 894 for _, gke := range dep.CloudProject.GkeCluster { |
910 gkeCluster := layoutDeploymentGKECluster{ | 895 gkeCluster := layoutDeploymentGKECluster{ |
911 Deployment_CloudProject_GKECluster: gke, | 896 Deployment_CloudProject_GKECluster: gke, |
912 cloudProject: &cp, | 897 cloudProject: &cp, |
913 } | 898 } |
914 | 899 |
915 // Bind Components to their GKE cluster. | 900 // Bind Components to their GKE cluster. |
916 for _, b := range gke.Pod { | 901 for _, b := range gke.Pod { |
917 comp := dep.components[title(b.Name)] | 902 comp := dep.components[title(b.Name)] |
918 switch { | 903 switch { |
919 case comp == nil: | 904 case comp == nil: |
920 » » » » » » return nil, errors.Reason("unkno
wn component %(comp)q for cluster %(name)q"). | 905 » » » » » » return nil, errors.Reason("unkno
wn component %q for cluster %q", b.Name, gke.Name).Err() |
921 » » » » » » » D("comp", b.Name).D("nam
e", gke.Name).Err() | |
922 | 906 |
923 case b.Replicas <= 0: | 907 case b.Replicas <= 0: |
924 » » » » » » return nil, errors.Reason("GKE c
omponent %(comp)q must have at least 1 replica"). | 908 » » » » » » return nil, errors.Reason("GKE c
omponent %q must have at least 1 replica", b.Name).Err() |
925 » » » » » » » D("comp", b.Name).Err() | |
926 } | 909 } |
927 | 910 |
928 bp := &layoutDeploymentGKEPodBinding{ | 911 bp := &layoutDeploymentGKEPodBinding{ |
929 Deployment_CloudProject_GKEClust
er_PodBinding: b, | 912 Deployment_CloudProject_GKEClust
er_PodBinding: b, |
930 cluster: &gkeCluster, | 913 cluster: &gkeCluster, |
931 } | 914 } |
932 comp.gkePods = append(comp.gkePods, bp) | 915 comp.gkePods = append(comp.gkePods, bp) |
933 gkeCluster.pods = append(gkeCluster.pods
, bp) | 916 gkeCluster.pods = append(gkeCluster.pods
, bp) |
934 } | 917 } |
935 | 918 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 switch st, err := os.Stat(path); { | 951 switch st, err := os.Stat(path); { |
969 case err == nil: | 952 case err == nil: |
970 if !st.IsDir() { | 953 if !st.IsDir() { |
971 return path, nil | 954 return path, nil |
972 } | 955 } |
973 | 956 |
974 case isNotExist(err): | 957 case isNotExist(err): |
975 break | 958 break |
976 | 959 |
977 default: | 960 default: |
978 » » » return "", errors.Annotate(err).Reason("failed to state
%(path)q"). | 961 » » » return "", errors.Annotate(err, "failed to state %q", pa
th).Err() |
979 » » » » D("path", path).Err() | |
980 } | 962 } |
981 | 963 |
982 // Walk up one directory. | 964 // Walk up one directory. |
983 oldDir := dir | 965 oldDir := dir |
984 dir, _ = filepath.Split(dir) | 966 dir, _ = filepath.Split(dir) |
985 if oldDir == dir { | 967 if oldDir == dir { |
986 » » » return "", errors.Reason("could not find %(filename)q st
arting from %(dir)q"). | 968 » » » return "", errors.Reason("could not find %q starting fro
m %q", filename, dir).Err() |
987 » » » » D("filename", filename).D("dir", dir).Err() | |
988 } | 969 } |
989 } | 970 } |
990 } | 971 } |
991 | 972 |
992 type componentRegistrar interface { | 973 type componentRegistrar interface { |
993 addGAEModule(*layoutDeploymentGAEModule) | 974 addGAEModule(*layoutDeploymentGAEModule) |
994 addGKEPod(*layoutDeploymentGKEPodBinding) | 975 addGKEPod(*layoutDeploymentGKEPodBinding) |
995 } | 976 } |
OLD | NEW |