func (r *Router) createMCP(resourceId string) (*mcp.MCP, error) { r.handlerLock.Lock() defer r.handlerLock.Unlock() hd, found := r.handlerDataByResource[resourceId] if found { return hd.m, nil } res := &resource.Resource{} if err := r.persister.Get(resourceId, res); err != nil { return nil, err } if err := validator.Validate(res.Code); err != nil { return nil, err } oc, err := newOwnerCode(res.Owner, res.Code) if err != nil { return nil, err } m, found := r.handlerByOwnerCode[oc] if found { if err := r.construct(m, res); err != nil { return nil, err } r.handlerDataByResource[res.Id] = handlerData{ oc: oc, m: m, } return m, nil } m, err = mcp.New(res.Code, r.findResource) if err != nil { return nil, err } if err := m.Start(); err != nil { return nil, err } if err := r.construct(m, res); err != nil { return nil, err } r.handlerByOwnerCode[oc] = m r.handlerDataByResource[res.Id] = handlerData{ oc: oc, m: m, } return m, nil }
func (web *Web) putResource(c *context) error { res := &resource.Resource{} if err := web.persister.Get(c.vars["resource"], res); err == persist.ErrNotFound { return webErr{status: 404, body: err.Error()} } else if err != nil { return err } if res.Owner != c.user.Resource { return webErr{status: 403, body: "Not owner"} } tmpFileBase := filepath.Join(os.TempDir(), fmt.Sprintf("%x%x", rand.Int63(), rand.Int63())) tmpFileName := fmt.Sprintf("%v.go", tmpFileBase) tmpFile, err := os.Create(tmpFileName) if err != nil { return err } if err := func() error { defer tmpFile.Close() if _, err := io.Copy(tmpFile, c.req.Body); err != nil { return err } return nil }(); err != nil { return err } defer os.Remove(tmpFileName) output, err := exec.Command("goimports", "-w", tmpFileName).CombinedOutput() if err != nil { return err } if len(output) > 0 { return webErr{status: 400, body: string(output)} } body, err := ioutil.ReadFile(tmpFileName) if err != nil { return err } if err := validator.Validate(string(body)); err != nil { return webErr{status: 400, body: err.Error()} } output, err = exec.Command("go", "build", "-o", tmpFileBase, tmpFileName).CombinedOutput() if err != nil { return err } if len(output) > 0 { return webErr{status: 400, body: string(output)} } if err := web.persister.Transact(func(p *persist.Persister) error { if err := p.Get(res.Id, res); err != nil { return err } res.Code = string(body) return p.Put(res.Id, res) }); err != nil { return err } if err := web.hackRouter.Restart(res.Id); err != nil { return err } return nil }