docker

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2023 License: MIT Imports: 4 Imported by: 6

README

An experimental Docker client

This is an experimental client for Docker. Most of the low-level details are finalized and just requires implementing the API calls on top of that.

The goals of this project are:

  1. Abstract away connection semantics - the official client is kind of broken in this regard, where abstractions for connection and transport protocol are co-mingled. This makes it difficult to, for instance, take advantage of HTTP/2 in the official client, or implement things like SSH forwarding (this exists in the official client, but with great effort).
  2. Semantic versioning - The official client is built such that it is very difficult to not make breaking changes when adding new things, therefore it is difficult to version semantically (without being at some insanely high and meaningless version).
  3. Easy to consume in go.mod - Traditionally the official client is... painful... to import, particularly with go modules. This is caused by a number of project level issues, such as (lack of) version tagging. We are trying to fix this upstream but we have to make certain not to break too much or introduce things that are not maintainable.
  4. Do not import from the upstream types -- the upstream repo has a lot of history, things move around, have lots of transitive dependencies, and in general is just slow to import due to that history. Instead we define the required types directly in this repo, even if it's only as a copy of the existing ones.
  5. Easy to reason about errors - You should be able to know exactly what kind of error was returned without having to muck around with the http response
  6. Integrate with your choice tracing/metrics frameworks

Usage

All client operations are dependent on a transport. Transports are defined in the transport package. You can implement your own, here is the interface:

// RequestOpt is as functional arguments to configure an HTTP request for a Doer.
type RequestOpt func(*http.Request) error

// Doer performs an http request for Client
// It is the Doer's responsibility to deal with setting the host details on
// the request
// It is expected that one Doer connects to one Docker instance.
type Doer interface {
	// Do typically performs a normal http request/response
	Do(ctx context.Context, method string, uri string, opts ...RequestOpt) (*http.Response, error)
	// DoRaw performs the request but passes along the response as a bi-directional stream
	DoRaw(ctx context.Context, method string, uri string, opts ...RequestOpt) (net.Conn, error)
}

Do is the main function to implement, it takes an HTTP method, a uri (e.g. /containers/json), and a lits of options for configuring an *http.Request (e.g. to add request headers, query params, etc.)

DoRaw is used only for endpoints that need to "hijack" the http connection (ie. drop all HTTP semantics and drop to a raw, bi-directional stream). This is used for container attach.

The package contains a default transport that you can use directly, or wrap, as well as helpers for creating it from DOCKER_HOST style connection strings.

Once you have a transport you can create a client:

// create a transport that connects over /var/run/docker.sock
tr, err := transport.DefaultUnixTransport()
if err != nil {
	panic(err)
}
client := NewClient(WithTransport(tr))

Or if you don't provide a transport, the default for the platform will be used.

Perform actions on a container:

s := client.ContainerService()
c, err := s.Create(ctx, container.WithCreateImage("busybox:latest"), container.WithCreateCmd("/bin/echo", "hello"))
if err != nil {
    // handle error
}

cStdout, err := c.StdoutPipe(ctx)
if err != nil {
    // handle error
}
defer cStdout.Close()

if err := c.Start(ctx); err != nil {
    // handle error
}

io.Copy(os.Stdout, cStdout)

if err := s.Remove(ctx, c.ID(), container.WithRemoveForce); err != nil {
    // handle error
}

Documentation

Overview

package docker provides a client for accessing the Docker API.

*Usage*

All client operations are dependent on a transport. Transports are defined in the transport package. You can implement your own, here is the interface:

// RequestOpt is as functional arguments to configure an HTTP request for a Doer.
type RequestOpt func(*http.Request) error

// Doer performs an http request for Client
// It is the Doer's responsibility to deal with setting the host details on
// the request
// It is expected that one Doer connects to one Docker instance.
type Doer interface {
	// Do typically performs a normal http request/response
	Do(ctx context.Context, method string, uri string, opts ...RequestOpt) (*http.Response, error)
	// DoRaw performs the request but passes along the response as a bi-directional stream
	DoRaw(ctx context.Context, method string, uri string, opts ...RequestOpt) (io.ReadWriteCloser, error)
}

Do is the main function to implement, it takes an HTTP method, a uri (e.g. /containers/json), and a lits of options for configuring an *http.Request (e.g. to add request headers, query params, etc.)

DoRaw is used only for endpoints that need to “hijack” the http connection (ie. drop all HTTP semantics and drop to a raw, bi-directional stream). This is used for container attach.

The package contains a default transport that you can use directly, or wrap, as well as helpers for creating it from DOCKER_HOST style connection strings.

Once you have a transport you can create a client:

// create a transport that connects over /var/run/docker.sock
tr, err := transport.DefaultUnixTransport()
if err != nil {
	panic(err)
}
client := NewClient(WithTransport(tr))

Or if you don’t provide a transport, the default for the platform will be used.

Perform actions on a container:

s := client.ContainerService()
c, err := s.Create(ctx, container.WithCreateImage("busybox:latest"), container.WithCreateCmd("/bin/echo", "hello"))
if err != nil {
		// handle error
}

cStdout, err := c.StdoutPipe(ctx)
if err != nil {
		// handle error
}
defer cStdout.Close()

if err := c.Start(ctx); err != nil {
		// handle error
}

io.Copy(os.Stdout, cStdout)

if err := s.Remove(ctx, c.ID(), container.WithRemoveForce); err != nil {
		// handle error
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the main docker client Create one with `NewClient`

func NewClient

func NewClient(opts ...NewClientOption) *Client

NewClient creates a new docker client You can pass in options using functional arguments.

If no transport is provided as an option, the default transport will be used.

You probably want to set an API version for the client to use here. See `NewClientConfig` for available options

func (*Client) ContainerService

func (c *Client) ContainerService() *container.Service

ContainerService provides access to container functionaliaty, such as create, delete, start, stop, etc.

func (*Client) ImageService

func (c *Client) ImageService() *image.Service

ImageService provides access to image functionality, such as create, list.

func (*Client) SystemService

func (c *Client) SystemService() *system.Service

SystemService creates a new system service from the client.

func (*Client) Transport added in v0.1.1

func (c *Client) Transport() transport.Doer

Transport returns the transport used by the client.

type NewClientConfig

type NewClientConfig struct {
	// Transport is the communication method for reaching a docker engine instance.
	// You can implement your own transport, or use the ones provided in the transport package.
	// If this is unset, the default transport will be used (unix socket connected to /var/run/docker.sock).
	Transport transport.Doer
}

NewClientConfig is the list of options for configuring a new docker client

type NewClientOption

type NewClientOption func(*NewClientConfig)

func WithTransport

func WithTransport(tr transport.Doer) NewClientOption

WithTransport is a NewClientOption that sets the transport to be used for the client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL