Skip to content

Commit

Permalink
feat(api): defaultRegion (#5212)
Browse files Browse the repository at this point in the history
Signed-off-by: Yvonnick Esnault <[email protected]>
  • Loading branch information
yesnault authored May 28, 2020
1 parent c9486c0 commit 132c980
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 8 deletions.
13 changes: 7 additions & 6 deletions engine/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,11 @@ type Configuration struct {
Token string `toml:"token" comment:"Token shared between Izanami and CDS to be able to send webhooks from izanami" json:"-"`
} `toml:"izanami" comment:"Feature flipping provider: https://maif.github.io/izanami" json:"izanami"`
} `toml:"features" comment:"###########################\n CDS Features flipping Settings \n##########################" json:"features"`
Services []sdk.ServiceConfiguration `toml:"services" comment:"###########################\n CDS Services Settings \n##########################" json:"services"`
DefaultOS string `toml:"defaultOS" default:"linux" comment:"if no model and os/arch is specified in your job's requirements then spawn worker on this operating system (example: freebsd, linux, windows)" json:"defaultOS"`
DefaultArch string `toml:"defaultArch" default:"amd64" comment:"if no model and no os/arch is specified in your job's requirements then spawn worker on this architecture (example: amd64, arm, 386)" json:"defaultArch"`
Graylog struct {
Services []sdk.ServiceConfiguration `toml:"services" comment:"###########################\n CDS Services Settings \n##########################" json:"services"`
DefaultOS string `toml:"defaultOS" default:"linux" comment:"if no model and os/arch is specified in your job's requirements then spawn worker on this operating system (example: freebsd, linux, windows)" json:"defaultOS"`
DefaultArch string `toml:"defaultArch" default:"amd64" comment:"if no model and no os/arch is specified in your job's requirements then spawn worker on this architecture (example: amd64, arm, 386)" json:"defaultArch"`
DefaultRegion string `toml:"defaultRegion" default:"" comment:"Optional. If no region in your job's requirements then spawn worker with this region. You need to have an hatchery managing this region." json:"defaultRegion"`
Graylog struct {
AccessToken string `toml:"accessToken" json:"-"`
Stream string `toml:"stream" json:"-"`
URL string `toml:"url" comment:"Example: http://localhost:9000" json:"url"`
Expand Down Expand Up @@ -719,7 +720,7 @@ func (a *API) Serve(ctx context.Context) error {

migrate.Add(ctx, sdk.Migration{Name: "RefactorProjectVCSServerCrypto", Release: "0.44.0", Blocker: true, Automatic: true, ExecFunc: func(ctx context.Context) error {
return migrate.RefactorProjectVCSServers(ctx, a.DBConnectionFactory.GetDBMap())
}})
}})

migrate.Add(ctx, sdk.Migration{Name: "RefactorWorkerModelCrypto", Release: "0.44.0", Blocker: true, Automatic: true, ExecFunc: func(ctx context.Context) error {
return migrate.RefactorWorkerModelCrypto(ctx, a.DBConnectionFactory.GetDBMap())
Expand Down Expand Up @@ -812,7 +813,7 @@ func (a *API) Serve(ctx context.Context) error {
}, a.PanicDump())
sdk.GoRoutine(ctx, "workflow.Initialize",
func(ctx context.Context) {
workflow.Initialize(ctx, a.DBConnectionFactory.GetDBMap, a.Cache, a.Config.URL.UI, a.Config.DefaultOS, a.Config.DefaultArch)
workflow.Initialize(ctx, a.DBConnectionFactory.GetDBMap, a.Cache, a.Config.URL.UI, a.Config.DefaultOS, a.Config.DefaultArch, a.Config.DefaultRegion)
}, a.PanicDump())
sdk.GoRoutine(ctx, "PushInElasticSearch",
func(ctx context.Context) {
Expand Down
17 changes: 17 additions & 0 deletions engine/api/workflow/gorp_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,23 @@ func (j JobRun) WorkflowNodeRunJob() (sdk.WorkflowNodeJobRun, error) {
})
}
}
if defaultRegion != "" {
var regionFound bool
for _, req := range jr.Job.Action.Requirements {
if req.Type == sdk.RegionRequirement {
regionFound = true
break
}
}

if !regionFound {
jr.Job.Action.Requirements = append(jr.Job.Action.Requirements, sdk.Requirement{
Name: defaultRegion,
Type: sdk.RegionRequirement,
Value: defaultRegion,
})
}
}
return jr, nil
}

Expand Down
10 changes: 8 additions & 2 deletions engine/api/workflow/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import (
"github.com/ovh/cds/sdk/log"
)

var baseUIURL, defaultOS, defaultArch string
var baseUIURL, defaultOS, defaultArch, defaultRegion string

//Initialize starts goroutines for workflows
func Initialize(ctx context.Context, DBFunc func() *gorp.DbMap, store cache.Store, uiURL, confDefaultOS, confDefaultArch string) {
func Initialize(ctx context.Context, DBFunc func() *gorp.DbMap, store cache.Store, uiURL, confDefaultOS, confDefaultArch, confDefaultRegion string) {
baseUIURL = uiURL
defaultOS = confDefaultOS
defaultArch = confDefaultArch
defaultRegion = confDefaultRegion
tickStop := time.NewTicker(30 * time.Minute)
tickHeart := time.NewTicker(10 * time.Second)
defer tickHeart.Stop()
Expand All @@ -41,3 +42,8 @@ func Initialize(ctx context.Context, DBFunc func() *gorp.DbMap, store cache.Stor
}
}
}

// SetDefaultRegion is used by unit tests
func SetDefaultRegion(r string) {
defaultRegion = r
}
57 changes: 57 additions & 0 deletions engine/api/workflow_queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,63 @@ func Test_postTakeWorkflowJobHandler(t *testing.T) {
assert.Len(t, wkrDB.PrivateKey, 32)
}

func Test_postTakeWorkflowJobHandlerDefautlRegion(t *testing.T) {
api, _, router, end := newTestAPI(t)
defer end()
ctx := testRunWorkflow(t, api, router)
testGetWorkflowJobAsWorker(t, api, router, &ctx)
require.NotNil(t, ctx.job)

//Prepare request
vars := map[string]string{
"key": ctx.project.Key,
"permWorkflowName": ctx.workflow.Name,
"id": fmt.Sprintf("%d", ctx.job.ID),
}

//Register the worker
testRegisterWorker(t, api, router, &ctx)

// Add cdn config
api.Config.CDN = cdn.Configuration{
TCP: sdk.TCPServer{
Port: 8090,
Addr: "localhost",
},
}

uri := router.GetRoute("POST", api.postTakeWorkflowJobHandler, vars)
require.NotEmpty(t, uri)

workflow.SetDefaultRegion("my-region")

//This call must work
req := assets.NewJWTAuthentifiedRequest(t, ctx.workerToken, "POST", uri, nil)
rec := httptest.NewRecorder()
router.Mux.ServeHTTP(rec, req)
require.Equal(t, 200, rec.Code)

pbji := &sdk.WorkflowNodeJobRunData{}
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), pbji))

run, err := workflow.LoadNodeJobRun(context.TODO(), api.mustDB(), api.Cache, ctx.job.ID)
require.NoError(t, err)
assert.Equal(t, "Building", run.Status)
assert.Equal(t, ctx.model.Name, run.Model)
assert.Equal(t, ctx.worker.Name, run.WorkerName)
assert.NotEmpty(t, run.HatcheryName)

var found bool
for _, v := range run.Job.Action.Requirements {
if v.Type == sdk.RegionRequirement {
require.Equal(t, "my-region", v.Value)
found = true
}
}
require.Equal(t, true, found)

}

func Test_postTakeWorkflowInvalidJobHandler(t *testing.T) {
api, _, router, end := newTestAPI(t)
defer end()
Expand Down

0 comments on commit 132c980

Please sign in to comment.