Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
henryse committed Mar 14, 2024
2 parents c70971d + e367dfb commit ca2e261
Show file tree
Hide file tree
Showing 20 changed files with 215 additions and 1,121 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v3.0.2
uses: actions/checkout@v4.1.2

- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3

- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
55 changes: 35 additions & 20 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,29 @@ jobs:
- freebsd
- linux
- windows
goarch:
- amd64
- arm64

name: cross-compilation (GOOS=${{ matrix.goos }})
name: cross-compilation (GOOS=${{ matrix.goos }}, GOARCH=${{ matrix.goarch }})
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3.3.0
- uses: actions/checkout@v4.1.2
- uses: actions/setup-go@v5.0.0
with:
go-version: 1.19

- uses: actions/checkout@v3.0.2
go-version: "1.x"

- run: go build
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}

test:
strategy:
matrix:
go_version:
- 1.18
- 1.19
go-version:
- "1.21"
- "1.22"
os:
- macos
- ubuntu
Expand All @@ -49,35 +52,47 @@ jobs:
- os: macos
goarch: 386

name: test (${{ matrix.os }}/go-${{ matrix.go_version }}/${{ matrix.goarch }})
name: tests (${{ matrix.os }}/go-${{ matrix.go-version }}/${{ matrix.goarch }})
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/setup-go@v3.3.0
- uses: actions/checkout@v4.1.2
- uses: actions/setup-go@v5.0.0
id: go
with:
go-version: ${{ matrix.go_version }}

- uses: actions/checkout@v3.0.2
go-version: ${{ matrix.go-version }}

- run: go mod download

- run: make staticcheck
if: matrix.go_version == '1.19'
if: matrix.go-version == '1.21'

- run: make gotest
env:
GOARCH: ${{ matrix.goarch }}
GOPROXY: off

integration-tests:
strategy:
matrix:
os:
- ubuntu
- windows

name: integration tests (${{ matrix.os }})
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v4.1.2

- uses: actions/setup-go@v5.0.0
id: go
with:
go-version: "1.x"

- run: make integration
if: matrix.os != 'macos' && matrix.goarch == 'amd64'
env:
GOFLAGS: -mod=readonly

lint:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.0.2

- uses: golangci/golangci-lint-action@v3.2.0
- uses: actions/checkout@v4.1.2
- uses: golangci/golangci-lint-action@v4.0.0
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ implemented/merged.
For new projects, using the official SDK is probably more appropriate as
go-dockerclient lags behind the official SDK.

When using the official SDK, keep in mind that because of how the its
dependencies are organized, you may need some extra steps in order to be able
to import it in your projects (see
[#784](https://github.com/henryse/go-dockerclient/issues/784) and
[moby/moby#28269](https://github.com/moby/moby/issues/28269)).

## Example

```go
Expand Down
13 changes: 12 additions & 1 deletion auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package docker

import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"errors"
Expand Down Expand Up @@ -262,11 +263,21 @@ type AuthStatus struct {
//
// See https://goo.gl/6nsZkH for more details.
func (c *Client) AuthCheck(conf *AuthConfiguration) (AuthStatus, error) {
return c.AuthCheckWithContext(conf, context.TODO())
}

// AuthCheckWithContext validates the given credentials. It returns nil if successful. The context object
// can be used to cancel the request.
//
// For Docker API versions >= 1.23, the AuthStatus struct will be populated, otherwise it will be empty.
//
// See https://goo.gl/6nsZkH for more details.
func (c *Client) AuthCheckWithContext(conf *AuthConfiguration, ctx context.Context) (AuthStatus, error) {
var authStatus AuthStatus
if conf == nil {
return authStatus, errors.New("conf is nil")
}
resp, err := c.do(http.MethodPost, "/auth", doOptions{data: conf})
resp, err := c.do(http.MethodPost, "/auth", doOptions{data: conf, context: ctx})
if err != nil {
return authStatus, err
}
Expand Down
16 changes: 8 additions & 8 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ func (c *Client) getServerAPIVersionString() (version string, err error) {
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("received unexpected status %d while trying to retrieve the server version", resp.StatusCode)
}
var versionResponse map[string]interface{}
var versionResponse map[string]any
if err := json.NewDecoder(resp.Body).Decode(&versionResponse); err != nil {
return "", err
}
Expand All @@ -427,7 +427,7 @@ func (c *Client) getServerAPIVersionString() (version string, err error) {
}

type doOptions struct {
data interface{}
data any
forceJSON bool
headers map[string]string
context context.Context
Expand Down Expand Up @@ -485,7 +485,7 @@ func (c *Client) do(method, path string, doOptions doOptions) (*http.Response, e

return nil, chooseError(ctx, err)
}
if resp.StatusCode < 200 || resp.StatusCode >= 400 {
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusBadRequest {
return nil, newError(resp)
}
return resp, nil
Expand All @@ -511,7 +511,7 @@ type streamOptions struct {
func chooseError(ctx context.Context, err error) error {
select {
case <-ctx.Done():
return ctx.Err()
return context.Cause(ctx)
default:
return err
}
Expand Down Expand Up @@ -710,7 +710,7 @@ type hijackOptions struct {
in io.Reader
stdout io.Writer
stderr io.Writer
data interface{}
data any
}

// CloseWaiter is an interface with methods for closing the underlying resource
Expand Down Expand Up @@ -873,7 +873,7 @@ func (c *Client) getURL(path string) string {
return fmt.Sprintf("%s%s", urlStr, path)
}

func (c *Client) getPath(basepath string, opts interface{}) (string, error) {
func (c *Client) getPath(basepath string, opts any) (string, error) {
queryStr, requiredAPIVersion := queryStringVersion(opts)
return c.pathVersionCheck(basepath, queryStr, requiredAPIVersion)
}
Expand Down Expand Up @@ -912,7 +912,7 @@ func (c *Client) getFakeNativeURL(path string) string {
return fmt.Sprintf("%s%s", urlStr, path)
}

func queryStringVersion(opts interface{}) (string, APIVersion) {
func queryStringVersion(opts any) (string, APIVersion) {
if opts == nil {
return "", nil
}
Expand Down Expand Up @@ -951,7 +951,7 @@ func queryStringVersion(opts interface{}) (string, APIVersion) {
return items.Encode(), apiVersion
}

func queryString(opts interface{}) string {
func queryString(opts any) string {
s, _ := queryStringVersion(opts)
return s
}
Expand Down
6 changes: 3 additions & 3 deletions client_stress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"net/http/httptest"
"os"
"reflect"
"sort"
"slices"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -126,8 +126,8 @@ func TestClientDoConcurrentStress(t *testing.T) {
for _, r := range reqs {
reqPaths = append(reqPaths, r.Method+r.URL.Path)
}
sort.Strings(paths)
sort.Strings(reqPaths)
slices.Sort(paths)
slices.Sort(reqPaths)
if !reflect.DeepEqual(reqPaths, paths) {
t.Fatalf("expected server request paths to equal %v, got: %v", paths, reqPaths)
}
Expand Down
14 changes: 6 additions & 8 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,10 @@ func TestNewVersionedClient(t *testing.T) {
}

func TestNewVersionedClientFromEnv(t *testing.T) {
t.Parallel()
endpoint := "tcp://localhost:2376"
endpointURL := "http://localhost:2376"
os.Setenv("DOCKER_HOST", endpoint)
os.Setenv("DOCKER_TLS_VERIFY", "")
t.Setenv("DOCKER_HOST", endpoint)
t.Setenv("DOCKER_TLS_VERIFY", "")
client, err := NewVersionedClientFromEnv("1.12")
if err != nil {
t.Fatal(err)
Expand All @@ -120,13 +119,12 @@ func TestNewVersionedClientFromEnv(t *testing.T) {
}

func TestNewVersionedClientFromEnvTLS(t *testing.T) {
t.Parallel()
endpoint := "tcp://localhost:2376"
endpointURL := "https://localhost:2376"
base, _ := os.Getwd()
os.Setenv("DOCKER_CERT_PATH", filepath.Join(base, "/testing/data/"))
os.Setenv("DOCKER_HOST", endpoint)
os.Setenv("DOCKER_TLS_VERIFY", "1")
t.Setenv("DOCKER_CERT_PATH", filepath.Join(base, "/testing/data/"))
t.Setenv("DOCKER_HOST", endpoint)
t.Setenv("DOCKER_TLS_VERIFY", "1")
client, err := NewVersionedClientFromEnv("1.12")
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -367,7 +365,7 @@ func TestQueryString(t *testing.T) {
f32QueryString := fmt.Sprintf("w=%s&x=10&y=10.35", strconv.FormatFloat(float64(v), 'f', -1, 64))
jsonPerson := url.QueryEscape(`{"Name":"gopher","age":4}`)
tests := []struct {
input interface{}
input any
want string
wantAPI APIVersion
}{
Expand Down
1 change: 1 addition & 0 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ type HostConfig struct {
PublishAllPorts bool `json:"PublishAllPorts,omitempty" yaml:"PublishAllPorts,omitempty" toml:"PublishAllPorts,omitempty"`
ReadonlyRootfs bool `json:"ReadonlyRootfs,omitempty" yaml:"ReadonlyRootfs,omitempty" toml:"ReadonlyRootfs,omitempty"`
AutoRemove bool `json:"AutoRemove,omitempty" yaml:"AutoRemove,omitempty" toml:"AutoRemove,omitempty"`
Annotations map[string]string `json:"Annotations,omitempty" yaml:"Annotations,omitempty" toml:"Annotations,omitempty"`
}

// NetworkingConfig represents the container's networking configuration for each of its interfaces
Expand Down
1 change: 1 addition & 0 deletions container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var ErrContainerAlreadyExists = errors.New("container already exists")
// See https://goo.gl/tyzwVM for more details.
type CreateContainerOptions struct {
Name string
Platform string
Config *Config `qs:"-"`
HostConfig *HostConfig `qs:"-"`
NetworkingConfig *NetworkingConfig `qs:"-"`
Expand Down
19 changes: 18 additions & 1 deletion container_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestCreateContainerWithHostConfig(t *testing.T) {
t.Fatal(err)
}
req := fakeRT.requests[0]
var gotBody map[string]interface{}
var gotBody map[string]any
err = json.NewDecoder(req.Body).Decode(&gotBody)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -127,3 +127,20 @@ func TestPassingNameOptToCreateContainerReturnsItInContainer(t *testing.T) {
t.Errorf("Container name expected to be TestCreateContainer, was %s", container.Name)
}
}

func TestPassingPlatformOpt(t *testing.T) {
t.Parallel()
fakeRT := &FakeRoundTripper{message: "{}", status: http.StatusOK}
client := newTestClient(fakeRT)
config := Config{}
opts := CreateContainerOptions{Name: "TestCreateContainerWithPlatform", Platform: "darwin/arm64", Config: &config}
_, err := client.CreateContainer(opts)
if err != nil {
t.Fatal(err)
}
req := fakeRT.requests[0]
gotQs := req.URL.Query().Get("platform")
if gotQs != "darwin/arm64" {
t.Errorf("CreateContainer: missing expected platform query string (%v)", req.URL.RequestURI())
}
}
8 changes: 4 additions & 4 deletions env.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (env *Env) SetInt64(key string, value int64) {
// GetJSON unmarshals the value of the provided key in the provided iface.
//
// iface is a value that can be provided to the json.Unmarshal function.
func (env *Env) GetJSON(key string, iface interface{}) error {
func (env *Env) GetJSON(key string, iface any) error {
sval := env.Get(key)
if sval == "" {
return nil
Expand All @@ -89,7 +89,7 @@ func (env *Env) GetJSON(key string, iface interface{}) error {

// SetJSON marshals the given value to JSON format and stores it using the
// provided key.
func (env *Env) SetJSON(key string, value interface{}) error {
func (env *Env) SetJSON(key string, value any) error {
sval, err := json.Marshal(value)
if err != nil {
return err
Expand Down Expand Up @@ -131,7 +131,7 @@ func (env *Env) Set(key, value string) {
//
// If `src` cannot be decoded as a json dictionary, an error is returned.
func (env *Env) Decode(src io.Reader) error {
m := make(map[string]interface{})
m := make(map[string]any)
if err := json.NewDecoder(src).Decode(&m); err != nil {
return err
}
Expand All @@ -142,7 +142,7 @@ func (env *Env) Decode(src io.Reader) error {
}

// SetAuto will try to define the Set* method to call based on the given value.
func (env *Env) SetAuto(key string, value interface{}) {
func (env *Env) SetAuto(key string, value any) {
if fval, ok := value.(float64); ok {
env.SetInt64(key, int64(fval))
} else if sval, ok := value.(string); ok {
Expand Down

0 comments on commit ca2e261

Please sign in to comment.