// Register registers a proc with the registry. func (p *Proc) Register() (*Proc, error) { sp, err := p.GetSnapshot().FastForward() if err != nil { return nil, err } exists, _, err := sp.Exists(p.dir.Name) if err != nil { return nil, err } if exists { return nil, ErrConflict } if !reProcName.MatchString(p.Name) { return nil, ErrBadProcName } p.Port, err = claimNextPort(sp) if err != nil { return nil, fmt.Errorf("couldn't claim port: %s", err) } port := cp.NewFile(p.dir.Prefix(procsPortPath), p.Port, new(cp.IntCodec), sp) port, err = port.Save() if err != nil { return nil, err } // Claim control port. p.ControlPort, err = claimNextPort(sp) if err != nil { return nil, fmt.Errorf("claim control port: %s", err) } controlPort := cp.NewFile(p.dir.Prefix(procsControlPortPath), p.ControlPort, new(cp.IntCodec), sp) controlPort, err = controlPort.Save() if err != nil { return nil, err } reg, err := parseTime(formatTime(time.Now())) if err != nil { return nil, err } d, err := p.dir.Join(sp).Set(registeredPath, formatTime(reg)) if err != nil { return nil, err } p.Registered = reg p.dir = d return p, nil }
// 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 }
// Started puts the Instance into start state. func (i *Instance) Started(host, hostname string, port, telePort int) (*Instance, error) { // // instances/ // 6868/ // object = <app> <rev> <proc> // - start = 10.0.0.1 // + start = 10.0.0.1 24690 localhost 24691 // if i.Status == InsStatusRunning { return i, nil } err := i.verifyClaimer(host) if err != nil { return nil, err } i.started(host, hostname, port, telePort) start := cp.NewFile(i.dir.Prefix(startPath), i.startArray(), new(cp.ListCodec), i.GetSnapshot()) start, err = start.Save() if err != nil { return nil, err } i.dir = i.dir.Join(start) return i, nil }
// NewHook returns a new Hook given an App, a name and the script. func (a *App) NewHook(name, script string) *Hook { return &Hook{ file: cp.NewFile(a.dir.Prefix(hooksPath, name), nil, new(cp.JsonCodec), a.GetSnapshot()), App: a, Name: name, Script: script, } }
// NewTag returns a named Tag referencing a given ref. func (a *App) NewTag(name, ref string) *Tag { return &Tag{ file: cp.NewFile( a.dir.Prefix(tagsPath, name), nil, new(cp.JsonCodec), a.GetSnapshot(), ), App: a, Name: name, Ref: ref, } }
// Register adds the App to the global process state. func (a *App) Register() (*App, error) { sp, err := a.GetSnapshot().FastForward() if err != nil { return nil, err } exists, _, err := sp.Exists(a.dir.Name) if err != nil { return nil, err } if exists { return nil, errorf(ErrConflict, `app "%s" already exists`, a.Name) } if a.DeployType == "" { a.DeployType = DeployLXC } v := map[string]interface{}{ "repo-url": a.RepoURL, "stack": a.Stack, "deploy-type": a.DeployType, } attrs := cp.NewFile(a.dir.Prefix("attrs"), v, new(cp.JsonCodec), sp) attrs, err = attrs.Save() if err != nil { return nil, err } a.dir = a.dir.Join(sp) for k, v := range a.Env { _, err = a.SetEnvironmentVar(k, v) if err != nil { return nil, err } } reg := time.Now() d, err := a.dir.Set(registeredPath, formatTime(reg)) if err != nil { return nil, err } a.Registered = reg a.dir = d return a, err }
// StoreAttrs saves the set Attrs for the Proc. func (p *Proc) StoreAttrs() (*Proc, error) { if p.Attrs.TrafficControl != nil { if err := p.Attrs.TrafficControl.Validate(); err != nil { return nil, err } } sp, err := p.GetSnapshot().FastForward() if err != nil { return nil, err } attrs := cp.NewFile(p.dir.Prefix(procsAttrsPath), p.Attrs, new(cp.JsonCodec), sp) attrs, err = attrs.Save() if err != nil { return nil, err } p.dir = p.dir.Join(attrs) return p, nil }
// Restarted tells the coordinator that the instance has been restarted. func (i *Instance) Restarted(restarts InsRestarts) (*Instance, error) { // // instances/ // 6868/ // object = <app> <rev> <proc> // start = 10.0.0.1 24690 localhost // - restarts = 1 4 // + restarts = 2 4 // // instances/ // 6869/ // object = <app> <rev> <proc> // start = 10.0.0.1 24691 localhost // + restarts = 1 0 // sp, err := i.GetSnapshot().FastForward() if err != nil { return i, err } i, err = getInstance(i.ID, sp) if err != nil { return nil, err } if i.Status != InsStatusRunning { return i, nil } f := cp.NewFile(i.dir.Prefix(restartsPath), nil, new(cp.ListIntCodec), sp) f, err = f.Set(restarts.Fields()) if err != nil { return nil, err } i.Restarts = restarts i.dir = i.dir.Join(f) return i, nil }
func (i *Instance) updateLookup( from, to InsStatus, client string, reason error, ) (*Instance, error) { i.Termination = Termination{ Client: client, Reason: reason.Error(), Time: time.Now(), } sp, err := i.GetSnapshot().FastForward() if err != nil { return nil, err } if from == InsStatusFailed || from == InsStatusLost { ins, err := getSerialisedInstance(i.AppName, i.ProcessName, i.ID, from, sp) if err != nil { return nil, err } i.Termination = ins.Termination } f := cp.NewFile(sp.Prefix(i.procStatusPath(to)), i, new(cp.JsonCodec), sp) f, err = f.Save() if err != nil { return nil, err } i.dir = i.dir.Join(f) err = i.dir.Snapshot.Del(i.procStatusPath(from)) if err != nil { return nil, err } return i, nil }
// Register adds the Env to the Apps envs. func (e *Env) Register() (*Env, error) { sp, err := e.GetSnapshot().FastForward() if err != nil { return nil, err } exists, _, err := sp.Exists(e.dir.Name) if err != nil { return nil, err } if exists { return nil, errorf(ErrConflict, `env "%s" can't be overwritten`, e.Ref) } for k := range e.Vars { if len(k) == 0 { return nil, errorf(ErrInvalidKey, `env keys can't be emproc`) } if strings.Contains(k, "=") { return nil, errorf(ErrInvalidKey, `env keys can't contain "="`) } } attrs := cp.NewFile(e.dir.Prefix(varsPath), e.Vars, new(cp.JsonCodec), sp) attrs, err = attrs.Save() if err != nil { return nil, err } reg := time.Now() d, err := e.dir.Set(registeredPath, formatTime(reg)) if err != nil { return nil, err } e.Registered = reg e.dir = d return e, nil }
// Register saves the runner in the coordinator. func (r *Runner) Register() (*Runner, error) { sp, err := r.GetSnapshot().FastForward() if err != nil { return nil, err } exists, _, err := sp.Exists(r.dir.Name) if err != nil { return nil, err } if exists { return nil, ErrConflict } f := cp.NewFile(r.dir.Name, []string{strconv.FormatInt(r.InstanceID, 10)}, new(cp.ListCodec), sp) f, err = f.Save() if err != nil { return nil, err } r.dir = r.dir.Join(f) return r, nil }