示例#1
0
文件: router.go 项目: zond/hackyhack
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
}
示例#2
0
文件: web.go 项目: zond/hackyhack
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
}