github.com/olljanat/moby@v1.13.1/cli/command/idresolver/idresolver.go (about)

     1  package idresolver
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"golang.org/x/net/context"
     7  
     8  	"github.com/docker/docker/api/types/swarm"
     9  	"github.com/docker/docker/client"
    10  	"github.com/docker/docker/pkg/stringid"
    11  )
    12  
    13  // IDResolver provides ID to Name resolution.
    14  type IDResolver struct {
    15  	client    client.APIClient
    16  	noResolve bool
    17  	cache     map[string]string
    18  }
    19  
    20  // New creates a new IDResolver.
    21  func New(client client.APIClient, noResolve bool) *IDResolver {
    22  	return &IDResolver{
    23  		client:    client,
    24  		noResolve: noResolve,
    25  		cache:     make(map[string]string),
    26  	}
    27  }
    28  
    29  func (r *IDResolver) get(ctx context.Context, t interface{}, id string) (string, error) {
    30  	switch t := t.(type) {
    31  	case swarm.Node:
    32  		node, _, err := r.client.NodeInspectWithRaw(ctx, id)
    33  		if err != nil {
    34  			return id, nil
    35  		}
    36  		if node.Spec.Annotations.Name != "" {
    37  			return node.Spec.Annotations.Name, nil
    38  		}
    39  		if node.Description.Hostname != "" {
    40  			return node.Description.Hostname, nil
    41  		}
    42  		return id, nil
    43  	case swarm.Service:
    44  		service, _, err := r.client.ServiceInspectWithRaw(ctx, id)
    45  		if err != nil {
    46  			return id, nil
    47  		}
    48  		return service.Spec.Annotations.Name, nil
    49  	case swarm.Task:
    50  		// If the caller passes the full task there's no need to do a lookup.
    51  		if t.ID == "" {
    52  			var err error
    53  
    54  			t, _, err = r.client.TaskInspectWithRaw(ctx, id)
    55  			if err != nil {
    56  				return id, nil
    57  			}
    58  		}
    59  		taskID := stringid.TruncateID(t.ID)
    60  		if t.ServiceID == "" {
    61  			return taskID, nil
    62  		}
    63  		service, err := r.Resolve(ctx, swarm.Service{}, t.ServiceID)
    64  		if err != nil {
    65  			return "", err
    66  		}
    67  		return fmt.Sprintf("%s.%d.%s", service, t.Slot, taskID), nil
    68  	default:
    69  		return "", fmt.Errorf("unsupported type")
    70  	}
    71  
    72  }
    73  
    74  // Resolve will attempt to resolve an ID to a Name by querying the manager.
    75  // Results are stored into a cache.
    76  // If the `-n` flag is used in the command-line, resolution is disabled.
    77  func (r *IDResolver) Resolve(ctx context.Context, t interface{}, id string) (string, error) {
    78  	if r.noResolve {
    79  		return id, nil
    80  	}
    81  	if name, ok := r.cache[id]; ok {
    82  		return name, nil
    83  	}
    84  	name, err := r.get(ctx, t, id)
    85  	if err != nil {
    86  		return "", err
    87  	}
    88  	r.cache[id] = name
    89  	return name, nil
    90  }