| 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 |