예제 #1
0
func (sc *ServiceConfig) Status() ([]ServiceStatus, error) {
	command, err := sc.GetCommand()
	if err != nil {
		return nil, errors.WithStack(err)
	}

	status := ServiceStatus{
		Service: sc,
		Status:  "STOPPED",
	}

	if command.Pid != 0 {
		status.Status = "RUNNING"
		status.Pid = command.Pid
		proc, err := process.NewProcess(int32(command.Pid))
		if err != nil {
			return nil, errors.WithStack(err)
		}
		epochStart, err := proc.CreateTime()
		if err != nil {
			return nil, errors.WithStack(err)
		}
		status.StartTime = time.Unix(epochStart/1000, 0)
		status.Ports, err = sc.getPorts(proc)
		if err != nil {
			return nil, errors.WithStack(err)
		}
	}

	return []ServiceStatus{
		status,
	}, nil
}
예제 #2
0
파일: command.go 프로젝트: yext/edward
func (sc *ServiceCommand) waitForAnyPort(cancel <-chan struct{}, command *exec.Cmd) error {
	for true {
		time.Sleep(100 * time.Millisecond)

		select {
		case <-cancel:
			return nil
		default:
		}

		connections, err := net.Connections("all")
		if err != nil {
			return errors.WithStack(err)
		}

		proc, err := process.NewProcess(int32(command.Process.Pid))
		if err != nil {
			return errors.WithStack(err)
		}
		if hasPort(proc, connections) {
			return nil
		}
	}
	return errors.New("exited check loop unexpectedly")
}
예제 #3
0
파일: docker.go 프로젝트: tsuru/tsuru
func joinSwarm(existingClient *docker.Client, newClient *docker.Client, addr string) error {
	swarmInfo, err := existingClient.InspectSwarm(nil)
	if err != nil {
		return errors.WithStack(err)
	}
	dockerInfo, err := existingClient.Info()
	if err != nil {
		return errors.WithStack(err)
	}
	if len(dockerInfo.Swarm.RemoteManagers) == 0 {
		return errors.Errorf("no remote managers found in node %#v", dockerInfo)
	}
	addrs := make([]string, len(dockerInfo.Swarm.RemoteManagers))
	for i, peer := range dockerInfo.Swarm.RemoteManagers {
		addrs[i] = peer.Addr
	}
	host := tsuruNet.URLToHost(addr)
	opts := docker.JoinSwarmOptions{
		JoinRequest: swarm.JoinRequest{
			ListenAddr:    fmt.Sprintf("0.0.0.0:%d", swarmConfig.swarmPort),
			AdvertiseAddr: host,
			JoinToken:     swarmInfo.JoinTokens.Worker,
			RemoteAddrs:   addrs,
		},
	}
	err = newClient.JoinSwarm(opts)
	if err != nil && err != docker.ErrNodeAlreadyInSwarm {
		return errors.WithStack(err)
	}
	return redistributeManagers(existingClient)
}
예제 #4
0
// SearchFullText Search returns work items for the given query
func (r *GormSearchRepository) SearchFullText(ctx context.Context, rawSearchString string, start *int, limit *int) ([]*app.WorkItem, uint64, error) {
	// parse
	// generateSearchQuery
	// ....
	parsedSearchDict, err := parseSearchString(rawSearchString)
	if err != nil {
		return nil, 0, errs.WithStack(err)
	}

	sqlSearchQueryParameter := generateSQLSearchInfo(parsedSearchDict)
	var rows []workitem.WorkItem
	rows, count, err := r.search(ctx, sqlSearchQueryParameter, parsedSearchDict.workItemTypes, start, limit)
	if err != nil {
		return nil, 0, errs.WithStack(err)
	}
	result := make([]*app.WorkItem, len(rows))

	for index, value := range rows {
		var err error
		// FIXME: Against best practice http://go-database-sql.org/retrieving.html
		wiType, err := r.wir.LoadTypeFromDB(ctx, value.Type)
		if err != nil {
			return nil, 0, errors.NewInternalError(err.Error())
		}
		result[index], err = convertFromModel(*wiType, value)
		if err != nil {
			return nil, 0, errors.NewConversionError(err.Error())
		}
	}

	return result, count, nil
}
예제 #5
0
파일: db.go 프로젝트: tsuru/tsuru
func updateDBSwarmNodes(client *docker.Client) error {
	nodes, err := listValidNodes(client)
	if err != nil {
		return errors.WithStack(err)
	}
	var addrs []string
	for _, n := range nodes {
		if n.ManagerStatus == nil {
			continue
		}
		addr := n.Spec.Annotations.Labels[labelNodeDockerAddr.String()]
		if addr == "" {
			continue
		}
		addrs = append(addrs, addr)
	}
	coll, err := nodeAddrCollection()
	if err != nil {
		return err
	}
	defer coll.Close()
	_, err = coll.UpsertId(uniqueDocumentID, bson.M{"$set": bson.M{"addresses": addrs}})
	if err != nil {
		return errors.WithStack(err)
	}
	return nil
}
예제 #6
0
파일: provisioner.go 프로젝트: tsuru/tsuru
func (p *swarmProvisioner) Destroy(a provision.App) error {
	client, err := chooseDBSwarmNode()
	if err != nil {
		return err
	}
	multiErrors := tsuruErrors.NewMultiError()
	processes, err := allAppProcesses(a.GetName())
	if err != nil {
		multiErrors.Add(err)
	}
	for _, p := range processes {
		name := serviceNameForApp(a, p)
		err = client.RemoveService(docker.RemoveServiceOptions{
			ID: name,
		})
		if err != nil {
			if _, notFound := err.(*docker.NoSuchService); !notFound {
				multiErrors.Add(errors.WithStack(err))
			}
		}
	}
	err = client.RemoveNetwork(networkNameForApp(a))
	if err != nil {
		multiErrors.Add(errors.WithStack(err))
	}
	if multiErrors.Len() > 0 {
		return multiErrors
	}
	return nil
}
예제 #7
0
func (mgm tokenManager) Extract(tokenString string) (*account.Identity, error) {
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		return mgm.publicKey, nil
	})
	if err != nil {
		return nil, errors.WithStack(err)
	}

	if !token.Valid {
		return nil, errors.New("Token not valid")
	}

	claimedUUID := token.Claims.(jwt.MapClaims)["sub"]
	if claimedUUID == nil {
		return nil, errors.New("Subject can not be nil")
	}
	// in case of nil UUID, below type casting will fail hence we need above check
	id, err := uuid.FromString(token.Claims.(jwt.MapClaims)["sub"].(string))
	if err != nil {
		return nil, errors.WithStack(err)
	}

	ident := account.Identity{
		ID:       id,
		Username: token.Claims.(jwt.MapClaims)["preferred_username"].(string),
	}

	return &ident, nil
}
예제 #8
0
func encodeToken(referal *url.URL, outhToken *oauth2.Token) error {
	str := outhToken.Extra("expires_in")
	expiresIn, err := strconv.Atoi(fmt.Sprintf("%v", str))
	if err != nil {
		return errs.WithStack(errors.New("cant convert expires_in to integer " + err.Error()))
	}
	str = outhToken.Extra("refresh_expires_in")
	refreshExpiresIn, err := strconv.Atoi(fmt.Sprintf("%v", str))
	if err != nil {
		return errs.WithStack(errors.New("cant convert refresh_expires_in to integer " + err.Error()))
	}
	tokenData := &app.TokenData{
		AccessToken:      &outhToken.AccessToken,
		RefreshToken:     &outhToken.RefreshToken,
		TokenType:        &outhToken.TokenType,
		ExpiresIn:        &expiresIn,
		RefreshExpiresIn: &refreshExpiresIn,
	}
	b, err := json.Marshal(tokenData)
	if err != nil {
		return errs.WithStack(errors.New("cant marshal token data struct " + err.Error()))
	}

	parameters := url.Values{}
	parameters.Add("token", outhToken.AccessToken) // Temporary keep the old "token" param. We will drop this param as soon as UI adopt the new json param.
	parameters.Add("token_json", string(b))
	referal.RawQuery = parameters.Encode()

	return nil
}
예제 #9
0
파일: runner.go 프로젝트: yext/edward
func run(c *cli.Context) error {
	args := c.Args()
	if len(args) < 3 {
		return errors.New("a directory, log file and command is required")
	}
	workingDir := os.ExpandEnv(args[0])
	logFile := os.ExpandEnv(args[1])
	fullCommand := os.ExpandEnv(args[2])

	command, cmdArgs, err := parseCommand(fullCommand)
	if err != nil {
		return errors.WithStack(err)
	}

	log, err := os.Create(logFile)
	if err != nil {
		return errors.WithStack(err)
	}

	cmd := exec.Command(command, cmdArgs...)
	fmt.Println(cmd.Path)
	cmd.Dir = workingDir
	cmd.Stdout = log
	cmd.Stderr = log
	return cmd.Run()
}
예제 #10
0
// Transactional executes the given function in a transaction. If todo returns an error, the transaction is rolled back
func Transactional(db DB, todo func(f Application) error) error {
	var tx Transaction
	var err error
	if tx, err = db.BeginTransaction(); err != nil {
		log.Error(nil, map[string]interface{}{
			"err": err,
		}, "database BeginTransaction failed!")

		return errors.WithStack(err)
	}

	if err := todo(tx); err != nil {
		log.Debug(nil, map[string]interface{}{
			"pkg": "application",
		}, "Rolling back the transaction...")

		tx.Rollback()

		log.Error(nil, map[string]interface{}{
			"err": err,
		}, "database transaction failed!")
		return errors.WithStack(err)
	}

	log.Debug(nil, map[string]interface{}{
		"pkg": "application",
	}, "Commit the transaction!")

	return tx.Commit()
}
예제 #11
0
파일: provisioner.go 프로젝트: tsuru/tsuru
func (p *swarmProvisioner) ArchiveDeploy(a provision.App, archiveURL string, evt *event.Event) (imgID string, err error) {
	baseImage := image.GetBuildImage(a)
	buildingImage, err := image.AppNewImageName(a.GetName())
	if err != nil {
		return "", errors.WithStack(err)
	}
	client, err := chooseDBSwarmNode()
	if err != nil {
		return "", err
	}
	cmds := dockercommon.ArchiveDeployCmds(a, archiveURL)
	srvID, task, err := runOnceBuildCmds(client, a, cmds, baseImage, buildingImage, evt)
	if srvID != "" {
		defer removeServiceAndLog(client, srvID)
	}
	if err != nil {
		return "", err
	}
	_, err = commitPushBuildImage(client, buildingImage, task.Status.ContainerStatus.ContainerID, a)
	if err != nil {
		return "", err
	}
	err = deployProcesses(client, a, buildingImage, nil)
	if err != nil {
		return "", errors.WithStack(err)
	}
	return buildingImage, nil
}
예제 #12
0
// ValidateCorrectSourceAndTargetType returns an error if the Path of
// the source WIT as defined by the work item link type is not part of
// the actual source's WIT; the same applies for the target.
func (r *GormWorkItemLinkRepository) ValidateCorrectSourceAndTargetType(ctx context.Context, sourceID, targetID uint64, linkTypeID satoriuuid.UUID) error {
	linkType, err := r.workItemLinkTypeRepo.LoadTypeFromDBByID(ctx, linkTypeID)
	if err != nil {
		return errs.WithStack(err)
	}
	// Fetch the source work item
	source, err := r.workItemRepo.LoadFromDB(ctx, strconv.FormatUint(sourceID, 10))
	if err != nil {
		return errs.WithStack(err)
	}
	// Fetch the target work item
	target, err := r.workItemRepo.LoadFromDB(ctx, strconv.FormatUint(targetID, 10))
	if err != nil {
		return errs.WithStack(err)
	}
	// Fetch the concrete work item types of the target and the source.
	sourceWorkItemType, err := r.workItemTypeRepo.LoadTypeFromDB(ctx, source.Type)
	if err != nil {
		return errs.WithStack(err)
	}
	targetWorkItemType, err := r.workItemTypeRepo.LoadTypeFromDB(ctx, target.Type)
	if err != nil {
		return errs.WithStack(err)
	}
	// Check type paths
	if !sourceWorkItemType.IsTypeOrSubtypeOf(linkType.SourceTypeName) {
		return errors.NewBadParameterError("source work item type", source.Type)
	}
	if !targetWorkItemType.IsTypeOrSubtypeOf(linkType.TargetTypeName) {
		return errors.NewBadParameterError("target work item type", target.Type)
	}
	return nil
}
예제 #13
0
파일: config.go 프로젝트: yext/edward
func LoadConfigWithDir(reader io.Reader, workingDir string, edwardVersion string, logger common.Logger) (Config, error) {
	config, err := loadConfigContents(reader, workingDir, logger)
	if err != nil {
		return Config{}, errors.WithStack(err)
	}
	if config.MinEdwardVersion != "" && edwardVersion != "" {
		// Check that this config is supported by this version
		minVersion, err1 := version.NewVersion(config.MinEdwardVersion)
		if err1 != nil {
			return Config{}, errors.WithStack(err)
		}
		currentVersion, err2 := version.NewVersion(edwardVersion)
		if err2 != nil {
			return Config{}, errors.WithStack(err)
		}
		if currentVersion.LessThan(minVersion) {
			return Config{}, errors.New("this config requires at least version " + config.MinEdwardVersion)
		}
	}
	err = config.initMaps()

	config.printf("Config loaded with: %d groups and %d services\n", len(config.GroupMap), len(config.ServiceMap))

	return config, errors.WithStack(err)
}
예제 #14
0
파일: config.go 프로젝트: yext/edward
func (c *Config) loadImports() error {
	c.printf("Loading imports\n")
	for _, i := range c.Imports {
		var cPath string
		if filepath.IsAbs(i) {
			cPath = i
		} else {
			cPath = filepath.Join(c.workingDir, i)
		}

		c.printf("Loading: %v\n", cPath)

		r, err := os.Open(cPath)
		if err != nil {
			return errors.WithStack(err)
		}
		cfg, err := loadConfigContents(r, filepath.Dir(cPath), c.Logger)
		if err != nil {
			return errors.WithStack(err)
		}

		err = c.importConfig(cfg)
		if err != nil {
			return errors.WithStack(err)
		}
	}
	return nil
}
예제 #15
0
파일: provisioner.go 프로젝트: tsuru/tsuru
func (p *swarmProvisioner) Shell(opts provision.ShellOptions) error {
	client, err := chooseDBSwarmNode()
	if err != nil {
		return err
	}
	tasks, err := runningTasksForApp(client, opts.App, opts.Unit)
	if err != nil {
		return err
	}
	if len(tasks) == 0 {
		if opts.Unit != "" {
			return &provision.UnitNotFoundError{ID: opts.Unit}
		}
		return provision.ErrEmptyApp
	}
	nodeClient, err := clientForNode(client, tasks[0].NodeID)
	if err != nil {
		return err
	}
	cmds := []string{"/usr/bin/env", "TERM=" + opts.Term, "bash", "-l"}
	execCreateOpts := docker.CreateExecOptions{
		AttachStdin:  true,
		AttachStdout: true,
		AttachStderr: true,
		Cmd:          cmds,
		Container:    tasks[0].Status.ContainerStatus.ContainerID,
		Tty:          true,
	}
	exec, err := nodeClient.CreateExec(execCreateOpts)
	if err != nil {
		return errors.WithStack(err)
	}
	startExecOptions := docker.StartExecOptions{
		InputStream:  opts.Conn,
		OutputStream: opts.Conn,
		ErrorStream:  opts.Conn,
		Tty:          true,
		RawTerminal:  true,
	}
	errs := make(chan error, 1)
	go func() {
		errs <- nodeClient.StartExec(exec.ID, startExecOptions)
	}()
	execInfo, err := nodeClient.InspectExec(exec.ID)
	for !execInfo.Running && err == nil {
		select {
		case startErr := <-errs:
			return startErr
		default:
			execInfo, err = nodeClient.InspectExec(exec.ID)
		}
	}
	if err != nil {
		return errors.WithStack(err)
	}
	nodeClient.ResizeExecTTY(exec.ID, opts.Height, opts.Width)
	return <-errs
}
예제 #16
0
파일: config.go 프로젝트: yext/edward
func (c Config) Save(writer io.Writer) error {
	c.printf("Saving config")
	content, err := json.MarshalIndent(c, "", "    ")
	if err != nil {
		return errors.WithStack(err)
	}
	_, err = writer.Write(content)
	return errors.WithStack(err)
}
예제 #17
0
// executeSQLFile loads the given filename from the packaged SQL files and
// executes it on the given database
func executeSQLFile(filename string) fn {
	return func(db *sql.Tx) error {
		data, err := Asset(filename)
		if err != nil {
			return errs.WithStack(err)
		}
		_, err = db.Exec(string(data))
		return errs.WithStack(err)
	}
}
func TestConvertExistingWorkItem(t *testing.T) {
	resource.Require(t, resource.Database)

	// Setting up the dependent tracker query and tracker data in the Database
	tr := Tracker{URL: "https://api.github.com/", Type: ProviderGithub}

	db = db.Create(&tr)
	require.Nil(t, db.Error)

	tq := TrackerQuery{Query: "some random query", Schedule: "0 0 0 * * *", TrackerID: tr.ID}
	db = db.Create(&tq)
	require.Nil(t, db.Error)
	defer cleaner.DeleteCreatedEntities(db)()

	t.Log("Created Tracker Query and Tracker")

	models.Transactional(db, func(tx *gorm.DB) error {
		t.Log("Adding a work item which wasn't present.")

		remoteItemData := TrackerItemContent{
			Content: []byte(`{"title":"linking","url":"http://github.com/sbose/api/testonly/1","state":"closed","body":"body of issue","user.login":"******","assignee.login":"******"}`),
			ID:      "http://github.com/sbose/api/testonly/1",
		}

		workItem, err := convert(tx, int(tq.ID), remoteItemData, ProviderGithub)

		assert.Nil(t, err)
		assert.Equal(t, "linking", workItem.Fields[workitem.SystemTitle])
		assert.Equal(t, "sbose78", workItem.Fields[workitem.SystemCreator])
		assert.Equal(t, "pranav", workItem.Fields[workitem.SystemAssignees].([]interface{})[0])
		assert.Equal(t, "closed", workItem.Fields[workitem.SystemState])
		return errors.WithStack(err)
	})

	t.Log("Updating the existing work item when it's reimported.")

	models.Transactional(db, func(tx *gorm.DB) error {
		remoteItemDataUpdated := TrackerItemContent{
			Content: []byte(`{"title":"linking-updated","url":"http://github.com/api/testonly/1","state":"closed","body":"body of issue","user.login":"******","assignee.login":"******"}`),
			ID:      "http://github.com/sbose/api/testonly/1",
		}
		workItemUpdated, err := convert(tx, int(tq.ID), remoteItemDataUpdated, ProviderGithub)

		assert.Nil(t, err)
		assert.Equal(t, "linking-updated", workItemUpdated.Fields[workitem.SystemTitle])
		assert.Equal(t, "sbose78", workItemUpdated.Fields[workitem.SystemCreator])
		assert.Equal(t, "pranav", workItemUpdated.Fields[workitem.SystemAssignees].([]interface{})[0])
		assert.Equal(t, "closed", workItemUpdated.Fields[workitem.SystemState])

		wir := workitem.NewWorkItemRepository(tx)
		wir.Delete(context.Background(), workItemUpdated.ID)

		return errors.WithStack(err)
	})
}
예제 #19
0
func (sc *ServiceConfig) Launch(cfg OperationConfig) error {
	if cfg.IsExcluded(sc) {
		return nil
	}

	command, err := sc.GetCommand()
	if err != nil {
		return errors.WithStack(err)
	}
	return errors.WithStack(command.StartAsync(cfg))
}
예제 #20
0
func (sc *ServiceConfig) Build(cfg OperationConfig) error {
	if cfg.IsExcluded(sc) {
		return nil
	}

	command, err := sc.GetCommand()
	if err != nil {
		return errors.WithStack(err)
	}
	return errors.WithStack(command.BuildSync(false))
}
예제 #21
0
파일: provisioner.go 프로젝트: tsuru/tsuru
func (p *swarmProvisioner) AddNode(opts provision.AddNodeOptions) error {
	init := false
	existingClient, err := chooseDBSwarmNode()
	if err != nil && errors.Cause(err) != errNoSwarmNode {
		return err
	}
	err = addNodeCredentials(opts)
	if err != nil {
		return err
	}
	newClient, err := newClient(opts.Address)
	if err != nil {
		return err
	}
	if existingClient == nil {
		err = initSwarm(newClient, opts.Address)
		existingClient = newClient
		init = true
	} else {
		err = joinSwarm(existingClient, newClient, opts.Address)
	}
	if err != nil {
		return err
	}
	dockerInfo, err := newClient.Info()
	if err != nil {
		return errors.WithStack(err)
	}
	nodeData, err := existingClient.InspectNode(dockerInfo.Swarm.NodeID)
	if err != nil {
		return errors.WithStack(err)
	}
	nodeData.Spec.Annotations.Labels = map[string]string{
		labelNodeDockerAddr.String(): opts.Address,
	}
	for k, v := range opts.Metadata {
		nodeData.Spec.Annotations.Labels[k] = v
	}
	err = existingClient.UpdateNode(dockerInfo.Swarm.NodeID, docker.UpdateNodeOptions{
		Version:  nodeData.Version.Index,
		NodeSpec: nodeData.Spec,
	})
	if err != nil {
		return errors.WithStack(err)
	}
	err = updateDBSwarmNodes(existingClient)
	if err != nil {
		return err
	}
	if init {
		return p.ensureNodeContainersCreated()
	}
	return nil
}
예제 #22
0
// Load returns a single Identity as a Database Model
// This is more for use internally, and probably not what you want in  your controllers
func (m *GormIdentityRepository) Load(ctx context.Context, id uuid.UUID) (*Identity, error) {
	defer goa.MeasureSince([]string{"goa", "db", "identity", "load"}, time.Now())

	var native Identity
	err := m.db.Table(m.TableName()).Where("id = ?", id).Find(&native).Error
	if err == gorm.ErrRecordNotFound {
		return nil, errors.WithStack(err)
	}

	return &native, errors.WithStack(err)
}
예제 #23
0
func (sc *ServiceConfig) Start(cfg OperationConfig) error {
	if cfg.IsExcluded(sc) {
		return nil
	}

	err := sc.Build(cfg)
	if err != nil {
		return errors.WithStack(err)
	}
	err = sc.Launch(cfg)
	return errors.WithStack(err)
}
예제 #24
0
파일: generator.go 프로젝트: yext/edward
func loadIgnores(path string, currentIgnores *ignore.GitIgnore) (*ignore.GitIgnore, error) {
	ignoreFile := filepath.Join(path, ".edwardignore")
	if _, err := os.Stat(ignoreFile); err != nil {
		if os.IsNotExist(err) {
			return currentIgnores, nil
		}
		return currentIgnores, errors.WithStack(err)
	}

	ignores, err := ignore.CompileIgnoreFile(ignoreFile)
	return ignores, errors.WithStack(err)
}
예제 #25
0
// enrichLinkSingle includes related resources in the link's "included" array
func enrichLinkSingle(ctx *workItemLinkContext, link *app.WorkItemLinkSingle) error {

	// include link type
	linkType, err := ctx.Application.WorkItemLinkTypes().Load(ctx.Context, link.Data.Relationships.LinkType.Data.ID)
	if err != nil {
		return errs.WithStack(err)
	}
	link.Included = append(link.Included, linkType.Data)

	// include link category
	linkCat, err := ctx.Application.WorkItemLinkCategories().Load(ctx.Context, linkType.Data.Relationships.LinkCategory.Data.ID)
	if err != nil {
		return errs.WithStack(err)
	}
	link.Included = append(link.Included, linkCat.Data)

	// TODO(kwk): include source work item type (once #559 is merged)
	// sourceWit, err := appl.WorkItemTypes().Load(ctx, linkType.Data.Relationships.SourceType.Data.ID)
	// if err != nil {
	// 	return errs.WithStack(err)
	// }
	// link.Included = append(link.Included, sourceWit.Data)

	// TODO(kwk): include target work item type (once #559 is merged)
	// targetWit, err := appl.WorkItemTypes().Load(ctx, linkType.Data.Relationships.TargetType.Data.ID)
	// if err != nil {
	// 	return errs.WithStack(err)
	// }
	// link.Included = append(link.Included, targetWit.Data)

	// TODO(kwk): include source work item
	sourceWi, err := ctx.Application.WorkItems().Load(ctx.Context, link.Data.Relationships.Source.Data.ID)
	if err != nil {
		return errs.WithStack(err)
	}
	link.Included = append(link.Included, ConvertWorkItem(ctx.RequestData, sourceWi))

	// TODO(kwk): include target work item
	targetWi, err := ctx.Application.WorkItems().Load(ctx.Context, link.Data.Relationships.Target.Data.ID)
	if err != nil {
		return errs.WithStack(err)
	}
	link.Included = append(link.Included, ConvertWorkItem(ctx.RequestData, targetWi))

	// Add links to individual link data element
	selfURL := rest.AbsoluteURL(ctx.RequestData, ctx.LinkFunc(*link.Data.ID))
	link.Data.Links = &app.GenericLinks{
		Self: &selfURL,
	}

	return nil
}
예제 #26
0
파일: command.go 프로젝트: yext/edward
func (sc *ServiceCommand) waitUntilLive(command *exec.Cmd) error {

	sc.printf("Waiting for %v to start.\n", sc.Service.Name)

	var startCheck func(cancel <-chan struct{}) error
	if sc.Service.LaunchChecks != nil && len(sc.Service.LaunchChecks.LogText) > 0 {
		startCheck = func(cancel <-chan struct{}) error {
			return errors.WithStack(
				sc.waitForLogText(sc.Service.LaunchChecks.LogText, cancel),
			)
		}
	} else if sc.Service.LaunchChecks != nil && len(sc.Service.LaunchChecks.Ports) > 0 {
		startCheck = func(cancel <-chan struct{}) error {
			return errors.WithStack(
				sc.waitForListeningPorts(sc.Service.LaunchChecks.Ports, cancel, command),
			)
		}
	} else {
		startCheck = func(cancel <-chan struct{}) error {
			return errors.WithStack(
				sc.waitForAnyPort(cancel, command),
			)
		}
	}

	processFinished := func(cancel <-chan struct{}) error {
		// Wait until the process exists
		command.Wait()
		select {
		case <-cancel:
			return nil
		default:
		}
		return errors.New("service terminated prematurely")
	}

	timeout := time.NewTimer(30 * time.Second)
	defer timeout.Stop()

	done := make(chan struct{})
	defer close(done)

	select {
	case result := <-cancelableWait(done, startCheck):
		return errors.WithStack(result.error)
	case result := <-cancelableWait(done, processFinished):
		return errors.WithStack(result.error)
	case <-timeout.C:
		return errors.New("Waiting for service timed out")
	}

}
예제 #27
0
func provideRemoteData(dataURL string) ([]byte, error) {
	response, err := http.Get(dataURL)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	defer response.Body.Close()
	responseData, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	return responseData, nil
}
예제 #28
0
파일: watch.go 프로젝트: yext/edward
func startWatch(watches *services.ServiceWatch, cfg services.OperationConfig) (*fsnotify.Watcher, error) {
	fmt.Printf("Watching %v paths for service %v\n", len(watches.IncludedPaths), watches.Service.GetName())
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return nil, errors.WithStack(err)
	}

	go func() {
		for {
			select {
			case event := <-watcher.Events:
				if event.Op&fsnotify.Write == fsnotify.Write {
					fmt.Printf("File edited: %v\n", event.Name)

					var wasExcluded bool
					for _, excluded := range watches.ExcludedPaths {
						if strings.HasPrefix(event.Name, excluded) {
							fmt.Println("File is under excluded path:", excluded)
							wasExcluded = true
							break
						}
					}

					if wasExcluded {
						continue
					}
					fmt.Printf("Rebuilding %v\n", watches.Service.GetName())
					err = rebuildService(watches.Service, cfg)
					if err != nil {
						fmt.Printf("Could not rebuild %v: %v\n", watches.Service.GetName(), err)
					}
				}

			case err := <-watcher.Errors:
				if err != nil {
					log.Println("error:", err)
				}
			}
		}
	}()

	for _, dir := range watches.IncludedPaths {
		err = watcher.Add(dir)
		if err != nil {
			watcher.Close()
			return nil, errors.WithStack(err)
		}
	}
	return watcher, nil
}
예제 #29
0
// enrichLinkList includes related resources in the linkArr's "included" element
func enrichLinkList(ctx *workItemLinkContext, linkArr *app.WorkItemLinkList) error {

	// include link types
	typeDataArr, err := getTypesOfLinks(ctx, linkArr.Data)
	if err != nil {
		return errs.WithStack(err)
	}
	// Convert slice of objects to slice of interface (see https://golang.org/doc/faq#convert_slice_of_interface)
	interfaceArr := make([]interface{}, len(typeDataArr))
	for i, v := range typeDataArr {
		interfaceArr[i] = v
	}
	linkArr.Included = append(linkArr.Included, interfaceArr...)

	// include link categories
	catDataArr, err := getCategoriesOfLinkTypes(ctx, typeDataArr)
	if err != nil {
		return errs.WithStack(err)
	}
	// Convert slice of objects to slice of interface (see https://golang.org/doc/faq#convert_slice_of_interface)
	interfaceArr = make([]interface{}, len(catDataArr))
	for i, v := range catDataArr {
		interfaceArr[i] = v
	}
	linkArr.Included = append(linkArr.Included, interfaceArr...)

	// TODO(kwk): Include WIs from source and target
	workItemDataArr, err := getWorkItemsOfLinks(ctx, linkArr.Data)
	if err != nil {
		return errs.WithStack(err)
	}
	// Convert slice of objects to slice of interface (see https://golang.org/doc/faq#convert_slice_of_interface)
	interfaceArr = make([]interface{}, len(workItemDataArr))
	for i, v := range workItemDataArr {
		interfaceArr[i] = v
	}
	linkArr.Included = append(linkArr.Included, interfaceArr...)

	// TODO(kwk): Include WITs (once #559 is merged)

	// Add links to individual link data element
	for _, link := range linkArr.Data {
		selfURL := rest.AbsoluteURL(ctx.RequestData, ctx.LinkFunc(*link.ID))
		link.Links = &app.GenericLinks{
			Self: &selfURL,
		}
	}

	return nil
}
예제 #30
0
// PopulateCommonTypes makes sure the database is populated with the correct types (e.g. bug etc.)
func PopulateCommonTypes(ctx context.Context, db *gorm.DB, witr *workitem.GormWorkItemTypeRepository) error {

	if err := createOrUpdateSystemPlannerItemType(ctx, witr, db); err != nil {
		return errs.WithStack(err)
	}
	workitem.ClearGlobalWorkItemTypeCache() // Clear the WIT cache after updating existing WITs
	if err := createOrUpdatePlannerItemExtension(workitem.SystemUserStory, ctx, witr, db); err != nil {
		return errs.WithStack(err)
	}
	if err := createOrUpdatePlannerItemExtension(workitem.SystemValueProposition, ctx, witr, db); err != nil {
		return errs.WithStack(err)
	}
	if err := createOrUpdatePlannerItemExtension(workitem.SystemFundamental, ctx, witr, db); err != nil {
		return errs.WithStack(err)
	}
	if err := createOrUpdatePlannerItemExtension(workitem.SystemExperience, ctx, witr, db); err != nil {
		return errs.WithStack(err)
	}
	if err := createOrUpdatePlannerItemExtension(workitem.SystemScenario, ctx, witr, db); err != nil {
		return errs.WithStack(err)
	}
	if err := createOrUpdatePlannerItemExtension(workitem.SystemFeature, ctx, witr, db); err != nil {
		return errs.WithStack(err)
	}
	if err := createOrUpdatePlannerItemExtension(workitem.SystemBug, ctx, witr, db); err != nil {
		return errs.WithStack(err)
	}
	workitem.ClearGlobalWorkItemTypeCache() // Clear the WIT cache after updating existing WITs
	return nil
}