예제 #1
0
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.ID == "" {
		a.App = &ct.App{ID: utils.UUID()}
	}
	if a.Artifact == nil {
		return errors.New("bootstrap: artifact must be set")
	}
	if a.Artifact.ID == "" {
		a.Artifact.ID = utils.UUID()
	}
	if a.Release == nil {
		return errors.New("bootstrap: release must be set")
	}
	if a.Release.ID == "" {
		a.Release.ID = utils.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 {
		server, err := resource.NewServer(p.URL)
		if err != nil {
			return err
		}
		res, err := server.Provision(nil)
		server.Close()
		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
	}
	hosts, err := cc.ListHosts()
	if err != nil {
		return err
	}
	hostIDs := make([]string, 0, len(hosts))
	for id := range hosts {
		hostIDs = append(hostIDs, id)
	}
	for typ, count := range a.Processes {
		for i := 0; i < count; i++ {
			config, err := utils.JobConfig(a.ExpandedFormation, typ)
			if err != nil {
				return err
			}
			job, err := startJob(s, hostIDs[i%len(hosts)], config)
			if err != nil {
				return err
			}
			as.Jobs = append(as.Jobs, *job)
		}
	}

	return nil
}
예제 #2
0
func (a *AddAppAction) Run(s *State) error {
	data, ok := s.StepData[a.FromStep].(*RunAppState)
	if !ok {
		return fmt.Errorf("bootstrap: unable to find step %q", a.FromStep)
	}
	as := &AppState{
		ExpandedFormation: &ct.ExpandedFormation{},
		Resources:         make([]*ct.Resource, 0, len(data.Resources)),
	}
	s.StepData[a.ID] = as

	client, err := s.ControllerClient()
	if err != nil {
		return err
	}

	a.App.ID = data.App.ID
	if err := client.CreateApp(a.App); err != nil {
		return err
	}
	as.App = a.App
	if err := client.CreateArtifact(data.Artifact); err != nil {
		return err
	}
	as.Artifact = data.Artifact
	if err := client.CreateRelease(data.Release); err != nil {
		return err
	}
	as.Release = data.Release

	for i, p := range data.Providers {
		if provider, ok := s.Providers[p.Name]; ok {
			p = provider
		} else {
			if err := client.CreateProvider(p); err != nil {
				return err
			}
			s.Providers[p.Name] = p
		}

		resource := &ct.Resource{
			ID:         utils.UUID(),
			ProviderID: p.ID,
			ExternalID: data.Resources[i].ID,
			Env:        data.Resources[i].Env,
		}
		if err := client.PutResource(resource); err != nil {
			return err
		}
		as.Resources = append(as.Resources, resource)
	}

	formation := &ct.Formation{
		AppID:     data.App.ID,
		ReleaseID: data.Release.ID,
		Processes: data.Processes,
	}
	if err := client.PutFormation(formation); err != nil {
		return err
	}
	as.Formation = formation
	if err := client.SetAppRelease(data.App.ID, data.Release.ID); err != nil {
		return err
	}

	return nil
}