buildr/internal/containers/container.go
Peter 1261932bdc
All checks were successful
continuous-integration/drone/push Build is passing
refactor: apply golangci-lint findings
2023-06-22 19:16:00 +02:00

79 lines
1.7 KiB
Go

package containers
import (
"archive/tar"
"context"
"errors"
"fmt"
"sync"
"github.com/docker/docker/api/types"
"github.com/docker/go-connections/nat"
)
var (
_ Container = (*containerRef)(nil)
ErrNoMappedPort = errors.New("no mapped port found")
)
type containerRef struct {
info types.ContainerJSON
shutdowner Shutdowner
client Client
resourceName string
containerID string
networkID string
inspectOnce sync.Once
}
func (c *containerRef) CopyFileFromContainer(ctx context.Context, path string, f CopyContainerFileHandler) (err error) {
reader, _, err := c.client.CopyFromContainer(ctx, c.containerID, path)
if err != nil {
return err
}
defer func() {
err = errors.Join(err, reader.Close())
}()
tarReader := tar.NewReader(reader)
var header *tar.Header
for header, err = tarReader.Next(); err == nil; header, err = tarReader.Next() {
if err := f(header, tarReader); err != nil {
return err
}
}
return nil
}
func (c *containerRef) NetworkID() string {
return c.networkID
}
func (c *containerRef) ID() string {
return c.containerID
}
func (c *containerRef) MappedPort(ctx context.Context, port nat.Port) (hostIP, hostPort string, err error) {
c.inspectOnce.Do(func() {
c.info, err = c.client.ContainerInspect(ctx, c.containerID)
})
if err != nil {
return "", "", err
}
binding, ok := c.info.NetworkSettings.Ports[port]
if !ok || len(binding) == 0 {
return "", "", fmt.Errorf("%w: %s", ErrNoMappedPort, port.Port())
}
return binding[0].HostIP, binding[0].HostPort, nil
}
func (c *containerRef) Shutdown(ctx context.Context) error {
return c.shutdowner.ShutdownContainer(ctx, c)
}