| 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 "fmt" | 8 "fmt" |
| 9 "path/filepath" | 9 "path/filepath" |
| 10 "sort" | 10 "sort" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 func (d *gaeDeployment) clearModules() { | 76 func (d *gaeDeployment) clearModules() { |
| 77 d.modules, d.moduleNames = nil, nil | 77 d.modules, d.moduleNames = nil, nil |
| 78 } | 78 } |
| 79 | 79 |
| 80 func (d *gaeDeployment) stage(w *work, root *managedfs.Dir, params *deployParams
) error { | 80 func (d *gaeDeployment) stage(w *work, root *managedfs.Dir, params *deployParams
) error { |
| 81 sort.Strings(d.moduleNames) | 81 sort.Strings(d.moduleNames) |
| 82 | 82 |
| 83 // Generate a directory for our deployment's modules. | 83 // Generate a directory for our deployment's modules. |
| 84 moduleBaseDir, err := root.EnsureDirectory("modules") | 84 moduleBaseDir, err := root.EnsureDirectory("modules") |
| 85 if err != nil { | 85 if err != nil { |
| 86 » » return errors.Annotate(err).Reason("failed to create modules dir
ectory").Err() | 86 » » return errors.Annotate(err, "failed to create modules directory"
).Err() |
| 87 } | 87 } |
| 88 | 88 |
| 89 // Stage each module in parallel. Also, generate AppEngine-wide YAMLs. | 89 // Stage each module in parallel. Also, generate AppEngine-wide YAMLs. |
| 90 err = w.RunMulti(func(workC chan<- func() error) { | 90 err = w.RunMulti(func(workC chan<- func() error) { |
| 91 // Generate our AppEngine-wide YAML files. | 91 // Generate our AppEngine-wide YAML files. |
| 92 workC <- func() error { | 92 workC <- func() error { |
| 93 return d.generateYAMLs(w, root) | 93 return d.generateYAMLs(w, root) |
| 94 } | 94 } |
| 95 | 95 |
| 96 // Stage each AppEngine module. | 96 // Stage each AppEngine module. |
| 97 for _, name := range d.moduleNames { | 97 for _, name := range d.moduleNames { |
| 98 module := d.modules[name] | 98 module := d.modules[name] |
| 99 workC <- func() error { | 99 workC <- func() error { |
| 100 moduleDir, err := moduleBaseDir.EnsureDirectory(
string(module.comp.comp.title)) | 100 moduleDir, err := moduleBaseDir.EnsureDirectory(
string(module.comp.comp.title)) |
| 101 if err != nil { | 101 if err != nil { |
| 102 » » » » » return errors.Annotate(err).Reason("fail
ed to create module directory for %(module)q"). | 102 » » » » » return errors.Annotate(err, "failed to c
reate module directory for %q", module.comp.comp.title).Err() |
| 103 » » » » » » D("module", module.comp.comp.tit
le).Err() | |
| 104 } | 103 } |
| 105 if err := module.stage(w, moduleDir, params); er
r != nil { | 104 if err := module.stage(w, moduleDir, params); er
r != nil { |
| 106 » » » » » return errors.Annotate(err).Reason("fail
ed to stage module %(name)q"). | 105 » » » » » return errors.Annotate(err, "failed to s
tage module %q", module.comp.comp.title).Err() |
| 107 » » » » » » D("name", module.comp.comp.title
).Err() | |
| 108 } | 106 } |
| 109 return nil | 107 return nil |
| 110 } | 108 } |
| 111 } | 109 } |
| 112 }) | 110 }) |
| 113 if err != nil { | 111 if err != nil { |
| 114 » » return errors.Annotate(err).Reason("failed to stage modules").Er
r() | 112 » » return errors.Annotate(err, "failed to stage modules").Err() |
| 115 } | 113 } |
| 116 | 114 |
| 117 // Build our verison/module map for commit. | 115 // Build our verison/module map for commit. |
| 118 for _, name := range d.moduleNames { | 116 for _, name := range d.moduleNames { |
| 119 module := d.modules[name] | 117 module := d.modules[name] |
| 120 if module.comp.dep.sg.Tainted && !params.commitTainted { | 118 if module.comp.dep.sg.Tainted && !params.commitTainted { |
| 121 log.Fields{ | 119 log.Fields{ |
| 122 "component": module.comp.String(), | 120 "component": module.comp.String(), |
| 123 }.Warningf(w, "Not committing tainted component.") | 121 }.Warningf(w, "Not committing tainted component.") |
| 124 continue | 122 continue |
| (...skipping 26 matching lines...) Expand all Loading... |
| 151 } | 149 } |
| 152 } | 150 } |
| 153 }) | 151 }) |
| 154 } | 152 } |
| 155 | 153 |
| 156 func (d *gaeDeployment) push(w *work) error { | 154 func (d *gaeDeployment) push(w *work) error { |
| 157 // Always push the default module first and independently, since this is
a | 155 // Always push the default module first and independently, since this is
a |
| 158 // GAE requirement for initial deployments. | 156 // GAE requirement for initial deployments. |
| 159 if module := d.modules[gaeDefaultModule]; module != nil { | 157 if module := d.modules[gaeDefaultModule]; module != nil { |
| 160 if err := module.pushFn(w); err != nil { | 158 if err := module.pushFn(w); err != nil { |
| 161 » » » return errors.Annotate(err).Reason("failed to push defau
lt module").Err() | 159 » » » return errors.Annotate(err, "failed to push default modu
le").Err() |
| 162 } | 160 } |
| 163 } | 161 } |
| 164 | 162 |
| 165 // Push the remaining GAE modules in parallel. | 163 // Push the remaining GAE modules in parallel. |
| 166 return w.RunMulti(func(workC chan<- func() error) { | 164 return w.RunMulti(func(workC chan<- func() error) { |
| 167 for _, name := range d.moduleNames { | 165 for _, name := range d.moduleNames { |
| 168 if name == gaeDefaultModule { | 166 if name == gaeDefaultModule { |
| 169 // (Pushed above) | 167 // (Pushed above) |
| 170 continue | 168 continue |
| 171 } | 169 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 193 | 191 |
| 194 err = w.RunMulti(func(workC chan<- func() error) { | 192 err = w.RunMulti(func(workC chan<- func() error) { |
| 195 for _, v := range versions { | 193 for _, v := range versions { |
| 196 modules := d.versionModuleMap[v] | 194 modules := d.versionModuleMap[v] |
| 197 | 195 |
| 198 // Migrate each module's version in parallel. | 196 // Migrate each module's version in parallel. |
| 199 for _, mod := range modules { | 197 for _, mod := range modules { |
| 200 mod := mod | 198 mod := mod |
| 201 workC <- func() error { | 199 workC <- func() error { |
| 202 if err := gcloud.exec("app", "versions",
"migrate", "--service", mod, v).check(w); err != nil { | 200 if err := gcloud.exec("app", "versions",
"migrate", "--service", mod, v).check(w); err != nil { |
| 203 » » » » » » return errors.Annotate(err).Reas
on("failed to set default version"). | 201 » » » » » » return errors.Annotate(err, "fai
led to set default version: %q", v).Err() |
| 204 » » » » » » » D("version", v).Err() | |
| 205 } | 202 } |
| 206 return nil | 203 return nil |
| 207 } | 204 } |
| 208 } | 205 } |
| 209 } | 206 } |
| 210 }) | 207 }) |
| 211 if err != nil { | 208 if err != nil { |
| 212 » » return errors.Annotate(err).Reason("failed to set default versio
ns").Err() | 209 » » return errors.Annotate(err, "failed to set default versions").Er
r() |
| 213 } | 210 } |
| 214 | 211 |
| 215 // If any modules were installed as default, push our new related config
s. | 212 // If any modules were installed as default, push our new related config
s. |
| 216 // Otherwise, do not update them. | 213 // Otherwise, do not update them. |
| 217 if d.alwaysCommitGAEConfig || len(d.versionModuleMap) > 0 { | 214 if d.alwaysCommitGAEConfig || len(d.versionModuleMap) > 0 { |
| 218 for _, deployable := range []string{"dispatch.yaml", "index.yaml
", "queue.yaml", "cron.yaml"} { | 215 for _, deployable := range []string{"dispatch.yaml", "index.yaml
", "queue.yaml", "cron.yaml"} { |
| 219 if _, ok := d.yamlMap[deployable]; !ok { | 216 if _, ok := d.yamlMap[deployable]; !ok { |
| 220 // Does not exist for this project. | 217 // Does not exist for this project. |
| 221 continue | 218 continue |
| 222 } | 219 } |
| 223 | 220 |
| 224 deployablePath := d.yamlDir.File(deployable).String() | 221 deployablePath := d.yamlDir.File(deployable).String() |
| 225 if err := gcloud.exec("app", "deploy", deployablePath).c
heck(w); err != nil { | 222 if err := gcloud.exec("app", "deploy", deployablePath).c
heck(w); err != nil { |
| 226 » » » » return errors.Annotate(err).Reason("failed to de
ploy YAML %(deployable)q from [%(path)s]"). | 223 » » » » return errors.Annotate(err, "failed to deploy YA
ML %q from [%s]", deployable, deployablePath).Err() |
| 227 » » » » » D("deployable", deployable). | |
| 228 » » » » » D("path", deployablePath). | |
| 229 » » » » » Err() | |
| 230 } | 224 } |
| 231 } | 225 } |
| 232 } | 226 } |
| 233 return nil | 227 return nil |
| 234 } | 228 } |
| 235 | 229 |
| 236 func (d *gaeDeployment) generateYAMLs(w *work, root *managedfs.Dir) error { | 230 func (d *gaeDeployment) generateYAMLs(w *work, root *managedfs.Dir) error { |
| 237 // Get ALL AppEngine modules for this cloud project. | 231 // Get ALL AppEngine modules for this cloud project. |
| 238 var ( | 232 var ( |
| 239 err error | 233 err error |
| 240 yamls = make(map[string]interface{}, 3) | 234 yamls = make(map[string]interface{}, 3) |
| 241 ) | 235 ) |
| 242 | 236 |
| 243 yamls["index.yaml"] = gaeBuildIndexYAML(d.project) | 237 yamls["index.yaml"] = gaeBuildIndexYAML(d.project) |
| 244 yamls["cron.yaml"] = gaeBuildCronYAML(d.project) | 238 yamls["cron.yaml"] = gaeBuildCronYAML(d.project) |
| 245 if yamls["dispatch.yaml"], err = gaeBuildDispatchYAML(d.project); err !=
nil { | 239 if yamls["dispatch.yaml"], err = gaeBuildDispatchYAML(d.project); err !=
nil { |
| 246 » » return errors.Annotate(err).Reason("failed to generate dispatch.
yaml").Err() | 240 » » return errors.Annotate(err, "failed to generate dispatch.yaml").
Err() |
| 247 } | 241 } |
| 248 if yamls["queue.yaml"], err = gaeBuildQueueYAML(d.project); err != nil { | 242 if yamls["queue.yaml"], err = gaeBuildQueueYAML(d.project); err != nil { |
| 249 » » return errors.Annotate(err).Reason("failed to generate index.yam
l").Err() | 243 » » return errors.Annotate(err, "failed to generate index.yaml").Err
() |
| 250 } | 244 } |
| 251 | 245 |
| 252 for k, v := range yamls { | 246 for k, v := range yamls { |
| 253 f := root.File(k) | 247 f := root.File(k) |
| 254 if err := f.GenerateYAML(w, v); err != nil { | 248 if err := f.GenerateYAML(w, v); err != nil { |
| 255 » » » return errors.Annotate(err).Reason("failed to generate %
(yaml)q").D("yaml", k).Err() | 249 » » » return errors.Annotate(err, "failed to generate %q", k).
Err() |
| 256 } | 250 } |
| 257 } | 251 } |
| 258 | 252 |
| 259 d.yamlDir = root | 253 d.yamlDir = root |
| 260 d.yamlMap = yamls | 254 d.yamlMap = yamls |
| 261 return nil | 255 return nil |
| 262 } | 256 } |
| 263 | 257 |
| 264 // stagedGAEModule is a single staged AppEngine module. | 258 // stagedGAEModule is a single staged AppEngine module. |
| 265 type stagedGAEModule struct { | 259 type stagedGAEModule struct { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 295 // | 289 // |
| 296 // Go / Managed VM (Same as Go/Classic, plus): | 290 // Go / Managed VM (Same as Go/Classic, plus): |
| 297 // ------------------------------------------- | 291 // ------------------------------------------- |
| 298 // <root>/component/Dockerfile (Generated Docker file) | 292 // <root>/component/Dockerfile (Generated Docker file) |
| 299 func (m *stagedGAEModule) stage(w *work, root *managedfs.Dir, params *deployPara
ms) error { | 293 func (m *stagedGAEModule) stage(w *work, root *managedfs.Dir, params *deployPara
ms) error { |
| 300 // Calculate our version. | 294 // Calculate our version. |
| 301 if m.version = params.forceVersion; m.version == nil { | 295 if m.version = params.forceVersion; m.version == nil { |
| 302 var err error | 296 var err error |
| 303 m.version, err = makeCloudProjectVersion(m.comp.dep.cloudProject
, m.comp.source()) | 297 m.version, err = makeCloudProjectVersion(m.comp.dep.cloudProject
, m.comp.source()) |
| 304 if err != nil { | 298 if err != nil { |
| 305 » » » return errors.Annotate(err).Reason("failed to calculate
cloud project version").Err() | 299 » » » return errors.Annotate(err, "failed to calculate cloud p
roject version").Err() |
| 306 } | 300 } |
| 307 } | 301 } |
| 308 | 302 |
| 309 // The directory where the base YAML and other depoyment-relative data w
ill be | 303 // The directory where the base YAML and other depoyment-relative data w
ill be |
| 310 // written. | 304 // written. |
| 311 base := root | 305 base := root |
| 312 | 306 |
| 313 // appYAMLPath is used in the immediate "switch" statement as a | 307 // appYAMLPath is used in the immediate "switch" statement as a |
| 314 // parameter to some inline functions. It will be populated later in thi
s | 308 // parameter to some inline functions. It will be populated later in thi
s |
| 315 // staging function, well before those inline functions are evaluated. | 309 // staging function, well before those inline functions are evaluated. |
| 316 // | 310 // |
| 317 // It is a pointer so that if, somehow, this does not end up being the c
ase, | 311 // It is a pointer so that if, somehow, this does not end up being the c
ase, |
| 318 // we will panic instead of silently using an empty string. | 312 // we will panic instead of silently using an empty string. |
| 319 var appYAMLPath *string | 313 var appYAMLPath *string |
| 320 | 314 |
| 321 // Our "__deploy" directory will be where deploy-specific artifacts are | 315 // Our "__deploy" directory will be where deploy-specific artifacts are |
| 322 // blended with the current app. The name is chosen to (probably) not | 316 // blended with the current app. The name is chosen to (probably) not |
| 323 // interfere with app files. | 317 // interfere with app files. |
| 324 deployDir, err := root.EnsureDirectory("__deploy") | 318 deployDir, err := root.EnsureDirectory("__deploy") |
| 325 if err != nil { | 319 if err != nil { |
| 326 » » return errors.Annotate(err).Reason("failed to create deploy dire
ctory").Err() | 320 » » return errors.Annotate(err, "failed to create deploy directory")
.Err() |
| 327 } | 321 } |
| 328 | 322 |
| 329 // Build each Component. We will delete any existing contents and leave
it | 323 // Build each Component. We will delete any existing contents and leave
it |
| 330 // unmanaged to allow our build system to put whatever files it wants in | 324 // unmanaged to allow our build system to put whatever files it wants in |
| 331 // there. | 325 // there. |
| 332 buildDir, err := deployDir.EnsureDirectory("build") | 326 buildDir, err := deployDir.EnsureDirectory("build") |
| 333 if err != nil { | 327 if err != nil { |
| 334 » » return errors.Annotate(err).Reason("failed to create build direc
tory").Err() | 328 » » return errors.Annotate(err, "failed to create build directory").
Err() |
| 335 } | 329 } |
| 336 if err := buildDir.CleanUp(); err != nil { | 330 if err := buildDir.CleanUp(); err != nil { |
| 337 » » return errors.Annotate(err).Reason("failed to cleanup build dire
ctory").Err() | 331 » » return errors.Annotate(err, "failed to cleanup build directory")
.Err() |
| 338 } | 332 } |
| 339 buildDir.Ignore() | 333 buildDir.Ignore() |
| 340 | 334 |
| 341 // Build our Component into this directory. | 335 // Build our Component into this directory. |
| 342 if err := buildComponent(w, m.comp, buildDir); err != nil { | 336 if err := buildComponent(w, m.comp, buildDir); err != nil { |
| 343 » » return errors.Annotate(err).Reason("failed to build component").
Err() | 337 » » return errors.Annotate(err, "failed to build component").Err() |
| 344 } | 338 } |
| 345 | 339 |
| 346 switch t := m.GetRuntime().(type) { | 340 switch t := m.GetRuntime().(type) { |
| 347 case *deploy.AppEngineModule_GoModule_: | 341 case *deploy.AppEngineModule_GoModule_: |
| 348 gom := t.GoModule | 342 gom := t.GoModule |
| 349 | 343 |
| 350 // Construct a GOPATH for this module. | 344 // Construct a GOPATH for this module. |
| 351 goPath, err := root.EnsureDirectory("gopath") | 345 goPath, err := root.EnsureDirectory("gopath") |
| 352 if err != nil { | 346 if err != nil { |
| 353 » » » return errors.Annotate(err).Reason("failed to create GOP
ATH base").Err() | 347 » » » return errors.Annotate(err, "failed to create GOPATH bas
e").Err() |
| 354 } | 348 } |
| 355 if err := stageGoPath(w, m.comp, goPath); err != nil { | 349 if err := stageGoPath(w, m.comp, goPath); err != nil { |
| 356 » » » return errors.Annotate(err).Reason("failed to stage GOPA
TH").Err() | 350 » » » return errors.Annotate(err, "failed to stage GOPATH").Er
r() |
| 357 } | 351 } |
| 358 | 352 |
| 359 // Generate a stub Go package, which we will populate with an en
try point. | 353 // Generate a stub Go package, which we will populate with an en
try point. |
| 360 goSrcDir, err := root.EnsureDirectory("src") | 354 goSrcDir, err := root.EnsureDirectory("src") |
| 361 if err != nil { | 355 if err != nil { |
| 362 » » » return errors.Annotate(err).Reason("failed to create stu
b source directory").Err() | 356 » » » return errors.Annotate(err, "failed to create stub sourc
e directory").Err() |
| 363 } | 357 } |
| 364 | 358 |
| 365 mainPkg := fmt.Sprintf("%s/main", m.comp.comp.title) | 359 mainPkg := fmt.Sprintf("%s/main", m.comp.comp.title) |
| 366 mainPkgParts := strings.Split(mainPkg, "/") | 360 mainPkgParts := strings.Split(mainPkg, "/") |
| 367 mainPkgDir, err := goSrcDir.EnsureDirectory(mainPkgParts[0], mai
nPkgParts[1:]...) | 361 mainPkgDir, err := goSrcDir.EnsureDirectory(mainPkgParts[0], mai
nPkgParts[1:]...) |
| 368 if err != nil { | 362 if err != nil { |
| 369 » » » return errors.Annotate(err).Reason("failed to create dir
ectory for main package %(pkg)q"). | 363 » » » return errors.Annotate(err, "failed to create directory
for main package %q", mainPkg).Err() |
| 370 » » » » D("pkg", mainPkg).Err() | |
| 371 } | 364 } |
| 372 m.goPath = []string{root.String(), goPath.String()} | 365 m.goPath = []string{root.String(), goPath.String()} |
| 373 | 366 |
| 374 // Choose how to push based on whether or not this is a Managed
VM. | 367 // Choose how to push based on whether or not this is a Managed
VM. |
| 375 if m.GetManagedVm() != nil { | 368 if m.GetManagedVm() != nil { |
| 376 // If this is a Managed VM, symlink files from the main
package. | 369 // If this is a Managed VM, symlink files from the main
package. |
| 377 // | 370 // |
| 378 // NOTE: This has the effect of prohibiting the entry po
int package for | 371 // NOTE: This has the effect of prohibiting the entry po
int package for |
| 379 // GAE Managed VMs from importing "internal" directories
, since this stub | 372 // GAE Managed VMs from importing "internal" directories
, since this stub |
| 380 // space is outside of the main package space. | 373 // space is outside of the main package space. |
| 381 pkgPath := findGoPackage(t.GoModule.EntryPackage, m.goPa
th) | 374 pkgPath := findGoPackage(t.GoModule.EntryPackage, m.goPa
th) |
| 382 if pkgPath == "" { | 375 if pkgPath == "" { |
| 383 » » » » return errors.Reason("unable to find path for %(
package)q").D("package", t.GoModule.EntryPackage).Err() | 376 » » » » return errors.Reason("unable to find path for %q
", t.GoModule.EntryPackage).Err() |
| 384 } | 377 } |
| 385 | 378 |
| 386 if err := mainPkgDir.ShallowSymlinkFrom(pkgPath, true);
err != nil { | 379 if err := mainPkgDir.ShallowSymlinkFrom(pkgPath, true);
err != nil { |
| 387 » » » » return errors.Annotate(err).Reason("failed to cr
eate shallow symlink of main module").Err() | 380 » » » » return errors.Annotate(err, "failed to create sh
allow symlink of main module").Err() |
| 388 } | 381 } |
| 389 | 382 |
| 390 m.localBuildFn = func(w *work) error { | 383 m.localBuildFn = func(w *work) error { |
| 391 return m.localBuildGo(w, t.GoModule.EntryPackage
) | 384 return m.localBuildGo(w, t.GoModule.EntryPackage
) |
| 392 } | 385 } |
| 393 m.pushFn = func(w *work) error { | 386 m.pushFn = func(w *work) error { |
| 394 return m.pushGoMVM(w, *appYAMLPath) | 387 return m.pushGoMVM(w, *appYAMLPath) |
| 395 } | 388 } |
| 396 } else { | 389 } else { |
| 397 // Generate a classic GAE stub. Since GAE works through
"init()", all this | 390 // Generate a classic GAE stub. Since GAE works through
"init()", all this |
| 398 // stub has to do is import the actual entry point packa
ge. | 391 // stub has to do is import the actual entry point packa
ge. |
| 399 if err := m.writeGoClassicGAEStub(w, mainPkgDir, gom.Ent
ryPackage); err != nil { | 392 if err := m.writeGoClassicGAEStub(w, mainPkgDir, gom.Ent
ryPackage); err != nil { |
| 400 » » » » return errors.Annotate(err).Reason("failed to ge
nerate GAE classic entry stub").Err() | 393 » » » » return errors.Annotate(err, "failed to generate
GAE classic entry stub").Err() |
| 401 } | 394 } |
| 402 | 395 |
| 403 m.localBuildFn = func(w *work) error { | 396 m.localBuildFn = func(w *work) error { |
| 404 return m.localBuildGo(w, mainPkg) | 397 return m.localBuildGo(w, mainPkg) |
| 405 } | 398 } |
| 406 m.pushFn = func(w *work) error { | 399 m.pushFn = func(w *work) error { |
| 407 return m.pushClassic(w, *appYAMLPath) | 400 return m.pushClassic(w, *appYAMLPath) |
| 408 } | 401 } |
| 409 } | 402 } |
| 410 | 403 |
| 411 // Write artifacts into the Go stub package path. | 404 // Write artifacts into the Go stub package path. |
| 412 base = mainPkgDir | 405 base = mainPkgDir |
| 413 | 406 |
| 414 case *deploy.AppEngineModule_StaticModule_: | 407 case *deploy.AppEngineModule_StaticModule_: |
| 415 m.pushFn = func(w *work) error { | 408 m.pushFn = func(w *work) error { |
| 416 return m.pushClassic(w, *appYAMLPath) | 409 return m.pushClassic(w, *appYAMLPath) |
| 417 } | 410 } |
| 418 } | 411 } |
| 419 | 412 |
| 420 // Build our static files map. | 413 // Build our static files map. |
| 421 // | 414 // |
| 422 // For each static files directory, symlink a generated directory immedi
ately | 415 // For each static files directory, symlink a generated directory immedi
ately |
| 423 // under our deployment directory. | 416 // under our deployment directory. |
| 424 staticDir, err := deployDir.EnsureDirectory("static") | 417 staticDir, err := deployDir.EnsureDirectory("static") |
| 425 if err != nil { | 418 if err != nil { |
| 426 » » return errors.Annotate(err).Reason("failed to create static dire
ctory").Err() | 419 » » return errors.Annotate(err, "failed to create static directory")
.Err() |
| 427 } | 420 } |
| 428 | 421 |
| 429 staticMap := make(map[string]string) | 422 staticMap := make(map[string]string) |
| 430 staticBuildPathMap := make(map[*deploy.BuildPath]string) | 423 staticBuildPathMap := make(map[*deploy.BuildPath]string) |
| 431 if handlerSet := m.Handlers; handlerSet != nil { | 424 if handlerSet := m.Handlers; handlerSet != nil { |
| 432 for _, h := range handlerSet.Handler { | 425 for _, h := range handlerSet.Handler { |
| 433 var bp *deploy.BuildPath | 426 var bp *deploy.BuildPath |
| 434 switch t := h.GetContent().(type) { | 427 switch t := h.GetContent().(type) { |
| 435 case *deploy.AppEngineModule_Handler_StaticBuildDir: | 428 case *deploy.AppEngineModule_Handler_StaticBuildDir: |
| 436 bp = t.StaticBuildDir | 429 bp = t.StaticBuildDir |
| 437 case *deploy.AppEngineModule_Handler_StaticFiles_: | 430 case *deploy.AppEngineModule_Handler_StaticFiles_: |
| 438 bp = t.StaticFiles.GetBuild() | 431 bp = t.StaticFiles.GetBuild() |
| 439 } | 432 } |
| 440 if bp == nil { | 433 if bp == nil { |
| 441 continue | 434 continue |
| 442 } | 435 } |
| 443 | 436 |
| 444 // Have we already mapped this BuildPath? | 437 // Have we already mapped this BuildPath? |
| 445 if _, ok := staticBuildPathMap[bp]; ok { | 438 if _, ok := staticBuildPathMap[bp]; ok { |
| 446 continue | 439 continue |
| 447 } | 440 } |
| 448 | 441 |
| 449 // Get the actual path for this BuildPath entry. | 442 // Get the actual path for this BuildPath entry. |
| 450 dirPath, err := m.comp.buildPath(bp) | 443 dirPath, err := m.comp.buildPath(bp) |
| 451 if err != nil { | 444 if err != nil { |
| 452 » » » » return errors.Annotate(err).Reason("cannot resol
ve static directory").Err() | 445 » » » » return errors.Annotate(err, "cannot resolve stat
ic directory").Err() |
| 453 } | 446 } |
| 454 | 447 |
| 455 // Do we already have a static map entry for this filesy
stem source path? | 448 // Do we already have a static map entry for this filesy
stem source path? |
| 456 staticName, ok := staticMap[dirPath] | 449 staticName, ok := staticMap[dirPath] |
| 457 if !ok { | 450 if !ok { |
| 458 sd := staticDir.File(strconv.Itoa(len(staticMap)
)) | 451 sd := staticDir.File(strconv.Itoa(len(staticMap)
)) |
| 459 if err := sd.SymlinkFrom(dirPath, true); err !=
nil { | 452 if err := sd.SymlinkFrom(dirPath, true); err !=
nil { |
| 460 » » » » » return errors.Annotate(err).Reason("fail
ed to symlink static content for [%(path)s]"). | 453 » » » » » return errors.Annotate(err, "failed to s
ymlink static content for [%s]", dirPath).Err() |
| 461 » » » » » » D("path", dirPath).Err() | |
| 462 } | 454 } |
| 463 if staticName, err = root.RelPathFrom(sd.String(
)); err != nil { | 455 if staticName, err = root.RelPathFrom(sd.String(
)); err != nil { |
| 464 » » » » » return errors.Annotate(err).Reason("fail
ed to get relative path").Err() | 456 » » » » » return errors.Annotate(err, "failed to g
et relative path").Err() |
| 465 } | 457 } |
| 466 staticMap[dirPath] = staticName | 458 staticMap[dirPath] = staticName |
| 467 } | 459 } |
| 468 staticBuildPathMap[bp] = staticName | 460 staticBuildPathMap[bp] = staticName |
| 469 } | 461 } |
| 470 } | 462 } |
| 471 | 463 |
| 472 // "app.yaml" / "module.yaml" | 464 // "app.yaml" / "module.yaml" |
| 473 appYAML, err := gaeBuildAppYAML(m.AppEngineModule, staticBuildPathMap) | 465 appYAML, err := gaeBuildAppYAML(m.AppEngineModule, staticBuildPathMap) |
| 474 if err != nil { | 466 if err != nil { |
| 475 » » return errors.Annotate(err).Reason("failed to generate module YA
ML").Err() | 467 » » return errors.Annotate(err, "failed to generate module YAML").Er
r() |
| 476 } | 468 } |
| 477 | 469 |
| 478 appYAMLName := "module.yaml" | 470 appYAMLName := "module.yaml" |
| 479 if m.ModuleName == "" { | 471 if m.ModuleName == "" { |
| 480 // This is the default module, so name it "app.yaml". | 472 // This is the default module, so name it "app.yaml". |
| 481 appYAMLName = "app.yaml" | 473 appYAMLName = "app.yaml" |
| 482 } | 474 } |
| 483 f := base.File(appYAMLName) | 475 f := base.File(appYAMLName) |
| 484 if err := f.GenerateYAML(w, appYAML); err != nil { | 476 if err := f.GenerateYAML(w, appYAML); err != nil { |
| 485 » » return errors.Annotate(err).Reason("failed to generate %(filenam
e)q file"). | 477 » » return errors.Annotate(err, "failed to generate %q file", appYAM
LName).Err() |
| 486 » » » D("filename", appYAMLName).Err() | |
| 487 } | 478 } |
| 488 s := f.String() | 479 s := f.String() |
| 489 appYAMLPath = &s | 480 appYAMLPath = &s |
| 490 | 481 |
| 491 // Cleanup our staging filesystem. | 482 // Cleanup our staging filesystem. |
| 492 if err := root.CleanUp(); err != nil { | 483 if err := root.CleanUp(); err != nil { |
| 493 » » return errors.Annotate(err).Reason("failed to cleanup component
directory").Err() | 484 » » return errors.Annotate(err, "failed to cleanup component directo
ry").Err() |
| 494 } | 485 } |
| 495 return nil | 486 return nil |
| 496 } | 487 } |
| 497 | 488 |
| 498 func (m *stagedGAEModule) writeGoClassicGAEStub(w *work, mainDir *managedfs.Dir,
pkg string) error { | 489 func (m *stagedGAEModule) writeGoClassicGAEStub(w *work, mainDir *managedfs.Dir,
pkg string) error { |
| 499 main := mainDir.File("stub.go") | 490 main := mainDir.File("stub.go") |
| 500 return main.GenerateGo(w, fmt.Sprintf(``+ | 491 return main.GenerateGo(w, fmt.Sprintf(``+ |
| 501 ` | 492 ` |
| 502 // Package entry is a stub entry package for classic AppEngine application. | 493 // Package entry is a stub entry package for classic AppEngine application. |
| 503 // | 494 // |
| (...skipping 14 matching lines...) Expand all Loading... |
| 518 gcloud, err := w.tools.gcloud(m.gaeDep.project.Name) | 509 gcloud, err := w.tools.gcloud(m.gaeDep.project.Name) |
| 519 if err != nil { | 510 if err != nil { |
| 520 return err | 511 return err |
| 521 } | 512 } |
| 522 | 513 |
| 523 appPath, appYAML := filepath.Split(appYAMLPath) | 514 appPath, appYAML := filepath.Split(appYAMLPath) |
| 524 x := gcloud.exec("app", "deploy", "--no-promote", "--version", m.version
.String(), appYAML). | 515 x := gcloud.exec("app", "deploy", "--no-promote", "--version", m.version
.String(), appYAML). |
| 525 cwd(appPath) | 516 cwd(appPath) |
| 526 x = addGoEnv(m.goPath, x) | 517 x = addGoEnv(m.goPath, x) |
| 527 if err := x.check(w); err != nil { | 518 if err := x.check(w); err != nil { |
| 528 » » return errors.Annotate(err).Reason("failed to deploy classic GAE
module").Err() | 519 » » return errors.Annotate(err, "failed to deploy classic GAE module
").Err() |
| 529 } | 520 } |
| 530 return nil | 521 return nil |
| 531 } | 522 } |
| 532 | 523 |
| 533 // localBuildGo performs verification of a Go binary. | 524 // localBuildGo performs verification of a Go binary. |
| 534 func (m *stagedGAEModule) localBuildGo(w *work, mainPkg string) error { | 525 func (m *stagedGAEModule) localBuildGo(w *work, mainPkg string) error { |
| 535 gt, err := w.goTool(m.goPath) | 526 gt, err := w.goTool(m.goPath) |
| 536 if err != nil { | 527 if err != nil { |
| 537 » » return errors.Annotate(err).Reason("failed to get Go tool").Err(
) | 528 » » return errors.Annotate(err, "failed to get Go tool").Err() |
| 538 } | 529 } |
| 539 if err := gt.build(w, "", mainPkg); err != nil { | 530 if err := gt.build(w, "", mainPkg); err != nil { |
| 540 » » return errors.Annotate(err).Reason("failed to local build %(pkg)
q").D("pkg", mainPkg).Err() | 531 » » return errors.Annotate(err, "failed to local build %q", mainPkg)
.Err() |
| 541 } | 532 } |
| 542 return nil | 533 return nil |
| 543 } | 534 } |
| 544 | 535 |
| 545 // pushGoMVM pushes a Go Managed VM version to the AppEngine instance. | 536 // pushGoMVM pushes a Go Managed VM version to the AppEngine instance. |
| 546 func (m *stagedGAEModule) pushGoMVM(w *work, appYAMLPath string) error { | 537 func (m *stagedGAEModule) pushGoMVM(w *work, appYAMLPath string) error { |
| 547 appDir, appYAML := filepath.Split(appYAMLPath) | 538 appDir, appYAML := filepath.Split(appYAMLPath) |
| 548 | 539 |
| 549 // Deploy Managed VM. | 540 // Deploy Managed VM. |
| 550 aedeploy, err := w.tools.aedeploy(m.goPath) | 541 aedeploy, err := w.tools.aedeploy(m.goPath) |
| 551 if err != nil { | 542 if err != nil { |
| 552 » » return errors.Annotate(err).Err() | 543 » » return errors.Annotate(err, "").Err() |
| 553 } | 544 } |
| 554 | 545 |
| 555 gcloud, err := w.tools.gcloud(m.gaeDep.project.Name) | 546 gcloud, err := w.tools.gcloud(m.gaeDep.project.Name) |
| 556 if err != nil { | 547 if err != nil { |
| 557 return err | 548 return err |
| 558 } | 549 } |
| 559 | 550 |
| 560 // Deploy via: aedeploy gcloud app deploy | 551 // Deploy via: aedeploy gcloud app deploy |
| 561 // | 552 // |
| 562 // We will promote it later on commit. | 553 // We will promote it later on commit. |
| 563 gcloudArgs := []string{ | 554 gcloudArgs := []string{ |
| 564 "app", "deploy", appYAML, | 555 "app", "deploy", appYAML, |
| 565 "--version", m.version.String(), | 556 "--version", m.version.String(), |
| 566 "--no-promote", | 557 "--no-promote", |
| 567 } | 558 } |
| 568 | 559 |
| 569 // Set verbosity based on current logging level. | 560 // Set verbosity based on current logging level. |
| 570 logLevel := log.GetLevel(w) | 561 logLevel := log.GetLevel(w) |
| 571 switch logLevel { | 562 switch logLevel { |
| 572 case log.Info: | 563 case log.Info: |
| 573 gcloudArgs = append(gcloudArgs, []string{"--verbosity", "info"}.
..) | 564 gcloudArgs = append(gcloudArgs, []string{"--verbosity", "info"}.
..) |
| 574 | 565 |
| 575 case log.Debug: | 566 case log.Debug: |
| 576 gcloudArgs = append(gcloudArgs, []string{"--verbosity", "debug"}
...) | 567 gcloudArgs = append(gcloudArgs, []string{"--verbosity", "debug"}
...) |
| 577 } | 568 } |
| 578 | 569 |
| 579 x := aedeploy.bootstrap(gcloud.exec(gcloudArgs[0], gcloudArgs[1:]...)).o
utputAt(logLevel).cwd(appDir) | 570 x := aedeploy.bootstrap(gcloud.exec(gcloudArgs[0], gcloudArgs[1:]...)).o
utputAt(logLevel).cwd(appDir) |
| 580 if err := x.check(w); err != nil { | 571 if err := x.check(w); err != nil { |
| 581 » » return errors.Annotate(err).Reason("failed to deploy managed VM"
).Err() | 572 » » return errors.Annotate(err, "failed to deploy managed VM").Err() |
| 582 } | 573 } |
| 583 return nil | 574 return nil |
| 584 } | 575 } |
| OLD | NEW |