diff options
Diffstat (limited to 'hyper')
| -rw-r--r-- | hyper/process/Makefile | 23 | ||||
| -rw-r--r-- | hyper/process/main.go | 80 | ||||
| -rw-r--r-- | hyper/process/src/hyper/process/Makefile | 11 | ||||
| -rw-r--r-- | hyper/process/src/hyper/process/process.go | 125 | 
4 files changed, 194 insertions, 45 deletions
| diff --git a/hyper/process/Makefile b/hyper/process/Makefile index 7d61b28d..bbc1c2fb 100644 --- a/hyper/process/Makefile +++ b/hyper/process/Makefile @@ -1,14 +1,19 @@ +include $(GOROOT)/src/Make.inc -A := 8 +GCIMPORTS = -I pkg/$(GOOS)_$(GOARCH) +LDIMPORTS = -L pkg/$(GOOS)_$(GOARCH) -.PHONY: all clean -all: main +TARG=main +GOFILES=\ +	main.go\ -clean: -	rm -f main *.$A +include $(GOROOT)/src/Make.cmd -%.$A: %.go -	$Ag $< +export GOPATH := $(PWD) +.PHONY: prepare +prepare: +	#goinstall -v github.com/garyburd/twister/server +	goinstall -v gorilla.googlecode.com/hg/gorilla/mux +	goinstall -v $(PWD)/src/hyper/process -%: %.$A -	$Al -o $@ $< +_go_.$O: prepare diff --git a/hyper/process/main.go b/hyper/process/main.go index 297be2cf..ebeeb6d6 100644 --- a/hyper/process/main.go +++ b/hyper/process/main.go @@ -1,52 +1,60 @@  package main -import "fmt" +import "json" +import "log" +import "http" +import "gorilla.googlecode.com/hg/gorilla/mux"  import "os" +import "fmt" + +import "hyper/process" +var proc = map[string] *hyper.Process{} -func reader(file *os.File) { -  var b []byte = make([]byte, 1024) -  var err os.Error = nil -  for err == nil { -    var n int -    n, err = file.Read(b) -    fmt.Printf("data: %d, %s\n", n, b) +// TODO Retrieve Process, Write, Kill [autokill], get exit code + +func RespondJSON(res http.ResponseWriter, v interface{}) os.Error { +  content, err := json.Marshal(v) +  if err == nil { +    log.Printf("< %s", content) +    res.Header().Set("Content-Type", "application/json; charset=\"utf-8\"") +    res.WriteHeader(http.StatusOK) +    res.Write(content) +  } else { +    log.Printf("%s while json.Marshal(%s)", err, v)    } +  return err  } -func main() { -  var name = "/usr/bin/bc" -  var argv = []string{ "bc" } -  var envv = []string{ "FOO=23" } -  //var chroot = false -  var dir = "/var/empty" -  var files [3][2]*os.File -  var err os.Error -  -  for i, _ := range files { -    files[i][0], files[i][1], err = os.Pipe() -    err = err +func CreateProcessHandler(res http.ResponseWriter, req *http.Request) { +  if p, err := hyper.NewProcess(req); err == nil { +    id := p.Id() +    proc[id] = p +    RespondJSON(res, &map[string]string{ +      "path": fmt.Sprintf("/proc/%s", id), +    }) +  } else { +    log.Printf("%s", err) +    res.WriteHeader(http.StatusInternalServerError)    } +} -  var attr = &os.ProcAttr{ -    Dir: dir, -    Env: envv, -    Files: []*os.File{ /*files[0][0] */ os.Stdin, files[1][1], files[2][1]}, +func RetrieveProcess(res http.ResponseWriter, req *http.Request) { +  if p := proc[mux.Vars(req)["id"]]; p != nil { +    RespondJSON(res, p) +  } else { +    res.WriteHeader(http.StatusNotFound)    } +} -  var p *os.Process +func main() { -  p, err = os.StartProcess(name, argv, attr) +  // Gorilla +  mux.HandleFunc("/proc", CreateProcessHandler).Methods("POST") +  mux.HandleFunc("/proc/{id}", RetrieveProcess).Methods("GET") -  for _, file := range attr.Files { -    file.Close() +  err := http.ListenAndServe(":8888", mux.DefaultRouter) +  if err != nil { +    log.Fatal("ListenAndServe: ", err.String())    } - -  p=p - -  go reader(files[1][0]) -  reader(files[2][0]) - -  fmt.Printf("hello, world\n") -  } diff --git a/hyper/process/src/hyper/process/Makefile b/hyper/process/src/hyper/process/Makefile new file mode 100644 index 00000000..7ecda716 --- /dev/null +++ b/hyper/process/src/hyper/process/Makefile @@ -0,0 +1,11 @@ +include ${GOROOT}/src/Make.inc + +TARG=hyper/process + +GOFILES=\ +	process.go\ + +#DEPS=\ +#	gorilla.googlecode.com/hg/gorilla/context\ + +include ${GOROOT}/src/Make.pkg diff --git a/hyper/process/src/hyper/process/process.go b/hyper/process/src/hyper/process/process.go new file mode 100644 index 00000000..a52197f0 --- /dev/null +++ b/hyper/process/src/hyper/process/process.go @@ -0,0 +1,125 @@ +package hyper + +import "fmt" +import "http" +import "bytes" +import "json" +import "os" + +type Process struct { +  Path string               `json:"path"` +  Argv []string             `json:"argv"` +  Envp map[string]string    `json:"envp"` +  //Stdin string              `json:"stdin"` +  Stdout string             `json:"stdout"` +  Stderr string             `json:"stderr"` +  process *os.Process +  process_stdin *os.File +  process_stdout *os.File +  process_stderr *os.File +  id string +} + +func (p *Process) Id() string { +  return p.id +} + +func NewProcess(req *http.Request) (*Process, os.Error) { +  body := make([]byte, 4096) +  _, err := req.Body.Read(body) +  if err != nil { +    return nil, err +  } + +  body = bytes.TrimRight(body, string([]byte{0})) + +  var p Process + +  if err := json.Unmarshal(body, &p); err != nil { +    return nil, err +  } + +  p.id = gensym() + +  if err := p.Start(); err != nil { +    return nil, err +  } + +  return &p, nil +} + +func (hp *Process) Write(b []byte) { +  n, err := hp.process_stdin.Write(b) +  if err != nil { +    fmt.Printf("Write: %s\n", err) +  } else { +    fmt.Printf("Wrote: %d bytes\n", n) +  } +} + +func (hp *Process) Start() os.Error { +  var name = hp.Path //os.Args[1] //"/usr/b" +  var argv = hp.Argv //os.Args[1:] //[]string{ "bc" } +  //var chroot = false +  //var dir = "/var/empty" +  var files [3][2]*os.File +  var err os.Error + +  for i, _ := range files { +    files[i][0], files[i][1], err = os.Pipe() +    if err != nil { +      return err +    } +  } + +  var env []string +  for k, v := range hp.Envp { +    env = append(env, fmt.Sprintf("%s=%s", k, v)) +  } + +  var attr = &os.ProcAttr{ +    //Dir: dir, +    Env: env, //os.Environ(), +    Files: []*os.File{ files[0][0], files[1][1], files[2][1]}, +  } + +  //var foo, _ = json.Marshal(attr) +  //fmt.Printf("%s\n", foo) + +  hp.process, err = os.StartProcess(name, argv, attr) +  if err != nil { +    return err +  } + +  hp.process_stdin = files[0][1] +  hp.process_stdout = files[1][0] +  hp.process_stderr = files[2][0] + +  for _, file := range attr.Files { +    file.Close() +  } + +  go reader(hp.process_stdout) +  go reader(hp.process_stderr) +  return nil +} + +func reader(file *os.File) { +  var b []byte = make([]byte, 1024) +  var err os.Error = nil +  for err == nil { +    var n int +    n, err = file.Read(b) +    fmt.Printf("data: %d, %s\n", n, b) +  } +} + +func gensym() string { +  f, _ := os.Open("/dev/urandom")  +  b := make([]byte, 16)  +  f.Read(b)  +  f.Close()  +  uuid := fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])  +  return uuid +} + | 
