diff --git a/cellcode/stream_cellcode.go b/cellcode/stream_cellcode.go deleted file mode 100644 index c50686e..0000000 --- a/cellcode/stream_cellcode.go +++ /dev/null @@ -1,83 +0,0 @@ -package main - -/* - -import ( - "os" - "os/exec" - "plugin" - - "fmt" - "log" - "net" - - "github.com/it-chain/tesseract/cellcode/cell" - "github.com/it-chain/tesseract/pb" - "github.com/it-chain/tesseract/stream" - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" -) - -type ICode interface { - Query(cell.Cell) - Invoke(cell.Cell) -} - -func main() { - if len(os.Args) != 3 { - os.Exit(1) - } - - iCodePath := os.Args[1] - port := os.Args[2] - - plug, err := plugin.Open(iCodePath) - if err != nil { - os.Exit(1) - } - - iCodePlugin, err := plug.Lookup("ICodeInstance") - if err != nil { - os.Exit(1) - } - - iCode := iCodePlugin.(ICode) - - cmd := exec.Command("touch", "/icode/1") - cmd.Run() - // Socket Connection - serverStream := stream.NewDefaultServerStream(port, func() { - cmd := exec.Command("touch", "/icode/2") - cmd.Run() - - // Setting Cell - - cell := cell.NewCell() - - if true { - iCode.Query(*cell) - } - cmd = exec.Command("touch", "/icode/inHandler") - cmd.Run() - }) - Listen(serverStream) - - cmd = exec.Command("touch", "/icode/end") - cmd.Run() - -} - -func Listen(s *stream.DefaultServerStream) { - lis, err := net.Listen("tcp", ":50003") - if err != nil { - log.Fatalf("failed to listen: %v", err) - } - server := grpc.NewServer() - pb.RegisterStreamServiceServer(server, s) - reflection.Register(server) - fmt.Println(s.Port + "in Listen") - if err := server.Serve(lis); err != nil { - log.Fatalf("failed to serve: %v", err) - } -} -*/ diff --git a/docker/default_docker.go b/docker/default_docker.go index be89be8..df8ba45 100644 --- a/docker/default_docker.go +++ b/docker/default_docker.go @@ -167,3 +167,28 @@ func CloseContainer(id string) error { return nil } + +// todo : create test case +func GetUsingPorts() ([]Port, error) { + ctx := context.Background() + cli, _ := docker.NewEnvClient() + portList := make([]Port, 0) + containerList, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true}) + + if err != nil { + return portList, err + } + + for _, oneContainer := range containerList { + for _, containerPort := range oneContainer.Ports { + portInfo := Port{ + IP: containerPort.IP, + PrivatePort: int(containerPort.PrivatePort), + PublicPort: int(containerPort.PublicPort), + } + portList = append(portList, portInfo) + } + } + + return portList, nil +} diff --git a/docker/docker.go b/docker/docker.go index 65ef094..128123d 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -5,4 +5,16 @@ import "docker.io/go-docker/api/types/container" type Docker interface { CreateContainerWithCellCode(dockerImage Image, dir string, shPath string, port string) (container.ContainerCreateCreatedBody, error) StartContainer(containerBody container.ContainerCreateCreatedBody) error + GetUsingPorts() ([]Port, error) +} + +type Port struct { + // Host IP address that the container's port is mapped to + IP string + + // Port on the container + PrivatePort int + + // Port exposed on the host + PublicPort int } diff --git a/tesseract.go b/tesseract.go index 915113e..949d0f6 100644 --- a/tesseract.go +++ b/tesseract.go @@ -10,6 +10,8 @@ import ( "encoding/json" + "fmt" + "github.com/it-chain/tesseract/cellcode/cell" "github.com/it-chain/tesseract/docker" "github.com/it-chain/tesseract/pb" @@ -99,24 +101,32 @@ func (t *Tesseract) SetupContainer(iCodeInfo ICodeInfo) (string, error) { } //1씩 증가 시키며 port를 확인한다 -//todo 이 함수 작동의미가 없음 tcp 50001과는 다름 -//todo docker daemon port check방법을 찾아야함 or docker network 구성 func getAvailablePort() (string, error) { + portList, err := docker.GetUsingPorts() + if err != nil { + return "", err + } +findLoop: for { - lis, err := net.Listen("tcp", "127.0.0.1:"+defaultPort) - - if err == nil { - lis.Close() - return defaultPort, nil - } - portNumber, err := strconv.Atoi(defaultPort) - if err != nil { return "", err } + for _, portInfo := range portList { + if portNumber == portInfo.PublicPort || portNumber == portInfo.PrivatePort { + fmt.Println("already using port! : ", string(portNumber)) + portNumber++ + defaultPort = strconv.Itoa(portNumber) + continue findLoop + } + } + lis, err := net.Listen("tcp", "127.0.0.1:"+defaultPort) + if err == nil { + lis.Close() + return defaultPort, nil + } portNumber++ defaultPort = strconv.Itoa(portNumber) } diff --git a/tesseract_internal_test.go b/tesseract_internal_test.go new file mode 100644 index 0000000..17e3e04 --- /dev/null +++ b/tesseract_internal_test.go @@ -0,0 +1,41 @@ +package tesseract + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetAvailablePort(t *testing.T) { + GOPATH := os.Getenv("GOPATH") + var setup = func(config Config) (*Tesseract, func()) { + te := New(config) + + return te, func() { + + t.Log("container is closing") + te.StopContainer() + } + } + + tesseract, tearDown := setup(Config{ShPath: GOPATH + "/src/github.com/it-chain/tesseract/sh/default_setup.sh"}) + + defer tearDown() + + code1 := ICodeInfo{ + Directory: GOPATH + "/src/github.com/it-chain/tesseract/cellcode/mock/icode/", + } + code2 := ICodeInfo{ + Directory: GOPATH + "/src/github.com/it-chain/tesseract/cellcode/mock/icode/", + } + code3 := ICodeInfo{ + Directory: GOPATH + "/src/github.com/it-chain/tesseract/cellcode/mock/icode/", + } + _, err := tesseract.SetupContainer(code1) + assert.NoError(t, err) + _, err = tesseract.SetupContainer(code2) + assert.NoError(t, err) + _, err = tesseract.SetupContainer(code3) + assert.NoError(t, err) +}