You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
3.5 KiB

package daemon
import (
"errors"
"fmt"
"os"
"strconv"
"github.com/subgraph/oz/ipc"
)
func clientConnect() (*ipc.MsgConn, error) {
return ipc.Connect(SocketName, messageFactory, nil)
}
func clientSend(msg interface{}) (*ipc.Message, error) {
c, err := clientConnect()
if err != nil {
return nil, err
}
defer c.Close()
rr, err := c.ExchangeMsg(msg)
if err != nil {
return nil, err
}
resp := <-rr.Chan()
rr.Done()
return resp, nil
}
func ListProfiles() ([]Profile, error) {
resp, err := clientSend(new(ListProfilesMsg))
if err != nil {
return nil, err
}
body, ok := resp.Body.(*ListProfilesResp)
if !ok {
return nil, errors.New("ListProfiles response was not expected type")
}
return body.Profiles, nil
}
func ListSandboxes() ([]SandboxInfo, error) {
resp, err := clientSend(&ListSandboxesMsg{})
if err != nil {
return nil, err
}
body, ok := resp.Body.(*ListSandboxesResp)
if !ok {
return nil, errors.New("ListSandboxes response was not expected type")
}
return body.Sandboxes, nil
}
func Launch(arg, cpath string, args []string, noexec bool) error {
idx, name, err := parseProfileArg(arg)
if err != nil {
return err
}
pwd, _ := os.Getwd()
groups, _ := os.Getgroups()
gg := []uint32{}
if len(groups) > 0 {
gg = make([]uint32, len(groups))
for i, v := range groups {
gg[i] = uint32(v)
}
}
resp, err := clientSend(&LaunchMsg{
Index: idx,
Name: name,
Path: cpath,
Pwd: pwd,
Gids: gg,
Args: args,
Env: os.Environ(),
Noexec: noexec,
})
if err != nil {
return err
}
switch body := resp.Body.(type) {
case *ErrorMsg:
fmt.Printf("error was %s\n", body.Msg)
case *OkMsg:
fmt.Println("ok received")
default:
fmt.Printf("Unexpected message received %+v", body)
}
return nil
}
func KillAllSandboxes() error {
return KillSandbox(-1)
}
func KillSandbox(id int) error {
resp, err := clientSend(&KillSandboxMsg{Id: id})
if err != nil {
return err
}
switch body := resp.Body.(type) {
case *ErrorMsg:
return errors.New(body.Msg)
case *OkMsg:
return nil
default:
return fmt.Errorf("Unexpected message received %+v", body)
}
}
func MountFiles(files []string) error {
resp, err := clientSend(&MountFilesMsg{Files: files})
if err != nil {
return err
}
switch body := resp.Body.(type) {
case *ErrorMsg:
return errors.New(body.Msg)
case *OkMsg:
return nil
default:
return fmt.Errorf("Unexpected message received %+v", body)
}
}
func UnmountFile(file string) error {
resp, err := clientSend(&UnmountFileMsg{File: file})
if err != nil {
return err
}
switch body := resp.Body.(type) {
case *ErrorMsg:
return errors.New(body.Msg)
case *OkMsg:
return nil
default:
return fmt.Errorf("Unexpected message received %+v", body)
}
}
func parseProfileArg(arg string) (int, string, error) {
if len(arg) == 0 {
return 0, "", errors.New("profile argument needed")
}
if n, err := strconv.Atoi(arg); err == nil {
return n, "", nil
}
return 0, arg, nil
}
func Logs(count int, follow bool) (chan string, error) {
c, err := clientConnect()
if err != nil {
return nil, err
}
rr, err := c.ExchangeMsg(&LogsMsg{Count: count, Follow: follow})
if err != nil {
return nil, err
}
out := make(chan string)
go dumpLogs(out, rr)
return out, nil
}
func dumpLogs(out chan<- string, rr ipc.ResponseReader) {
for resp := range rr.Chan() {
switch body := resp.Body.(type) {
case *OkMsg:
rr.Done()
close(out)
return
case *LogData:
for _, ll := range body.Lines {
out <- ll
}
default:
out <- fmt.Sprintf("Unexpected response type (%T)", body)
}
}
}