github.com/tommi2day/gomodules@v1.13.2-0.20240423190010-b7d55d252a27/maillib/mail_docker_test.go (about)

     1  package maillib
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"os"
     7  	"time"
     8  
     9  	"github.com/tommi2day/gomodules/common"
    10  	"github.com/tommi2day/gomodules/test"
    11  
    12  	"github.com/ory/dockertest/v3"
    13  	"github.com/ory/dockertest/v3/docker"
    14  )
    15  
    16  const mailRepo = "docker.io/mailserver/docker-mailserver"
    17  const mailRepoTag = "13.2.0"
    18  const smtpPort = 31025
    19  const imapPort = 31143
    20  const sslPort = 31465
    21  const tlsPort = 31587
    22  const imapsPort = 31993
    23  const containerTimeout = 120
    24  
    25  var mailContainerName string
    26  var mailContainer *dockertest.Resource
    27  var mailServer = "127.0.0.1"
    28  
    29  // prepareContainer create an Oracle Docker Container
    30  func prepareMailContainer() (container *dockertest.Resource, err error) {
    31  	if os.Getenv("SKIP_MAIL") != "" {
    32  		err = fmt.Errorf("skipping Mail Container in CI environment")
    33  		return
    34  	}
    35  	// align hostname in CI
    36  	host := os.Getenv("MAIL_HOST")
    37  	if host != "" {
    38  		mailServer = host
    39  	}
    40  	mailContainerName = os.Getenv("MAIL_CONTAINER_NAME")
    41  	if mailContainerName == "" {
    42  		mailContainerName = "mailserver"
    43  	}
    44  	pool, err := common.GetDockerPool()
    45  	if err != nil {
    46  		err = fmt.Errorf("cannot attach to docker: %v", err)
    47  		return
    48  	}
    49  
    50  	vendorImagePrefix := os.Getenv("VENDOR_IMAGE_PREFIX")
    51  	repoString := vendorImagePrefix + mailRepo
    52  	fmt.Printf("Try to start docker container for %s:%s\n", repoString, mailRepoTag)
    53  	container, err = pool.RunWithOptions(&dockertest.RunOptions{
    54  		Repository: repoString,
    55  		Tag:        mailRepoTag,
    56  
    57  		Env: []string{
    58  			"LOG_LEVEL=debug",
    59  			"ONE_DIR=1",
    60  			"POSTFIX_INET_PROTOCOLS=ipv4",
    61  			"PERMIT_DOCKER=connected-networks",
    62  			"ENABLE_OPENDKIM=0",
    63  			"ENABLE_OPENDMARC=0",
    64  			"ENABLE_AMAVIS=0",
    65  			"SSL_TYPE=manual",
    66  			"SSL_CERT_PATH=/tmp/custom-certs/" + mailHostname + "-full.crt",
    67  			"SSL_KEY_PATH=/tmp/custom-certs/" + mailHostname + ".key",
    68  		},
    69  		Hostname: mailHostname,
    70  		Name:     mailContainerName,
    71  		Mounts: []string{
    72  			test.TestDir + "/docker/mail/config:/tmp/docker-mailserver/",
    73  			test.TestDir + "/docker/mail/ssl:/tmp/custom-certs/:ro",
    74  		},
    75  		/*
    76  			CapAdd: []string{
    77  				"NET_ADMIN",
    78  			},
    79  		*/
    80  		ExposedPorts: []string{"25", "143", "465", "587", "993"},
    81  		PortBindings: map[docker.Port][]docker.PortBinding{
    82  			"25": {
    83  				{HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", smtpPort)},
    84  			},
    85  			"143": {
    86  				{HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", imapPort)},
    87  			},
    88  			"465": {
    89  				{HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", sslPort)},
    90  			},
    91  			"587": {
    92  				{HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", tlsPort)},
    93  			},
    94  			"993": {
    95  				{HostIP: "0.0.0.0", HostPort: fmt.Sprintf("%d", imapsPort)},
    96  			},
    97  		},
    98  	}, func(config *docker.HostConfig) {
    99  		// set AutoRemove to true so that stopped container goes away by itself
   100  		config.AutoRemove = true
   101  		config.RestartPolicy = docker.RestartPolicy{Name: "no"}
   102  	})
   103  
   104  	if err != nil {
   105  		err = fmt.Errorf("error starting mailserver docker container: %v", err)
   106  		return
   107  	}
   108  
   109  	pool.MaxWait = containerTimeout * time.Second
   110  	fmt.Printf("Wait to successfully connect to Mailserver with %s:%d (max %ds)...\n", mailServer, tlsPort, containerTimeout)
   111  	start := time.Now()
   112  	var c net.Conn
   113  	if err = pool.Retry(func() error {
   114  		c, err = net.Dial("tcp", fmt.Sprintf("%s:%d", mailServer, tlsPort))
   115  		if err != nil {
   116  			fmt.Printf("Err:%s\n", err)
   117  		}
   118  		return err
   119  	}); err != nil {
   120  		fmt.Printf("Could not connect to Mail Container: %s", err)
   121  		return
   122  	}
   123  	_ = c.Close()
   124  
   125  	// show env
   126  	// cmdout, _, err=execCmd(container, []string{"bash", "-c", "env|sort"})
   127  
   128  	// wait 20s to init container
   129  	time.Sleep(20 * time.Second)
   130  	elapsed := time.Since(start)
   131  	fmt.Printf("Mail Container is available after %s\n", elapsed.Round(time.Millisecond))
   132  
   133  	// test main.cf
   134  	cmdout := ""
   135  	cmd := []string{"/bin/ls", "-l", "/etc/postfix/*"}
   136  	cmdout, _, err = common.ExecDockerCmd(container, cmd)
   137  	if err != nil {
   138  		fmt.Printf("Exec Error %s", err)
   139  	} else {
   140  		fmt.Printf("Cmd:%v\n %s", cmd, cmdout)
   141  	}
   142  	err = nil
   143  	return
   144  }