2022-07-08 16:01:23 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"testing"
|
2022-07-10 11:17:44 +00:00
|
|
|
"time"
|
2022-07-08 16:01:23 +00:00
|
|
|
|
2022-07-24 14:54:16 +00:00
|
|
|
C "github.com/sagernet/sing-box/constant"
|
2022-07-08 16:01:23 +00:00
|
|
|
F "github.com/sagernet/sing/common/format"
|
|
|
|
|
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"github.com/docker/docker/api/types/container"
|
|
|
|
"github.com/docker/docker/client"
|
|
|
|
"github.com/docker/go-connections/nat"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
type DockerOptions struct {
|
|
|
|
Image string
|
|
|
|
EntryPoint string
|
|
|
|
Ports []uint16
|
|
|
|
Cmd []string
|
|
|
|
Env []string
|
|
|
|
Bind []string
|
2022-07-18 10:50:19 +00:00
|
|
|
Stdin []byte
|
2022-07-08 16:01:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func startDockerContainer(t *testing.T, options DockerOptions) {
|
|
|
|
dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
|
|
|
require.NoError(t, err)
|
|
|
|
defer dockerClient.Close()
|
|
|
|
|
2022-07-18 10:50:19 +00:00
|
|
|
writeStdin := len(options.Stdin) > 0
|
|
|
|
|
2022-07-08 16:01:23 +00:00
|
|
|
var containerOptions container.Config
|
2022-07-18 10:50:19 +00:00
|
|
|
|
|
|
|
if writeStdin {
|
|
|
|
containerOptions.OpenStdin = true
|
|
|
|
containerOptions.StdinOnce = true
|
|
|
|
}
|
|
|
|
|
2022-07-08 16:01:23 +00:00
|
|
|
containerOptions.Image = options.Image
|
2022-07-18 10:50:19 +00:00
|
|
|
if options.EntryPoint != "" {
|
|
|
|
containerOptions.Entrypoint = []string{options.EntryPoint}
|
|
|
|
}
|
2022-07-08 16:01:23 +00:00
|
|
|
containerOptions.Cmd = options.Cmd
|
|
|
|
containerOptions.Env = options.Env
|
|
|
|
containerOptions.ExposedPorts = make(nat.PortSet)
|
|
|
|
|
|
|
|
var hostOptions container.HostConfig
|
2022-07-24 14:54:16 +00:00
|
|
|
if !C.IsDarwin {
|
2022-07-08 16:01:23 +00:00
|
|
|
hostOptions.NetworkMode = "host"
|
|
|
|
}
|
|
|
|
hostOptions.PortBindings = make(nat.PortMap)
|
|
|
|
|
|
|
|
for _, port := range options.Ports {
|
|
|
|
containerOptions.ExposedPorts[nat.Port(F.ToString(port, "/tcp"))] = struct{}{}
|
|
|
|
containerOptions.ExposedPorts[nat.Port(F.ToString(port, "/udp"))] = struct{}{}
|
|
|
|
hostOptions.PortBindings[nat.Port(F.ToString(port, "/tcp"))] = []nat.PortBinding{
|
|
|
|
{HostPort: F.ToString(port), HostIP: "0.0.0.0"},
|
|
|
|
}
|
|
|
|
hostOptions.PortBindings[nat.Port(F.ToString(port, "/udp"))] = []nat.PortBinding{
|
|
|
|
{HostPort: F.ToString(port), HostIP: "0.0.0.0"},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dockerContainer, err := dockerClient.ContainerCreate(context.Background(), &containerOptions, &hostOptions, nil, nil, "")
|
|
|
|
require.NoError(t, err)
|
|
|
|
t.Cleanup(func() {
|
|
|
|
cleanContainer(dockerContainer.ID)
|
|
|
|
})
|
2022-07-18 10:50:19 +00:00
|
|
|
|
2022-07-08 16:01:23 +00:00
|
|
|
require.NoError(t, dockerClient.ContainerStart(context.Background(), dockerContainer.ID, types.ContainerStartOptions{}))
|
2022-07-18 10:50:19 +00:00
|
|
|
|
|
|
|
if writeStdin {
|
|
|
|
stdinAttach, err := dockerClient.ContainerAttach(context.Background(), dockerContainer.ID, types.ContainerAttachOptions{
|
|
|
|
Stdin: writeStdin,
|
|
|
|
Stream: true,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
_, err = stdinAttach.Conn.Write(options.Stdin)
|
|
|
|
require.NoError(t, err)
|
|
|
|
stdinAttach.Close()
|
|
|
|
}
|
|
|
|
|
2022-07-08 16:01:23 +00:00
|
|
|
/*attach, err := dockerClient.ContainerAttach(context.Background(), dockerContainer.ID, types.ContainerAttachOptions{
|
2022-07-18 10:50:19 +00:00
|
|
|
Stdout: true,
|
|
|
|
Stderr: true,
|
|
|
|
Logs: true,
|
|
|
|
Stream: true,
|
2022-07-08 16:01:23 +00:00
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
go func() {
|
2022-07-18 10:50:19 +00:00
|
|
|
stdcopy.StdCopy(os.Stderr, os.Stderr, attach.Reader)
|
2022-07-08 16:01:23 +00:00
|
|
|
}()*/
|
2022-07-10 06:22:28 +00:00
|
|
|
time.Sleep(time.Second)
|
2022-07-08 16:01:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func cleanContainer(id string) error {
|
|
|
|
dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer dockerClient.Close()
|
|
|
|
return dockerClient.ContainerRemove(context.Background(), id, types.ContainerRemoveOptions{Force: true})
|
|
|
|
}
|