| 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 jobsim | 5 package jobsim |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "encoding/json" | 8 "encoding/json" |
| 9 "fmt" | 9 "fmt" |
| 10 "math/rand" | 10 "math/rand" |
| 11 "net/http" | 11 "net/http" |
| 12 "strings" | |
| 13 "time" | 12 "time" |
| 14 | 13 |
| 15 "github.com/golang/protobuf/jsonpb" | 14 "github.com/golang/protobuf/jsonpb" |
| 16 "google.golang.org/grpc/codes" | 15 "google.golang.org/grpc/codes" |
| 17 | 16 |
| 18 "github.com/luci/luci-go/common/clock" | 17 "github.com/luci/luci-go/common/clock" |
| 19 "github.com/luci/luci-go/common/data/rand/cryptorand" | 18 "github.com/luci/luci-go/common/data/rand/cryptorand" |
| 19 "github.com/luci/luci-go/common/lhttp" |
| 20 "github.com/luci/luci-go/common/logging" | 20 "github.com/luci/luci-go/common/logging" |
| 21 "github.com/luci/luci-go/dm/api/distributor/jobsim" | 21 "github.com/luci/luci-go/dm/api/distributor/jobsim" |
| 22 dm "github.com/luci/luci-go/dm/api/service/v1" | 22 dm "github.com/luci/luci-go/dm/api/service/v1" |
| 23 "github.com/luci/luci-go/grpc/grpcutil" | 23 "github.com/luci/luci-go/grpc/grpcutil" |
| 24 "github.com/luci/luci-go/grpc/prpc" | 24 "github.com/luci/luci-go/grpc/prpc" |
| 25 authlib "github.com/luci/luci-go/server/auth" | 25 authlib "github.com/luci/luci-go/server/auth" |
| 26 "golang.org/x/net/context" | 26 "golang.org/x/net/context" |
| 27 ) | 27 ) |
| 28 | 28 |
| 29 // state is the opaque state data that DM will pass between re-executions of the | 29 // state is the opaque state data that DM will pass between re-executions of the |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 _, err = r.dmc.FinishAttempt(r.c, &dm.FinishAttemptReq{ | 312 _, err = r.dmc.FinishAttempt(r.c, &dm.FinishAttemptReq{ |
| 313 Auth: r.auth, | 313 Auth: r.auth, |
| 314 Data: executionResult(false, 0, time.Time{}), | 314 Data: executionResult(false, 0, time.Time{}), |
| 315 }) | 315 }) |
| 316 if err != nil { | 316 if err != nil { |
| 317 logging.WithError(err).Warningf(r.c, "got error on FinishAttempt
") | 317 logging.WithError(err).Warningf(r.c, "got error on FinishAttempt
") |
| 318 } | 318 } |
| 319 return | 319 return |
| 320 } | 320 } |
| 321 | 321 |
| 322 func isLocalHost(host string) bool { | |
| 323 switch { | |
| 324 case host == "localhost", strings.HasPrefix(host, "localhost:"): | |
| 325 case host == "127.0.0.1", strings.HasPrefix(host, "127.0.0.1:"): | |
| 326 case host == "[::1]", strings.HasPrefix(host, "[::1]:"): | |
| 327 case strings.HasPrefix(host, ":"): | |
| 328 | |
| 329 default: | |
| 330 return false | |
| 331 } | |
| 332 return true | |
| 333 } | |
| 334 | |
| 335 // runJob is analogous to a single Execution of a recipe. It will: | 322 // runJob is analogous to a single Execution of a recipe. It will: |
| 336 // * Activate itself with DM. | 323 // * Activate itself with DM. |
| 337 // * Inspect its previous State to determine where it left off on the previous | 324 // * Inspect its previous State to determine where it left off on the previous |
| 338 // execution. | 325 // execution. |
| 339 // * Execute stages (incrementing the Stage counter in the state, and/or | 326 // * Execute stages (incrementing the Stage counter in the state, and/or |
| 340 // accumulating into Sum) until it hits a stop condition: | 327 // accumulating into Sum) until it hits a stop condition: |
| 341 // * depending on incomplete Attempts | 328 // * depending on incomplete Attempts |
| 342 // * arriving at a final result | 329 // * arriving at a final result |
| 343 // | 330 // |
| 344 // If it hits some underlying error it will return that error, and expect to be | 331 // If it hits some underlying error it will return that error, and expect to be |
| 345 // retried by DM. | 332 // retried by DM. |
| 346 func runJob(c context.Context, host string, state *state, job *jobsim.Phrase, au
th *dm.Execution_Auth, cfgName string) error { | 333 func runJob(c context.Context, host string, state *state, job *jobsim.Phrase, au
th *dm.Execution_Auth, cfgName string) error { |
| 347 tr, err := authlib.GetRPCTransport(c, authlib.NoAuth) | 334 tr, err := authlib.GetRPCTransport(c, authlib.NoAuth) |
| 348 if err != nil { | 335 if err != nil { |
| 349 return err | 336 return err |
| 350 } | 337 } |
| 351 pcli := &prpc.Client{ | 338 pcli := &prpc.Client{ |
| 352 C: &http.Client{Transport: tr}, | 339 C: &http.Client{Transport: tr}, |
| 353 Host: host, | 340 Host: host, |
| 354 Options: prpc.DefaultOptions(), | 341 Options: prpc.DefaultOptions(), |
| 355 } | 342 } |
| 356 » pcli.Options.Insecure = isLocalHost(host) | 343 » pcli.Options.Insecure = lhttp.IsLocalHost(host) |
| 357 dmc := dm.NewDepsPRPCClient(pcli) | 344 dmc := dm.NewDepsPRPCClient(pcli) |
| 358 r := runner{c, auth, dmc, state} | 345 r := runner{c, auth, dmc, state} |
| 359 | 346 |
| 360 ok, err := r.activateExecution() | 347 ok, err := r.activateExecution() |
| 361 if !ok || err != nil { | 348 if !ok || err != nil { |
| 362 return err | 349 return err |
| 363 } | 350 } |
| 364 | 351 |
| 365 stop := false | 352 stop := false |
| 366 for ; r.state.Stage < len(job.Stages); r.state.Stage++ { | 353 for ; r.state.Stage < len(job.Stages); r.state.Stage++ { |
| 367 switch stg := job.Stages[r.state.Stage].StageType.(type) { | 354 switch stg := job.Stages[r.state.Stage].StageType.(type) { |
| 368 case *jobsim.Stage_Deps: | 355 case *jobsim.Stage_Deps: |
| 369 stop, err = r.doDeps(job.Seed, stg.Deps, cfgName) | 356 stop, err = r.doDeps(job.Seed, stg.Deps, cfgName) |
| 370 case *jobsim.Stage_Stall: | 357 case *jobsim.Stage_Stall: |
| 371 r.doStall(stg.Stall) | 358 r.doStall(stg.Stall) |
| 372 case *jobsim.Stage_Failure: | 359 case *jobsim.Stage_Failure: |
| 373 stop, err = r.doFailure(job.Seed, stg.Failure.Chance) | 360 stop, err = r.doFailure(job.Seed, stg.Failure.Chance) |
| 374 default: | 361 default: |
| 375 err = fmt.Errorf("don't know how to handle StageType: %T
", stg) | 362 err = fmt.Errorf("don't know how to handle StageType: %T
", stg) |
| 376 } | 363 } |
| 377 if stop || err != nil { | 364 if stop || err != nil { |
| 378 return err | 365 return err |
| 379 } | 366 } |
| 380 } | 367 } |
| 381 return r.doReturnStage(job.ReturnStage) | 368 return r.doReturnStage(job.ReturnStage) |
| 382 } | 369 } |
| OLD | NEW |