Class: Docker::Compose::Mapper
- Inherits:
-
Object
- Object
- Docker::Compose::Mapper
- Defined in:
- lib/docker/compose/mapper.rb
Overview
Uses a Session to discover information about services’ IP addresses and ports as reachable from localhost, then maps URLs and other common network address formats so they point to the right host and port.
NOTE: this class uses some heuristics to deal with cases where the Docker client is talking to a remote server because the ‘DOCKER_HOST` environment variable is set. In those cases, Mapper tries to determine the IP address of the exposed services as reachable from localhost; it generally makes a correct guess, but in certain super-complex networking scenarios it may guess wrong. Please open a GitHub issue if you find a situation where Mapper provides a wrong answer.
Constant Summary collapse
- ELIDED =
Pattern that matches an “elided” host or port that should be omitted from output, but is needed to identify a specific container and port.
/^\[.+\]$/.freeze
- REMOVE_ELIDED =
Regexp that can be used with gsub to strip elision marks
/[\[\]]/.freeze
- BadSubstitution =
Class.new(StandardError)
- NoService =
Class.new(RuntimeError)
Class Method Summary collapse
-
.map(env, session: Session.new, net_info: NetInfo.new) { ... } ⇒ Object
Instantiate a mapper; map some environment variables; yield to caller for additional processing.
Instance Method Summary collapse
-
#host_and_port(service, port) ⇒ Array
Figure out which host port a given service’s port has been published to, and/or whether that service is running.
-
#initialize(session = Session.new, net_info = NetInfo.new) ⇒ Mapper
constructor
Create an instance of Mapper.
-
#map(value) ⇒ String, Array
Substitute service hostnames and ports that appear in a URL or a host:port string.
Constructor Details
#initialize(session = Session.new, net_info = NetInfo.new) ⇒ Mapper
Create an instance of Mapper
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/docker/compose/mapper.rb', line 48 def initialize(session=Session.new, net_info=NetInfo.new) docker_host = ENV['DOCKER_HOST'] if docker_host.nil? || docker_host =~ /^(\/|unix|file)/ # If DOCKER_HOST is blank, or pointing to a local socket, then we # can trust the address information returned by `docker-compose port`. override_host = nil else # If DOCKER_HOST is present, assume that containers have bound to # whatever IP we reach it at; don't fall victim to docker-compose's # dirty lies! override_host = net_info.docker_routable_ip end @session = session @override_host = override_host end |
Class Method Details
.map(env, session: Session.new, net_info: NetInfo.new) { ... } ⇒ Object
Instantiate a mapper; map some environment variables; yield to caller for additional processing.
32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/docker/compose/mapper.rb', line 32 def self.map(env, session:Session.new, net_info:NetInfo.new) mapper = new(session, net_info) env.each_pair do |k, v| begin v = mapper.map(v) yield(k, v) rescue NoService yield(k, nil) end end end |
Instance Method Details
#host_and_port(service, port) ⇒ Array
Figure out which host port a given service’s port has been published to, and/or whether that service is running. Cannot distinguish between the “service not running” case and the “container port not published” case!
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/docker/compose/mapper.rb', line 102 def host_and_port(service, port) result = @session.port(service, port.to_s) if result result.chomp! else raise NoService, "Service '#{service}' not running, or does not " \ "publish port '#{port}'" end host, port = result.split(':') host = @override_host if @override_host [host, Integer(port)] end |
#map(value) ⇒ String, Array
Substitute service hostnames and ports that appear in a URL or a host:port string. If either component of a host:port string is surrounded by square brackets, “elide” that component, removing it from the result but using it to find the correct service and port.
88 89 90 91 92 93 94 |
# File 'lib/docker/compose/mapper.rb', line 88 def map(value) if value.respond_to?(:map) value.map { |e| map_scalar(e) } else map_scalar(value) end end |