// Package client provides Docker client initiatialisation functions. package client import ( "context" "errors" "fmt" "net/http" "os" "time" contextPkg "coopcloud.tech/abra/pkg/context" sshPkg "coopcloud.tech/abra/pkg/ssh" commandconnPkg "coopcloud.tech/abra/pkg/upstream/commandconn" "github.com/docker/docker/client" "github.com/sirupsen/logrus" ) // New initiates a new Docker client. New client connections are validated so // that we ensure connections via SSH to the daemon can succeed. It takes into // account that you may only want the local client and not communicate via SSH. // For this use-case, please pass "default" as the contextName. func New(serverName string) (*client.Client, error) { var clientOpts []client.Opt if serverName != "default" { context, err := GetContext(serverName) if err != nil { return nil, fmt.Errorf("unknown server, run \"abra server add %s\"?", serverName) } ctxEndpoint, err := contextPkg.GetContextEndpoint(context) if err != nil { return nil, err } helper, err := commandconnPkg.NewConnectionHelper(ctxEndpoint) if err != nil { return nil, err } httpClient := &http.Client{ Transport: &http.Transport{ DialContext: helper.Dialer, IdleConnTimeout: 30 * time.Second, }, } clientOpts = append(clientOpts, client.WithHTTPClient(httpClient), client.WithHost(helper.Host), client.WithDialContext(helper.Dialer), ) } version := os.Getenv("DOCKER_API_VERSION") if version != "" { clientOpts = append(clientOpts, client.WithVersion(version)) } else { clientOpts = append(clientOpts, client.WithAPIVersionNegotiation()) } cl, err := client.NewClientWithOpts(clientOpts...) if err != nil { return nil, err } logrus.Debugf("created client for %s", serverName) info, err := cl.Info(context.Background()) if err != nil { return cl, sshPkg.Fatal(serverName, err) } if info.Swarm.LocalNodeState == "inactive" { if serverName != "default" { return cl, fmt.Errorf("swarm mode not enabled on %s?", serverName) } else { return cl, errors.New("swarm mode not enabled on local server?") } } return cl, nil }