github.com/chenbh/concourse/v6@v6.4.2/worker/runtime/libcontainerd/client.go (about) 1 package libcontainerd 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/containerd/containerd" 9 "github.com/opencontainers/runtime-spec/specs-go" 10 ) 11 12 //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . Client 13 //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 github.com/containerd/containerd.Container 14 //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 github.com/containerd/containerd.Task 15 //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 github.com/containerd/containerd.Process 16 //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 github.com/containerd/containerd/cio.IO 17 18 // Client represents the minimum interface used to communicate with containerd 19 // to manage containers. 20 // 21 type Client interface { 22 23 // Init provides the initialization of internal structures necessary by 24 // the client, e.g., instantiation of the gRPC client. 25 // 26 Init() (err error) 27 28 // Version queries containerd's version service in order to verify 29 // connectivity. 30 // 31 Version(ctx context.Context) (err error) 32 33 // Stop deallocates any initialization performed by `Init()` and 34 // subsequent calls to methods of this interface. 35 // 36 Stop() (err error) 37 38 // NewContainer creates a container in containerd. 39 // 40 NewContainer( 41 ctx context.Context, 42 id string, 43 labels map[string]string, 44 oci *specs.Spec, 45 ) ( 46 container containerd.Container, err error, 47 ) 48 49 // Containers lists containers available in containerd matching a given 50 // labelset. 51 // 52 Containers( 53 ctx context.Context, 54 labels ...string, 55 ) ( 56 containers []containerd.Container, err error, 57 ) 58 59 // GetContainer retrieves a created container that matches the specified handle. 60 // 61 GetContainer( 62 ctx context.Context, 63 handle string, 64 ) ( 65 container containerd.Container, err error, 66 ) 67 68 // Destroy stops any running tasks on a container and removes the container. 69 // If a task cannot be stopped gracefully, it will be forcefully stopped after 70 // a timeout period (default 10 seconds). 71 // 72 Destroy(ctx context.Context, handle string) error 73 } 74 75 type client struct { 76 addr string 77 namespace string 78 requestTimeout time.Duration 79 80 containerd *containerd.Client 81 } 82 83 var _ Client = (*client)(nil) 84 85 func New(addr, namespace string, requestTimeout time.Duration) *client { 86 return &client{ 87 addr: addr, 88 namespace: namespace, 89 requestTimeout: requestTimeout, 90 } 91 } 92 93 func (c *client) Init() (err error) { 94 c.containerd, err = containerd.New( 95 c.addr, 96 containerd.WithDefaultNamespace(c.namespace), 97 ) 98 if err != nil { 99 err = fmt.Errorf("failed to connect to addr %s: %w", c.addr, err) 100 return 101 } 102 103 return 104 } 105 106 func (c *client) Stop() (err error) { 107 if c.containerd == nil { 108 return 109 } 110 111 err = c.containerd.Close() 112 return 113 } 114 115 func (c *client) NewContainer( 116 ctx context.Context, id string, labels map[string]string, oci *specs.Spec, 117 ) ( 118 containerd.Container, error, 119 ) { 120 ctx, cancel := context.WithTimeout(ctx, c.requestTimeout) 121 defer cancel() 122 123 return c.containerd.NewContainer(ctx, id, 124 containerd.WithSpec(oci), 125 containerd.WithContainerLabels(labels), 126 ) 127 } 128 129 func (c *client) Containers( 130 ctx context.Context, labels ...string, 131 ) ( 132 []containerd.Container, error, 133 ) { 134 ctx, cancel := context.WithTimeout(ctx, c.requestTimeout) 135 defer cancel() 136 137 return c.containerd.Containers(ctx, labels...) 138 } 139 140 func (c *client) GetContainer(ctx context.Context, handle string) (containerd.Container, error) { 141 ctx, cancel := context.WithTimeout(ctx, c.requestTimeout) 142 defer cancel() 143 144 cont, err := c.containerd.LoadContainer(ctx, handle) 145 if err != nil { 146 return nil, err 147 } 148 149 return &container{ 150 requestTimeout: c.requestTimeout, 151 container: cont, 152 }, nil 153 } 154 155 func (c *client) Version(ctx context.Context) (err error) { 156 ctx, cancel := context.WithTimeout(ctx, c.requestTimeout) 157 defer cancel() 158 159 _, err = c.containerd.Version(ctx) 160 return 161 } 162 func (c *client) Destroy(ctx context.Context, handle string) error { 163 ctx, cancel := context.WithTimeout(ctx, c.requestTimeout) 164 defer cancel() 165 166 container, err := c.GetContainer(ctx, handle) 167 if err != nil { 168 return err 169 } 170 171 return container.Delete(ctx) 172 }