66 lines
1.5 KiB
Go
66 lines
1.5 KiB
Go
package docker
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
|
|
cerrdefs "github.com/containerd/errdefs"
|
|
"github.com/docker/docker/client"
|
|
)
|
|
|
|
var windowsAbsolutePathPrefix = regexp.MustCompile(`^([A-Za-z]:[\\/]|\\\\)`)
|
|
|
|
type MountDescriptor struct {
|
|
Type string
|
|
Driver string
|
|
DriverOpts map[string]string
|
|
}
|
|
|
|
func IsBindMount(m MountDescriptor) bool {
|
|
if strings.EqualFold(m.Type, "bind") || strings.EqualFold(m.Type, "npipe") {
|
|
return true
|
|
}
|
|
|
|
isLocalDriver := m.Driver == "" || strings.EqualFold(m.Driver, "local")
|
|
|
|
for key, value := range m.DriverOpts {
|
|
if strings.EqualFold(key, "type") && strings.EqualFold(value, "bind") {
|
|
return true
|
|
}
|
|
|
|
if strings.EqualFold(key, "o") {
|
|
for token := range strings.SplitSeq(value, ",") {
|
|
token = strings.TrimSpace(token)
|
|
if strings.EqualFold(token, "bind") || strings.EqualFold(token, "rbind") {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
if isLocalDriver && strings.EqualFold(key, "device") && value != "" {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func IsBindPath(bind string) bool {
|
|
return strings.HasPrefix(bind, "/") || windowsAbsolutePathPrefix.MatchString(bind)
|
|
}
|
|
|
|
func InspectVolumeIsBindMount(ctx context.Context, cli *client.Client, volumeName string) (bool, error) {
|
|
vol, err := cli.VolumeInspect(ctx, volumeName)
|
|
if err != nil {
|
|
if cerrdefs.IsNotFound(err) {
|
|
return false, nil
|
|
}
|
|
|
|
return false, fmt.Errorf("failed to inspect volume %q: %w", volumeName, err)
|
|
}
|
|
|
|
return IsBindMount(MountDescriptor{Driver: vol.Driver, DriverOpts: vol.Options}), nil
|
|
}
|