mirror of
https://github.com/scroll-tech/scroll.git
synced 2026-01-22 04:18:07 -05:00
121 lines
2.4 KiB
Go
121 lines
2.4 KiB
Go
package docker
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/docker/docker/api/types"
|
|
|
|
"scroll-tech/common/cmd"
|
|
"scroll-tech/common/utils"
|
|
)
|
|
|
|
// ImgRedis the redis image.
|
|
type ImgRedis struct {
|
|
image string
|
|
name string
|
|
id string
|
|
|
|
port int
|
|
running bool
|
|
cmd *cmd.Cmd
|
|
}
|
|
|
|
// NewImgRedis return redis img instance.
|
|
func NewImgRedis(t *testing.T, image string, port int) ImgInstance {
|
|
img := &ImgRedis{
|
|
image: image,
|
|
name: fmt.Sprintf("%s-%d", image, time.Now().Nanosecond()),
|
|
port: port,
|
|
}
|
|
img.cmd = cmd.NewCmd(t, img.name, img.prepare()...)
|
|
return img
|
|
}
|
|
|
|
// Start run image and check if it is running healthily.
|
|
func (r *ImgRedis) Start() error {
|
|
id := GetContainerID(r.name)
|
|
if id != "" {
|
|
return fmt.Errorf("container already exist, name: %s", r.name)
|
|
}
|
|
// Add check status function.
|
|
keyword := "Ready to accept connections"
|
|
okCh := make(chan struct{}, 1)
|
|
r.cmd.RegistFunc(keyword, func(buf string) {
|
|
if strings.Contains(buf, keyword) {
|
|
select {
|
|
case okCh <- struct{}{}:
|
|
default:
|
|
return
|
|
}
|
|
}
|
|
})
|
|
defer r.cmd.UnRegistFunc(keyword)
|
|
|
|
// Start redis.
|
|
r.cmd.RunCmd(true)
|
|
|
|
// Wait result of keyword.
|
|
select {
|
|
case <-okCh:
|
|
utils.TryTimes(3, func() bool {
|
|
r.id = GetContainerID(r.name)
|
|
return r.id != ""
|
|
})
|
|
case <-time.After(time.Second * 10):
|
|
}
|
|
|
|
// Set redis status.
|
|
r.running = r.id != ""
|
|
if !r.running {
|
|
_ = r.Stop()
|
|
return fmt.Errorf("failed to start image: %s", r.image)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Stop the docker container.
|
|
func (r *ImgRedis) Stop() error {
|
|
if !r.running {
|
|
return nil
|
|
}
|
|
r.running = false
|
|
ctx := context.Background()
|
|
id := GetContainerID(r.name)
|
|
if id != "" {
|
|
timeout := time.Second * 3
|
|
if err := cli.ContainerStop(ctx, id, &timeout); err != nil {
|
|
return err
|
|
}
|
|
r.id = id
|
|
}
|
|
// remove the stopped container.
|
|
return cli.ContainerRemove(ctx, r.id, types.ContainerRemoveOptions{})
|
|
}
|
|
|
|
// Endpoint return the connection endpoint.
|
|
func (r *ImgRedis) Endpoint() string {
|
|
if !r.running {
|
|
return ""
|
|
}
|
|
port := 6379
|
|
if r.port != 0 {
|
|
port = r.port
|
|
}
|
|
return fmt.Sprintf("redis://default:redistest@localhost:%d/0", port)
|
|
}
|
|
|
|
// docker run --name redis-xxx -p randomport:6379 --requirepass "redistest" redis
|
|
func (r *ImgRedis) prepare() []string {
|
|
cmds := []string{"docker", "run", "--name", r.name}
|
|
var ports []string
|
|
if r.port != 0 {
|
|
ports = append(ports, []string{"-p", strconv.Itoa(r.port) + ":6379"}...)
|
|
}
|
|
return append(append(cmds, ports...), r.image)
|
|
}
|