func (c *controllerAPI) ProvisionResource(ctx context.Context, w http.ResponseWriter, req *http.Request) { p, err := c.getProvider(ctx) if err != nil { respondWithError(w, err) return } var rr ct.ResourceReq if err = httphelper.DecodeJSON(req, &rr); err != nil { respondWithError(w, err) return } var config []byte if rr.Config != nil { config = *rr.Config } else { config = []byte(`{}`) } data, err := resource.Provision(p.URL, config) if err != nil { respondWithError(w, err) return } res := &ct.Resource{ ProviderID: p.ID, ExternalID: data.ID, Env: data.Env, Apps: rr.Apps, } if err := schema.Validate(res); err != nil { respondWithError(w, err) return } if err := c.resourceRepo.Add(res); err != nil { // TODO: attempt to "rollback" provisioning respondWithError(w, err) return } httphelper.JSON(w, 200, res) }
func (a *RunAppAction) Run(s *State) error { if a.AppStep != "" { data, err := getAppStep(s, a.AppStep) if err != nil { return err } a.App = data.App procs := a.Processes a.ExpandedFormation = data.ExpandedFormation a.Processes = procs } as := &RunAppState{ ExpandedFormation: a.ExpandedFormation, Resources: make([]*resource.Resource, 0, len(a.Resources)), Providers: make([]*ct.Provider, 0, len(a.Resources)), } s.StepData[a.ID] = as if a.App == nil { a.App = &ct.App{} } if a.App.ID == "" { a.App.ID = random.UUID() } if a.ImageArtifact == nil { return errors.New("bootstrap: artifact must be set") } if a.ImageArtifact.ID == "" { a.ImageArtifact.ID = random.UUID() } if a.Release == nil { return errors.New("bootstrap: release must be set") } if a.Release.ID == "" { a.Release.ID = random.UUID() } a.Release.ArtifactIDs = []string{a.ImageArtifact.ID} if a.Release.Env == nil { a.Release.Env = make(map[string]string) } interpolateRelease(s, a.Release) for _, p := range a.Resources { u, err := url.Parse(p.URL) if err != nil { return err } lookupDiscoverdURLHost(s, u, time.Second) res, err := resource.Provision(u.String(), nil) if err != nil { return err } as.Providers = append(as.Providers, p) as.Resources = append(as.Resources, res) for k, v := range res.Env { a.Release.Env[k] = v } } for typ, count := range a.Processes { if s.Singleton && count > 1 { a.Processes[typ] = 1 count = 1 } hosts := s.ShuffledHosts() if a.ExpandedFormation.Release.Processes[typ].Omni { count = len(hosts) } for i := 0; i < count; i++ { host := hosts[i%len(hosts)] config := utils.JobConfig(a.ExpandedFormation, typ, host.ID(), "") hostresource.SetDefaults(&config.Resources) if a.ExpandedFormation.Release.Processes[typ].Data { if err := utils.ProvisionVolume(host, config); err != nil { return err } } if err := startJob(s, host, config); err != nil { return err } } } return nil }
func (a *RunAppAction) Run(s *State) error { if a.AppStep != "" { data, err := getAppStep(s, a.AppStep) if err != nil { return err } a.App = data.App procs := a.Processes a.ExpandedFormation = data.ExpandedFormation a.Processes = procs } as := &RunAppState{ ExpandedFormation: a.ExpandedFormation, Resources: make([]*resource.Resource, 0, len(a.Resources)), Providers: make([]*ct.Provider, 0, len(a.Resources)), } s.StepData[a.ID] = as if a.App == nil { a.App = &ct.App{} } if a.App.ID == "" { a.App.ID = random.UUID() } if a.Artifact == nil { return errors.New("bootstrap: artifact must be set") } if a.Artifact.ID == "" { a.Artifact.ID = random.UUID() } if a.Release == nil { return errors.New("bootstrap: release must be set") } if a.Release.ID == "" { a.Release.ID = random.UUID() } a.Release.ArtifactID = a.Artifact.ID if a.Release.Env == nil { a.Release.Env = make(map[string]string) } interpolateRelease(s, a.Release) for _, p := range a.Resources { u, err := url.Parse(p.URL) if err != nil { return err } lookupDiscoverdURLHost(u, time.Second) res, err := resource.Provision(u.String(), nil) if err != nil { return err } as.Providers = append(as.Providers, p) as.Resources = append(as.Resources, res) for k, v := range res.Env { a.Release.Env[k] = v } } cc, err := s.ClusterClient() if err != nil { return err } for typ, count := range a.Processes { if s.Singleton && count > 1 { a.Processes[typ] = 1 count = 1 } hosts, err := cc.ListHosts() if err != nil { return err } sort.Sort(schedutil.HostSlice(hosts)) for i := 0; i < count; i++ { hostID := hosts[i%len(hosts)].ID config := utils.JobConfig(a.ExpandedFormation, typ, hostID) if a.ExpandedFormation.Release.Processes[typ].Data { if err := utils.ProvisionVolume(cc, hostID, config); err != nil { return err } } job, err := startJob(s, hostID, config) if err != nil { return err } as.Jobs = append(as.Jobs, *job) } } return nil }