func getSerialisedInstance( app, proc string, id int64, status InsStatus, sp cp.Snapshot, ) (*Instance, error) { var ( i = &Instance{ ID: id, AppName: app, ProcessName: proc, dir: cp.NewDir(instancePath(id), sp), } c = &cp.JsonCodec{ DecodedVal: i, } ) _, err := sp.GetFile(i.procStatusPath(status), c) if err != nil { return nil, errorf(err, "fetching instance %d: %s", id, err) } return i, nil }
// NewRunner creates a Runner for the given Instance. func (s *Store) NewRunner(addr string, instanceID int64) *Runner { return &Runner{ dir: cp.NewDir(runnerPath(addr), s.GetSnapshot()), Addr: addr, InstanceID: instanceID, } }
// NewProc creates a Proc given App and name. func (s *Store) NewProc(app *App, name string) *Proc { return &Proc{ Name: name, App: app, dir: cp.NewDir(app.dir.Prefix(procsPath, string(name)), s.GetSnapshot()), } }
// NewEnv returns a new Env given an App, the ref and the map of vars. func (a *App) NewEnv(ref string, vars map[string]string) *Env { path := a.dir.Prefix(envsPath, ref) return &Env{ dir: cp.NewDir(path, a.GetSnapshot()), App: a, Ref: ref, Vars: vars, } }
// RegisterInstance stores the Instance. func (s *Store) RegisterInstance(app, rev, proc, env string) (ins *Instance, err error) { // // instances/ // 6868/ // + object = <app> <rev> <proc> // + start = // // apps/<app>/procs/<proc>/instances/<rev> // + 6868 = 2012-07-19 16:41 UTC // id, err := s.GetSnapshot().Getuid() if err != nil { return } ins = &Instance{ ID: id, AppName: app, RevisionName: rev, ProcessName: proc, Env: env, Registered: time.Now(), Status: InsStatusPending, dir: cp.NewDir(instancePath(id), s.GetSnapshot()), } object := cp.NewFile(ins.dir.Prefix(objectPath), ins.objectArray(), new(cp.ListCodec), s.GetSnapshot()) object, err = object.Save() if err != nil { return nil, err } start := cp.NewFile(ins.dir.Prefix(startPath), "", new(cp.StringCodec), s.GetSnapshot()) start, err = start.Save() if err != nil { return nil, err } // Create the file used for lookups of existing instances per proc. _, err = ins.GetSnapshot().Set(ins.procStatusPath(InsStatusRunning), formatTime(ins.Registered)) if err != nil { return nil, err } // This should be the last path set in order for the event system to work properly. registered, err := ins.dir.Set(registeredPath, formatTime(ins.Registered)) if err != nil { return } ins.dir = ins.dir.Join(registered) return }
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 }
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 }
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 }
// NewApp returns a new App given a name, repository url and stack. func (s *Store) NewApp(name string, repourl string, stack string) (app *App) { app = &App{Name: name, RepoURL: repourl, Stack: stack, Env: map[string]string{}} app.dir = cp.NewDir(path.Join(appsPath, app.Name), s.GetSnapshot()) return }
// NewRevision returns a new instance of Revision. func (s *Store) NewRevision(app *App, ref, archiveURL string) (rev *Revision) { rev = &Revision{App: app, Ref: ref, ArchiveURL: archiveURL} rev.dir = cp.NewDir(app.dir.Prefix(revsPath, ref), s.GetSnapshot()) return }
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 }
func (i *Instance) claimDir() *cp.Dir { return cp.NewDir(i.dir.Prefix(claimsPath), i.GetSnapshot()) }