Skip to content

Commit

Permalink
Merge pull request #1398 from vania-pooh/master
Browse files Browse the repository at this point in the history
Docker API 1.44
  • Loading branch information
vania-pooh authored Jan 25, 2024
2 parents 079fe2d + 6363e98 commit fd32287
Show file tree
Hide file tree
Showing 20 changed files with 297 additions and 150 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Setup Golang
uses: actions/setup-go@v3
with:
go-version: ~1.21.5
go-version: ~1.21.6

- uses: actions/cache@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Setup Golang
uses: actions/setup-go@v3
with:
go-version: ~1.21.5
go-version: ~1.21.6

- uses: actions/cache@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: Setup Golang
uses: actions/setup-go@v3
with:
go-version: ~1.21.5
go-version: ~1.21.6

- uses: actions/cache@v3
with:
Expand Down
2 changes: 2 additions & 0 deletions ci/build.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/bash

set -e

export GO111MODULE="on"
go install github.com/mitchellh/gox@latest # cross compile
CGO_ENABLED=0 gox -os "linux darwin windows" -arch "amd64" -osarch="darwin/arm64" -osarch="darwin/arm64" -osarch="linux/arm64" -osarch="windows/386" -output "dist/{{.Dir}}_{{.OS}}_{{.Arch}}" -ldflags "-X main.buildStamp=`date -u '+%Y-%m-%d_%I:%M:%S%p'` -X main.gitRevision=`git describe --tags || git rev-parse HEAD` -s -w"
4 changes: 3 additions & 1 deletion ci/test.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/bin/bash

set -e

export GO111MODULE="on"
go test -tags 's3 metadata' -v -race -coverprofile=coverage.txt -covermode=atomic -coverpkg github.com/aerokube/selenoid,github.com/aerokube/selenoid/session,github.com/aerokube/selenoid/config,github.com/aerokube/selenoid/protect,github.com/aerokube/selenoid/service,github.com/aerokube/selenoid/upload
go test -tags 's3 metadata' -v -race -coverprofile=coverage.txt -covermode=atomic -coverpkg github.com/aerokube/selenoid,github.com/aerokube/selenoid/session,github.com/aerokube/selenoid/config,github.com/aerokube/selenoid/protect,github.com/aerokube/selenoid/service,github.com/aerokube/selenoid/upload,github.com/aerokube/selenoid/info,github.com/aerokube/selenoid/jsonerror

go install golang.org/x/vuln/cmd/govulncheck@latest
"$(go env GOPATH)"/bin/govulncheck -tags production ./...
40 changes: 27 additions & 13 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,46 @@ module github.com/aerokube/selenoid
go 1.21

require (
github.com/aerokube/ggr v0.0.0-20221124163939-c041f40a7e45
github.com/aerokube/util v1.0.1
github.com/aws/aws-sdk-go v1.44.197
github.com/docker/docker v24.0.7+incompatible
github.com/docker/go-connections v0.4.0
github.com/aerokube/ggr v0.0.0-20240109084922-a37629b63e72
github.com/aws/aws-sdk-go v1.50.3
github.com/docker/docker v25.0.1+incompatible
github.com/docker/go-connections v0.5.0
github.com/docker/go-units v0.5.0
github.com/google/uuid v1.5.0
github.com/gorilla/websocket v1.5.0
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.1
github.com/imdario/mergo v0.3.13
github.com/mafredri/cdp v0.33.0
github.com/mafredri/cdp v0.34.1
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.8.4
golang.org/x/net v0.17.0
golang.org/x/net v0.20.0
)

require (
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/tools v0.9.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect
go.opentelemetry.io/otel v1.22.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0 // indirect
go.opentelemetry.io/otel/metric v1.22.0 // indirect
go.opentelemetry.io/otel/sdk v1.22.0 // indirect
go.opentelemetry.io/otel/trace v1.22.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.17.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect
)
131 changes: 76 additions & 55 deletions go.sum

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions info/info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package info

import (
"net"
"net/http"
"time"
)

func RequestInfo(r *http.Request) (string, string) {
const unknownUser = "unknown"
user := ""
if u, _, ok := r.BasicAuth(); ok {
user = u
} else {
user = unknownUser
}
remote := r.Header.Get("X-Forwarded-For")
if remote != "" {
return user, remote
}
remote, _, _ = net.SplitHostPort(r.RemoteAddr)
return user, remote
}

func SecondsSince(start time.Time) float64 {
return time.Now().Sub(start).Seconds()
}
67 changes: 59 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"encoding/json"
"flag"
"fmt"
"github.com/aerokube/selenoid/info"
"github.com/docker/docker/api"
"log"
"net"
"net/http"
Expand All @@ -24,8 +26,6 @@ import (
"github.com/aerokube/selenoid/service"
"github.com/aerokube/selenoid/session"
"github.com/aerokube/selenoid/upload"
"github.com/aerokube/util"
"github.com/aerokube/util/docker"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"golang.org/x/net/websocket"
Expand Down Expand Up @@ -187,7 +187,7 @@ func init() {
}
ip, _, _ := net.SplitHostPort(u.Host)
environment.IP = ip
cli, err = docker.CreateCompatibleDockerClient(
cli, err = createCompatibleDockerClient(
func(specifiedApiVersion string) {
log.Printf("[-] [INIT] [Using Docker API version: %s]", specifiedApiVersion)
},
Expand All @@ -204,6 +204,57 @@ func init() {
manager = &service.DefaultManager{Environment: &environment, Client: cli, Config: conf}
}

func createCompatibleDockerClient(onVersionSpecified, onVersionDetermined, onUsingDefaultVersion func(string)) (*client.Client, error) {
const dockerApiVersion = "DOCKER_API_VERSION"
dockerApiVersionEnv := os.Getenv(dockerApiVersion)
if dockerApiVersionEnv != "" {
onVersionSpecified(dockerApiVersionEnv)
} else {
maxMajorVersion, maxMinorVersion := parseVersion(api.DefaultVersion)
minMajorVersion, minMinorVersion := parseVersion("1.24")
for majorVersion := maxMajorVersion; majorVersion >= minMajorVersion; majorVersion-- {
for minorVersion := maxMinorVersion; minorVersion >= minMinorVersion; minorVersion-- {
apiVersion := fmt.Sprintf("%d.%d", majorVersion, minorVersion)
_ = os.Setenv(dockerApiVersion, apiVersion)
docker, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
return nil, err
}
if isDockerAPIVersionCorrect(docker) {
onVersionDetermined(apiVersion)
return docker, nil
}
_ = docker.Close()
}
}
onUsingDefaultVersion(api.DefaultVersion)
}
return client.NewClientWithOpts(client.FromEnv)
}

func parseVersion(ver string) (int, int) {
const point = "."
pieces := strings.Split(ver, point)
major, err := strconv.Atoi(pieces[0])
if err != nil {
return 0, 0
}
minor, err := strconv.Atoi(pieces[1])
if err != nil {
return 0, 0
}
return major, minor
}

func isDockerAPIVersionCorrect(docker *client.Client) bool {
ctx := context.Background()
apiInfo, err := docker.ServerVersion(ctx)
if err != nil {
return false
}
return apiInfo.APIVersion == docker.ClientVersion()
}

func parseGgrHost(s string) *ggr.Host {
h, p, err := net.SplitHostPort(s)
if err != nil {
Expand Down Expand Up @@ -260,7 +311,7 @@ func post(next http.HandlerFunc) http.HandlerFunc {

func ping(w http.ResponseWriter, _ *http.Request) {
w.Header().Add("Content-Type", "application/json")
json.NewEncoder(w).Encode(struct {
_ = json.NewEncoder(w).Encode(struct {
Uptime string `json:"uptime"`
LastReloadTime string `json:"lastReloadTime"`
NumRequests uint64 `json:"numRequests"`
Expand All @@ -274,7 +325,7 @@ func video(w http.ResponseWriter, r *http.Request) {
deleteFileIfExists(requestId, w, r, videoOutputDir, paths.Video, "DELETED_VIDEO_FILE")
return
}
user, remote := util.RequestInfo(r)
user, remote := info.RequestInfo(r)
if _, ok := r.URL.Query()[jsonParam]; ok {
listFilesAsJson(requestId, w, videoOutputDir, "VIDEO_ERROR")
return
Expand All @@ -285,7 +336,7 @@ func video(w http.ResponseWriter, r *http.Request) {
}

func deleteFileIfExists(requestId uint64, w http.ResponseWriter, r *http.Request, dir string, prefix string, status string) {
user, remote := util.RequestInfo(r)
user, remote := info.RequestInfo(r)
fileName := strings.TrimPrefix(r.URL.Path, prefix)
filePath := filepath.Join(dir, fileName)
_, err := os.Stat(filePath)
Expand Down Expand Up @@ -332,7 +383,7 @@ func handler() http.Handler {
})
root.HandleFunc(paths.Status, func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
json.NewEncoder(w).Encode(conf.State(sessions, limit, queue.Queued(), queue.Pending()))
_ = json.NewEncoder(w).Encode(conf.State(sessions, limit, queue.Queued(), queue.Pending()))
})
root.HandleFunc(paths.Ping, ping)
root.Handle(paths.VNC, websocket.Handler(vnc))
Expand Down Expand Up @@ -383,7 +434,7 @@ func main() {

sessions.Each(func(k string, s *session.Session) {
if enableFileUpload {
os.RemoveAll(path.Join(os.TempDir(), k))
_ = os.RemoveAll(path.Join(os.TempDir(), k))
}
s.Cancel()
})
Expand Down
8 changes: 4 additions & 4 deletions protect/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package protect

import (
"errors"
"github.com/aerokube/selenoid/info"
"log"
"math"
"net/http"
"time"

"github.com/aerokube/selenoid/jsonerror"
"github.com/aerokube/util"
)

// Queue - struct to hold a number of sessions
Expand Down Expand Up @@ -47,9 +47,9 @@ func (q *Queue) Check(next http.HandlerFunc) http.HandlerFunc {
<-q.limit
default:
if q.disabled {
user, remote := util.RequestInfo(r)
user, remote := info.RequestInfo(r)
log.Printf("[-] [QUEUE_IS_FULL] [%s] [%s]", user, remote)
err := errors.New("Queue Is Full")
err := errors.New("queue is full")
jsonerror.UnknownError(err).Encode(w)
return
}
Expand All @@ -61,7 +61,7 @@ func (q *Queue) Check(next http.HandlerFunc) http.HandlerFunc {
// Protect - handler to control limit of sessions
func (q *Queue) Protect(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
user, remote := util.RequestInfo(r)
user, remote := info.RequestInfo(r)
log.Printf("[-] [NEW_REQUEST] [%s] [%s]", user, remote)
s := time.Now()
go func() {
Expand Down
Loading

0 comments on commit fd32287

Please sign in to comment.