Class: Docker::API::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/docker/api/config.rb

Overview

Where the daemon is and how to reach it, resolved once and then frozen.

Frozen is the point. The docker-api gem exposes Docker.url= and Docker.creds= as process-global setters, so a second caller silently inherits -- or clobbers -- the first caller's daemon. Configuration here is a value: two clients hold two of them and cannot interfere.

Constant Summary collapse

DEFAULT_UNIX_SOCKET =

Where Docker listens by default on Linux and macOS.

"unix:///var/run/docker.sock"
DEFAULT_WINDOWS_PIPE =

Where Docker Desktop for Windows listens by default.

"npipe:////./pipe/docker_engine"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url: nil, tls: nil, api_version: :negotiate, read_timeout: 60, open_timeout: 10) ⇒ Config

Returns a new instance of Config.

Parameters:

  • url (String, nil) (defaults to: nil)

    the daemon URL

  • tls (Hash, nil) (defaults to: nil)

    TLS material

  • api_version (String, Symbol) (defaults to: :negotiate)

    version handling

  • read_timeout (Numeric) (defaults to: 60)

    seconds

  • open_timeout (Numeric) (defaults to: 10)

    seconds



43
44
45
46
47
48
49
50
51
# File 'lib/docker/api/config.rb', line 43

def initialize(url: nil, tls: nil, api_version: :negotiate,
  read_timeout: 60, open_timeout: 10)
  @url = url || self.class.default_url
  @tls = (tls || {}).freeze
  @api_version = api_version
  @read_timeout = read_timeout
  @open_timeout = open_timeout
  freeze
end

Instance Attribute Details

#api_versionString, Symbol (readonly)

Returns :negotiate, :none, or a pinned version.

Returns:

  • (String, Symbol)

    :negotiate, :none, or a pinned version



30
31
32
# File 'lib/docker/api/config.rb', line 30

def api_version
  @api_version
end

#open_timeoutNumeric (readonly)

Returns seconds to wait for a connection.

Returns:

  • (Numeric)

    seconds to wait for a connection



36
37
38
# File 'lib/docker/api/config.rb', line 36

def open_timeout
  @open_timeout
end

#read_timeoutNumeric (readonly)

Returns seconds to wait for response data.

Returns:

  • (Numeric)

    seconds to wait for response data



33
34
35
# File 'lib/docker/api/config.rb', line 33

def read_timeout
  @read_timeout
end

#tlsHash (readonly)

Returns TLS material, empty when TLS is not in use.

Returns:

  • (Hash)

    TLS material, empty when TLS is not in use



27
28
29
# File 'lib/docker/api/config.rb', line 27

def tls
  @tls
end

#urlString (readonly)

Returns the daemon URL.

Returns:

  • (String)

    the daemon URL



24
25
26
# File 'lib/docker/api/config.rb', line 24

def url
  @url
end

Class Method Details

.default_urlString

Returns the platform's default daemon URL.

Returns:

  • (String)

    the platform's default daemon URL



110
111
112
# File 'lib/docker/api/config.rb', line 110

def self.default_url
  windows? ? DEFAULT_WINDOWS_PIPE : DEFAULT_UNIX_SOCKET
end

.from_env(env = ENV, **overrides) ⇒ Docker::API::Config

Resolve configuration the way the Docker CLI does.

Examples:

Config.from_env("DOCKER_HOST" => "tcp://build:2376",
                "DOCKER_CERT_PATH" => "/certs",
                "DOCKER_TLS_VERIFY" => "1")

Parameters:

  • env (Hash) (defaults to: ENV)

    the environment to read, injectable for tests

Returns:



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/docker/api/config.rb', line 62

def self.from_env(env = ENV, **overrides)
  # Ruby permits non-Symbol keys in a **kwargs splat, so
  # `from_env("DOCKER_HOST" => "tcp://x")` puts the variable in overrides
  # and quietly reads the real environment instead. Saying so is much
  # kinder than resolving the wrong daemon and never mentioning it.
  stray = overrides.keys.grep(String)
  unless stray.empty?
    raise ArgumentError,
      "from_env takes the environment as its first argument: " \
      "from_env({ #{stray.first.inspect} => ... }). Got #{stray.inspect} as options."
  end

  # Resolution order, matching the CLI: an explicit argument, then
  # DOCKER_HOST, then the active context, then the platform default.
  #
  # `docker context use` exports nothing -- it writes currentContext into
  # config.json -- so a client that skips the store disagrees with the
  # CLI on the same machine and falls back to /var/run/docker.sock, which
  # Colima, Rancher Desktop, rootless Docker and Podman generally do not
  # create. The store is only consulted when nothing more explicit has
  # already answered, so this cannot change what an existing caller resolves.
  context = if overrides[:url].nil? && blank?(env["DOCKER_HOST"]) && blank?(env["DOCKER_URL"])
              Context.resolve(env)
            end

  # presence, not a bare ||: an exported-but-empty DOCKER_HOST is truthy
  # in Ruby, so it would beat the context and then resolve to the default
  # socket anyway. The CLI treats an empty value as unset.
  url = overrides[:url] || presence(env["DOCKER_HOST"]) || presence(env["DOCKER_URL"]) ||
    context&.[](:url) || default_url

  tls = if overrides.key?(:tls)
          overrides[:tls]
        else
          from_env = tls_from_env(env)
          from_env.empty? ? (context&.[](:tls) || {}) : from_env
        end

  new(
    url: url,
    tls: tls,
    api_version: overrides.fetch(:api_version, env["DOCKER_API_VERSION"] || :negotiate),
    read_timeout: overrides.fetch(:read_timeout, 60),
    open_timeout: overrides.fetch(:open_timeout, 10)
  )
end

.windows?Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/docker/api/config.rb', line 129

def self.windows?
  RbConfig::CONFIG["host_os"].match?(/mswin|mingw|cygwin/)
end

Instance Method Details

#to_sString Also known as: inspect

Returns:

  • (String)


156
157
158
159
# File 'lib/docker/api/config.rb', line 156

def to_s
  "#<Docker::API::Config url=#{url} tls=#{tls.empty? ? "none" : "configured"} " \
    "api_version=#{api_version}>"
end