diff --git a/container.go b/container.go index f1fa2d4..2c5eca5 100644 --- a/container.go +++ b/container.go @@ -28,14 +28,16 @@ type ContainerFactory interface { } type ContainerConfig struct { - language string // language that icode use + Language string // language that icode use // todo ENUM 으로 대체하면 좋음 ( expect to change enum ) Name string // container name ContainerImage ContainerImage // container docker image name to pull. example : 'golang:1.9' - IP string // IP address that manage icode. + HostIp string // HostIp address that manage icode. + + ContainerIp string // ContainerIp Port string // port num to communicate container and icode diff --git a/container/provider.go b/container/provider.go index e7b744b..b2c15d9 100644 --- a/container/provider.go +++ b/container/provider.go @@ -38,7 +38,7 @@ func Create(config tesseract.ContainerConfig) (DockerContainer, error) { containerImage := config.ContainerImage // checking port - lis, err := net.Listen("tcp", "127.0.0.1:"+config.Port) + lis, err := net.Listen("tcp", config.HostIp+":"+config.Port) lis.Close() if err != nil { return DockerContainer{}, err @@ -65,7 +65,7 @@ func Create(config tesseract.ContainerConfig) (DockerContainer, error) { return DockerContainer{}, err } - client, err := createClient(config.IP, config.Port) + client, err := createClient(config.ContainerIp, config.Port) if err != nil { iLogger.Errorf(nil, "[Tesseract] closing container %s", res.ID) diff --git a/docker/docker.go b/docker/docker.go index b02a305..dc9496a 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -20,6 +20,7 @@ import ( "github.com/docker/go-connections/nat" "github.com/it-chain/iLogger" "github.com/it-chain/tesseract" + "docker.io/go-docker/api/types/network" ) func CreateContainer(config tesseract.ContainerConfig) (container.ContainerCreateCreatedBody, error) { @@ -45,20 +46,28 @@ func CreateContainer(config tesseract.ContainerConfig) (container.ContainerCreat networkName := "" portBinding := nat.PortMap{} exposedPort := nat.PortSet{} + var networkConfig *network.NetworkingConfig if config.Network != nil { networkName = config.Network.Name - } - if config.Port != "" { + endpointSetting := make(map[string]*network.EndpointSettings) + endpointSetting[config.Network.Name] = &network.EndpointSettings{ + IPAddress: config.ContainerIp, + } + networkConfig = &network.NetworkingConfig{ + EndpointsConfig: endpointSetting, + } + }else{ exposedPort = nat.PortSet{ nat.Port(config.Port + "/tcp"): struct{}{}, } portBinding = nat.PortMap{ nat.Port(config.Port + "/tcp"): []nat.PortBinding{{ - HostIP: config.IP, + HostIP: config.HostIp, HostPort: config.Port, }}, } + } if err != nil { @@ -78,12 +87,13 @@ func CreateContainer(config tesseract.ContainerConfig) (container.ContainerCreat AttachStdout: true, AttachStderr: true, ExposedPorts: exposedPort, + }, &container.HostConfig{ CapAdd: []string{"SYS_ADMIN"}, PortBindings: portBinding, Binds: config.Mount, NetworkMode: container.NetworkMode(networkName), - }, nil, containerName) + }, networkConfig, containerName) if err != nil { return res, err @@ -276,21 +286,29 @@ func RemoveVolume(name string, force bool) error { return cli.VolumeRemove(ctx, name, force) } -func CreateNetwork(name string) (tesseract.Network, error) { +func CreateNetwork(name string, subnet string) (tesseract.Network, error) { ctx := context.Background() cli, _ := docker.NewEnvClient() defer cli.Close() - network, err := FindNetworkByName(name) + findNetwork, err := FindNetworkByName(name) if err != nil { return tesseract.Network{}, err } - if !isNetworkEmpty(network) { + if !isNetworkEmpty(findNetwork) { return tesseract.Network{}, errors.New("already exist network name") } - res, err := cli.NetworkCreate(ctx, name, types.NetworkCreate{}) + res, err := cli.NetworkCreate(ctx, name, types.NetworkCreate{ + Driver: "bridge", + IPAM: &network.IPAM{ + Options: nil, + Config: []network.IPAMConfig{ + {Subnet: subnet}, + }, + }, + }) if err != nil { return tesseract.Network{}, err @@ -302,48 +320,57 @@ func CreateNetwork(name string) (tesseract.Network, error) { }, nil } -func FindNetworkByName(name string) (types.NetworkResource, error) { +func FindNetworkByName(name string) (tesseract.Network, error) { ctx := context.Background() cli, _ := docker.NewEnvClient() defer cli.Close() networkList, err := cli.NetworkList(ctx, types.NetworkListOptions{}) if err != nil { - return types.NetworkResource{}, err + return tesseract.Network{}, err } - for _, network := range networkList { - if network.Name == name { - return network, nil + for _, net := range networkList { + if net.Name == name { + return tesseract.Network{ + ID: net.ID, + Name: net.Name, + }, nil } } - return types.NetworkResource{}, nil + return tesseract.Network{}, nil } -func FindVolumeByName(name string) (types.Volume, error) { +func FindVolumeByName(name string) (tesseract.Volume, error) { ctx := context.Background() cli, _ := docker.NewEnvClient() defer cli.Close() listBody, err := cli.VolumeList(ctx, filters.Args{}) if err != nil { - return types.Volume{}, err + return tesseract.Volume{}, err } for _, vol := range listBody.Volumes { if vol.Name == name { - return *vol, nil + return tesseract.Volume{ + CreatedAt: vol.CreatedAt, + Driver: vol.Driver, + Mountpoint: vol.Mountpoint, + Name: vol.Name, + Options: vol.Options, + }, nil } } - return types.Volume{}, nil + return tesseract.Volume{}, nil } -func isVolumeEmpty(vol types.Volume) bool { - return reflect.DeepEqual(vol, types.Volume{}) +func isVolumeEmpty(vol tesseract.Volume) bool { + return reflect.DeepEqual(vol, tesseract.Volume{}) } -func isNetworkEmpty(vol types.NetworkResource) bool { - return reflect.DeepEqual(vol, types.NetworkResource{}) +func isNetworkEmpty(vol tesseract.Network) bool { + return reflect.DeepEqual(vol, tesseract.Network{}) } func convToVolumesCreateBody(name string) volume.VolumesCreateBody { diff --git a/docker/docker_test.go b/docker/docker_test.go index 7fd75dc..706d298 100644 --- a/docker/docker_test.go +++ b/docker/docker_test.go @@ -68,7 +68,7 @@ func TestCreateContainer(t *testing.T) { res, err := docker.CreateContainer(tesseract.ContainerConfig{ Name: "container_mock", ContainerImage: testGolangImg, - IP: "127.0.0.1", + HostIp: "127.0.0.1", Port: "50001", StartCmd: []string{"go", "run", path.Join("/go/src", "icode_1", "icode.go"), "-p", "50001"}, Network: nil, @@ -108,7 +108,7 @@ func TestCreateContainerWithVolume(t *testing.T) { tesseract.ContainerConfig{ Name: "container_volume_test", ContainerImage: GolangImg, - IP: "127.0.0.1", + HostIp: "127.0.0.1", Port: "50001", StartCmd: []string{"cp", "-r", "/go/src/github.com/it-chain/tesseract/", "/volume/", "&&", "go", "run", "/go/src/github.com/it-chain/tesseract/test/volume/main.go", v.Name}, Network: nil, diff --git a/network.go b/network.go index c1d0130..99104e7 100644 --- a/network.go +++ b/network.go @@ -1,6 +1,6 @@ package tesseract type Network struct { - ID string - Name string + ID string + Name string } diff --git a/test/volume/main.go b/test/volume/main.go index e02b41e..4b23723 100644 --- a/test/volume/main.go +++ b/test/volume/main.go @@ -41,7 +41,7 @@ func main() { tesseract.ContainerConfig{ Name: "container_mock", ContainerImage: testGolangImg, - IP: "127.0.0.1", + HostIp: "127.0.0.1", Port: "50002", //StartCmd: []string{"go", "run", "/go/src/github.com/it-chain/tesseract/mock/test-volume/main.go"}, StartCmd: []string{"sleep", "1000"},