示例#1
0
文件: app.go 项目: soundcloud/visor
func getApp(name string, s cp.Snapshotable) (*App, error) {
	sp := s.GetSnapshot()
	app := storeFromSnapshotable(s).NewApp(name, "", "")

	f, err := sp.GetSnapshot().GetFile(app.dir.Prefix("attrs"), new(cp.JsonCodec))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = errorf(ErrNotFound, `app "%s" not found`, app.Name)
		}
		return nil, err
	}

	value := f.Value.(map[string]interface{})

	app.RepoURL = value["repo-url"].(string)
	app.Stack = value["stack"].(string)
	app.DeployType = value["deploy-type"].(string)

	f, err = app.dir.GetFile(registeredPath, new(cp.StringCodec))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = errorf(ErrNotFound, "registered not found for %s", app.Name)
		}
		return nil, err
	}
	app.Registered, err = parseTime(f.Value.(string))
	if err != nil {
		return nil, err
	}

	return app, nil
}
示例#2
0
文件: proc.go 项目: soundcloud/visor
func getProc(app *App, name string, s cp.Snapshotable) (*Proc, error) {
	p := &Proc{
		dir:  cp.NewDir(app.dir.Prefix(procsPath, name), s.GetSnapshot()),
		Name: name,
		App:  app,
	}

	port, err := p.dir.GetFile(procsPortPath, new(cp.IntCodec))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			exists, _, err := s.GetSnapshot().Exists(p.dir.Name)
			if err != nil {
				return nil, err
			}
			if !exists {
				return nil, errorf(ErrNotFound, `proc "%s" not found for app %s`, name, app.Name)
			}
			return nil, errorf(ErrNotFound, "port not found for %s:%s", app.Name, name)
		}
		return nil, err
	}
	p.Port = port.Value.(int)

	controlPort, err := p.dir.GetFile(procsControlPortPath, new(cp.IntCodec))
	if err != nil {
		if IsErrNotFound(err) {
			p.ControlPort = 0
		} else {
			return nil, err
		}
	} else {
		p.ControlPort = controlPort.Value.(int)
	}

	_, err = p.dir.GetFile(procsAttrsPath, &cp.JsonCodec{DecodedVal: &p.Attrs})
	if err != nil && !cp.IsErrNoEnt(err) {
		return nil, err
	}

	f, err := p.dir.GetFile(registeredPath, new(cp.StringCodec))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = errorf(ErrNotFound, "registered not found for %s:%s", app.Name, name)
		}
		return nil, err
	}
	p.Registered, err = parseTime(f.Value.(string))
	if err != nil {
		return nil, err
	}

	return p, nil
}
示例#3
0
文件: app.go 项目: soundcloud/visor
// EnvironmentVars returns all set variables for this app as a map.
func (a *App) EnvironmentVars() (vars map[string]string, err error) {
	vars = map[string]string{}

	sp, err := a.GetSnapshot().FastForward()
	if err != nil {
		return vars, err
	}
	names, err := sp.Getdir(a.dir.Prefix("env"))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = nil
		}
		return
	}
	a.dir = a.dir.Join(sp)

	type resp struct {
		key, val string
		err      error
	}
	ch := make(chan resp, len(names))

	if err != nil {
		if cp.IsErrNoEnt(err) {
			return vars, nil
		}
		return
	}

	for _, name := range names {
		go func(name string) {
			v, err := a.GetEnvironmentVar(name)
			if err != nil {
				ch <- resp{err: err}
			} else {
				ch <- resp{key: name, val: v}
			}
		}(name)
	}
	for i := 0; i < len(names); i++ {
		r := <-ch
		if r.err != nil {
			return nil, err
		}
		vars[strings.Replace(r.key, "-", "_", -1)] = r.val
	}
	return
}
示例#4
0
文件: visor.go 项目: soundcloud/visor
// Init sets up expected paths.
func (s *Store) Init() (*Store, error) {
	sp, err := s.GetSnapshot().FastForward()
	if err != nil {
		return nil, err
	}

	exists, _, err := sp.Exists(nextPortPath)
	if err != nil {
		return nil, err
	}

	if !exists {
		sp, err = sp.Set(nextPortPath, strconv.Itoa(startPort))
		if err != nil {
			return nil, err
		}
	}

	v, err := cp.VerifySchema(SchemaVersion, sp)
	if cp.IsErrNoEnt(err) {
		sp, err = cp.SetSchemaVersion(SchemaVersion, sp)
		if err != nil {
			return nil, err
		}
	} else if err != nil {
		if cp.IsErrSchemaMism(err) {
			err = fmt.Errorf("%s (%d != %d)", err, SchemaVersion, v)
		}
		return nil, err
	}

	s.snapshot = sp

	return s, nil
}
示例#5
0
文件: app.go 项目: soundcloud/visor
// GetProcs returns all registered Procs for the App
func (a *App) GetProcs() (procs []*Proc, err error) {
	sp, err := a.GetSnapshot().FastForward()
	if err != nil {
		return
	}
	names, err := sp.Getdir(a.dir.Prefix(procsPath))
	if err != nil || len(names) == 0 {
		if cp.IsErrNoEnt(err) {
			err = nil
		}
		return
	}
	ch, errch := cp.GetSnapshotables(names, func(name string) (cp.Snapshotable, error) {
		return getProc(a, name, sp)
	})
	for i := 0; i < len(names); i++ {
		select {
		case r := <-ch:
			procs = append(procs, r.(*Proc))
		case err := <-errch:
			return nil, err
		}
	}
	return
}
示例#6
0
// Claims returns the list of claimers.
func (i *Instance) Claims() (claims []string, err error) {
	sp, err := i.GetSnapshot().FastForward()
	if err != nil {
		return
	}
	claims, err = sp.Getdir(i.dir.Prefix("claims"))
	if cp.IsErrNoEnt(err) {
		claims = []string{}
		err = nil
	}
	return
}
示例#7
0
文件: app.go 项目: soundcloud/visor
// GetEnvironmentVar returns the value stored for the given key.
func (a *App) GetEnvironmentVar(k string) (value string, err error) {
	k = strings.Replace(k, "_", "-", -1)
	val, _, err := a.dir.Get("env/" + k)
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = errorf(ErrNotFound, `"%s" not found in %s's environment`, k, a.Name)
		}
		return
	}
	value = string(val)

	return
}
示例#8
0
func getRevision(app *App, ref string, s cp.Snapshotable) (*Revision, error) {
	r := &Revision{
		dir: cp.NewDir(app.dir.Prefix(revsPath, ref), s.GetSnapshot()),
		App: app,
		Ref: ref,
	}

	f, err := r.dir.GetFile(archiveURLPath, new(cp.StringCodec))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			exists, _, err := s.GetSnapshot().Exists(r.dir.Name)
			if err != nil {
				return nil, err
			}
			if !exists {
				return nil, errorf(ErrNotFound, `revision "%s" not found for app %s`, ref, app.Name)
			}
			return nil, errorf(ErrNotFound, "archive-url not found for %s:%s", app.Name, ref)
		}
		return nil, err
	}
	r.ArchiveURL = f.Value.(string)

	f, err = r.dir.GetFile(registeredPath, new(cp.StringCodec))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = errorf(ErrNotFound, "registered not found for %s:%s", app.Name, ref)
		}
		return nil, err
	}
	r.Registered, err = parseTime(f.Value.(string))
	if err != nil {
		return nil, err
	}

	return r, nil
}
示例#9
0
func (i *Instance) getRestarts() (InsRestarts, *cp.File, error) {
	var restarts InsRestarts

	f, err := i.dir.GetFile(restartsPath, new(cp.ListIntCodec))
	if err == nil {
		fields := f.Value.([]int)

		restarts.Fail = fields[restartFailField]
		restarts.OOM = fields[restartOOMField]
	} else if !cp.IsErrNoEnt(err) {
		return restarts, nil, err
	}

	return restarts, f, nil
}
示例#10
0
文件: env.go 项目: soundcloud/visor
func getEnv(app *App, ref string, s cp.Snapshotable) (*Env, error) {
	e := &Env{
		dir: cp.NewDir(app.dir.Prefix(envsPath, ref), s.GetSnapshot()),
		App: app,
		Ref: ref,
	}

	_, err := e.dir.GetFile(varsPath, &cp.JsonCodec{DecodedVal: &e.Vars})
	if err != nil {
		if cp.IsErrNoEnt(err) {
			exists, _, err := s.GetSnapshot().Exists(e.dir.Name)
			if err != nil {
				return nil, err
			}
			if !exists {
				return nil, errorf(ErrNotFound, `env "%s" not found for app %s`, ref, app.Name)
			}
			return nil, errorf(ErrNotFound, "vars not found for %s#%s", app.Name, ref)
		}
		return nil, err
	}

	f, err := e.dir.GetFile(registeredPath, new(cp.StringCodec))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = errorf(ErrNotFound, `registered not found for %s`, ref)
		}
		return nil, err
	}
	e.Registered, err = parseTime(f.Value.(string))
	if err != nil {
		return nil, err
	}

	return e, nil
}
示例#11
0
文件: tag.go 项目: soundcloud/visor
func getTag(a *App, name string, s cp.Snapshotable) (*Tag, error) {
	t := &Tag{}
	c := &cp.JsonCodec{DecodedVal: t}

	f, err := s.GetSnapshot().GetFile(a.dir.Prefix(tagsPath, name), c)
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = errorf(ErrNotFound, `tag "%s" not found`, name)
		}
		return nil, err
	}

	t.file = f
	t.App = a

	return t, nil
}
示例#12
0
func getRunner(addr string, s cp.Snapshotable) (*Runner, error) {
	sp := s.GetSnapshot()
	f, err := sp.GetFile(runnerPath(addr), new(cp.ListCodec))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = errorf(ErrNotFound, "runner '%s' not found", addr)
		}
		return nil, err
	}
	data := f.Value.([]string)
	insIDStr := data[0]
	insID, err := parseInstanceID(insIDStr)
	if err != nil {
		return nil, err
	}

	return storeFromSnapshotable(sp).NewRunner(addr, insID), nil
}
示例#13
0
文件: hook.go 项目: soundcloud/visor
func getHook(app *App, name string, s cp.Snapshotable) (*Hook, error) {
	c := new(cp.JsonCodec)
	c.DecodedVal = &Hook{}

	f, err := s.GetSnapshot().GetFile(app.dir.Prefix(hooksPath, name), c)
	if err != nil {
		if cp.IsErrNoEnt(err) {
			err = errorf(ErrNotFound, `hook not found for "%s"`, name)
		}
		return nil, err
	}

	h, ok := f.Value.(*Hook)
	if !ok {
		return nil, errors.New("retrieved file is not a hook")
	}
	h.file = f
	h.App = app

	return h, nil
}
示例#14
0
func getInstance(id int64, s cp.Snapshotable) (*Instance, error) {
	i := &Instance{
		ID:     id,
		Status: InsStatusPending,
		dir:    cp.NewDir(instancePath(id), s.GetSnapshot()),
	}

	exists, _, err := s.GetSnapshot().Exists(i.dir.Name)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, errorf(ErrNotFound, `instance '%d' not found`, id)
	}

	f, err := i.dir.GetFile(startPath, new(cp.ListCodec))
	if cp.IsErrNoEnt(err) {
		// Ignore
	} else if err != nil {
		return nil, err
	} else {
		fields := f.Value.([]string)

		if len(fields) > 0 { // IP
			i.Status = InsStatusClaimed
			i.IP = fields[0]
		}
		if len(fields) > 1 { // Port
			i.Status = InsStatusRunning
			i.Port, err = strconv.Atoi(fields[1])
			if err != nil {
				return nil, errorf(ErrInvalidPort, "invalid port: "+fields[1])
			}
		}
		if len(fields) > 2 { // Hostname
			i.Host = fields[2]
		}
		if len(fields) > 3 { // TelePort
			i.TelePort, err = strconv.Atoi(fields[3])
			if err != nil {
				return nil, errorf(ErrInvalidPort, "invalid teleport: "+fields[3])
			}
		}
	}

	statusStr, _, err := i.dir.Get(statusPath)
	if cp.IsErrNoEnt(err) {
		err = nil
	} else if err == nil {
		i.Status = InsStatus(statusStr)
	} else {
		return nil, err
	}

	if i.Status == InsStatusRunning {
		_, _, err := i.dir.Get(stopPath)
		if err == nil {
			i.Status = InsStatusStopping
		} else if !cp.IsErrNoEnt(err) {
			return nil, err
		}
	}

	f, err = i.dir.GetFile(objectPath, new(cp.ListCodec))
	if err != nil {
		return nil, errorf(ErrNotFound, "object file not found for instance %d", id)
	}

	fields := f.Value.([]string)
	if len(fields) < 3 {
		return nil, errorf(ErrInvalidFile, "object file for %d has %d instead %d fields", id, len(fields), 3)
	}

	i.AppName = fields[0]
	i.RevisionName = fields[1]
	i.ProcessName = fields[2]
	i.Env = fields[3]

	i.Restarts, _, err = i.getRestarts()
	if err != nil {
		return nil, err
	}

	f, err = i.dir.GetFile(registeredPath, new(cp.StringCodec))
	if err != nil {
		return nil, err
	}
	i.Registered, err = parseTime(f.Value.(string))
	if err != nil {
		return nil, err
	}

	f, err = i.claimDir().GetFile(i.IP, new(cp.StringCodec))
	if err != nil {
		if cp.IsErrNoEnt(err) {
			return i, nil
		}
		return nil, err
	}

	i.Claimed, err = parseTime(f.Value.(string))
	if err != nil {
		return nil, err
	}

	return i, nil
}