79 lines
1.7 KiB
Go
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)
|
|
}
|