Class: Docker::Compose::Session
- Inherits:
-
Object
- Object
- Docker::Compose::Session
- Defined in:
- lib/docker/compose/session.rb
Overview
A Ruby OOP interface to a docker-compose session. A session is bound to a particular directory and docker-compose file (which are set at initialize time) and invokes whichever docker-compose command is resident in $PATH.
Run docker-compose commands by calling instance methods of this class and passing kwargs that are equivalent to the CLI options you would pass to the command-line tool.
Note that the Ruby command methods usually expose a subset of the options allowed by the docker-compose CLI, and that options are sometimes renamed for clarity, e.g. the “-d” flag always becomes the “detached:” kwarg.
Constant Summary collapse
- ANSI =
A Regex that matches all ANSI escape sequences.
/\033\[([0-9];?)+[a-z]/
Instance Attribute Summary collapse
-
#dir ⇒ Object
readonly
Working directory (determines compose project name); default is Dir.pwd.
-
#file ⇒ Object
readonly
Project file; default is ‘docker-compose.yml’.
Instance Method Summary collapse
- #build(*services, force_rm: false, no_cache: false, pull: false) ⇒ Object
-
#config(*args) ⇒ Hash
Validate docker-compose file and return it as Hash.
-
#down ⇒ Object
Take the stack down.
-
#initialize(shell = Backticks::Runner.new(buffered: [:stderr], interactive: true), dir: Dir.pwd, file: 'docker-compose.yml') ⇒ Session
constructor
A new instance of Session.
-
#kill(*services, signal: 'KILL') ⇒ Object
Forcibly stop running services.
-
#logs(*services) ⇒ true
Monitor the logs of one or more containers.
-
#pause(*services) ⇒ Object
Pause running services.
-
#port(service, port, protocol: 'tcp', index: 1) ⇒ String?
Figure out which interface(s) and port a given service port has been published to.
- #ps(*services) ⇒ Object
-
#pull(*services) ⇒ Object
Pull images of services.
- #restart(*services, timeout: 10) ⇒ Object
- #rm(*services, force: false, volumes: false) ⇒ Object
-
#run(service, *cmd, detached: false, no_deps: false, volumes: [], env: [], rm: false, no_tty: false, user: nil) ⇒ Object
Idempotently run an arbitrary command with a service container.
-
#run!(*args) ⇒ String
Run a docker-compose command without validating that the CLI parameters make sense.
-
#scale(container_count, timeout: 10) ⇒ Object
Idempotently scales the number of containers for given services in the project.
-
#stop(*services, timeout: 10) ⇒ Object
Stop running services.
-
#unpause(*services) ⇒ Object
Unpause running services.
-
#up(*services, detached: false, timeout: 10, build: false, no_build: false, no_deps: false, no_start: false) ⇒ true
Idempotently up the given services in the project.
-
#version(short: false) ⇒ String, Hash
Determine the installed version of docker-compose.
Constructor Details
#initialize(shell = Backticks::Runner.new(buffered: [:stderr], interactive: true), dir: Dir.pwd, file: 'docker-compose.yml') ⇒ Session
Returns a new instance of Session.
27 28 29 30 31 32 |
# File 'lib/docker/compose/session.rb', line 27 def initialize(shell = Backticks::Runner.new(buffered: [:stderr], interactive: true), dir: Dir.pwd, file: 'docker-compose.yml') @shell = shell @dir = dir @file = file end |
Instance Attribute Details
#dir ⇒ Object (readonly)
Working directory (determines compose project name); default is Dir.pwd
22 23 24 |
# File 'lib/docker/compose/session.rb', line 22 def dir @dir end |
#file ⇒ Object (readonly)
Project file; default is ‘docker-compose.yml’
25 26 27 |
# File 'lib/docker/compose/session.rb', line 25 def file @file end |
Instance Method Details
#build(*services, force_rm: false, no_cache: false, pull: false) ⇒ Object
226 227 228 229 230 231 |
# File 'lib/docker/compose/session.rb', line 226 def build(*services, force_rm: false, no_cache: false, pull: false) o = opts(force_rm: [force_rm, false], no_cache: [no_cache, false], pull: [pull, false]) result = run!('build', o, services) end |
#config(*args) ⇒ Hash
Validate docker-compose file and return it as Hash
37 38 39 40 |
# File 'lib/docker/compose/session.rb', line 37 def config(*args) config = strip_ansi(run!('config', *args)) YAML.load(config) end |
#down ⇒ Object
Take the stack down
102 103 104 |
# File 'lib/docker/compose/session.rb', line 102 def down run!('down') end |
#kill(*services, signal: 'KILL') ⇒ Object
Forcibly stop running services.
167 168 169 170 |
# File 'lib/docker/compose/session.rb', line 167 def kill(*services, signal: 'KILL') o = opts(signal: [signal, 'KILL']) run!('kill', o, services) end |
#logs(*services) ⇒ true
Monitor the logs of one or more containers.
46 47 48 49 |
# File 'lib/docker/compose/session.rb', line 46 def logs(*services) run!('logs', services) true end |
#pause(*services) ⇒ Object
Pause running services.
144 145 146 |
# File 'lib/docker/compose/session.rb', line 144 def pause(*services) run!('pause', *services) end |
#port(service, port, protocol: 'tcp', index: 1) ⇒ String?
Figure out which interface(s) and port a given service port has been published to.
NOTE: if Docker Compose is communicating with a remote Docker host, this method returns IP addresses from the point of view of that host and its interfaces. If you need to know the address as reachable from localhost, you probably want to use ‘Mapper`.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/docker/compose/session.rb', line 187 def port(service, port, protocol: 'tcp', index: 1) inter = @shell.interactive @shell.interactive = false o = opts(protocol: [protocol, 'tcp'], index: [index, 1]) s = strip_ansi(run!('port', o, service, port).strip) (!s.empty? && s) || nil rescue Error => e # Deal with docker-compose v1.11+ if e.detail =~ /No container found/i nil else raise end ensure @shell.interactive = inter end |
#ps(*services) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/docker/compose/session.rb', line 51 def ps(*services) inter = @shell.interactive @shell.interactive = false lines = strip_ansi(run!('ps', {q: true}, services)).split(/[\r\n]+/) containers = Collection.new lines.each do |id| containers << docker_ps(strip_ansi(id)) end containers ensure @shell.interactive = inter end |
#pull(*services) ⇒ Object
Pull images of services
108 109 110 |
# File 'lib/docker/compose/session.rb', line 108 def pull(*services) run!('pull', *services) end |
#restart(*services, timeout: 10) ⇒ Object
137 138 139 140 |
# File 'lib/docker/compose/session.rb', line 137 def restart(*services, timeout:10) o = opts(timeout: [timeout, 10]) run!('restart', o, *services) end |
#rm(*services, force: false, volumes: false) ⇒ Object
112 113 114 115 |
# File 'lib/docker/compose/session.rb', line 112 def rm(*services, force: false, volumes: false) o = opts(f: [force, false], v: [volumes, false]) run!('rm', o, services) end |
#run(service, *cmd, detached: false, no_deps: false, volumes: [], env: [], rm: false, no_tty: false, user: nil) ⇒ Object
Idempotently run an arbitrary command with a service container.
130 131 132 133 134 135 |
# File 'lib/docker/compose/session.rb', line 130 def run(service, *cmd, detached: false, no_deps: false, volumes: [], env: [], rm: false, no_tty: false, user: nil) o = opts(d: [detached, false], no_deps: [no_deps, false], rm: [rm, false], T: [no_tty, false], u: [user, nil]) env_params = env.map { |v| { e: v } } volume_params = volumes.map { |v| { v: v } } run!('run', o, *env_params, *volume_params, service, cmd) end |
#run!(*args) ⇒ String
Run a docker-compose command without validating that the CLI parameters make sense. Prepend project and file options if suitable.
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/docker/compose/session.rb', line 242 def run!(*args) file_args = case @file when 'docker-compose.yml' [] when Array # backticks sugar can't handle array values; build a list of hashes # IMPORTANT: preserve the order of the files so overrides work correctly file_args = @file.map { |filepath| { :file => filepath } } else # a single String (or Pathname, etc); use normal sugar to add it [{ file: @file.to_s }] end @shell.chdir = dir cmd = @shell.run('docker-compose', *file_args, *args).join status = cmd.status out = cmd.captured_output err = cmd.captured_error status.success? || fail(Error.new(args.first, status, out+err)) out end |
#scale(container_count, timeout: 10) ⇒ Object
Idempotently scales the number of containers for given services in the project.
95 96 97 98 99 |
# File 'lib/docker/compose/session.rb', line 95 def scale(container_count, timeout: 10) args = container_count.map {|service, count| "#{service}=#{count}"} o = opts(timeout: [timeout, 10]) run!('scale', o, *args) end |
#stop(*services, timeout: 10) ⇒ Object
Stop running services.
158 159 160 161 |
# File 'lib/docker/compose/session.rb', line 158 def stop(*services, timeout: 10) o = opts(timeout: [timeout, 10]) run!('stop', o, services) end |
#unpause(*services) ⇒ Object
Unpause running services.
150 151 152 |
# File 'lib/docker/compose/session.rb', line 150 def unpause(*services) run!('unpause', *services) end |
#up(*services, detached: false, timeout: 10, build: false, no_build: false, no_deps: false, no_start: false) ⇒ true
Idempotently up the given services in the project.
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/docker/compose/session.rb', line 79 def up(*services, detached: false, timeout: 10, build: false, no_build: false, no_deps: false, no_start: false) o = opts(d: [detached, false], timeout: [timeout, 10], build: [build, false], no_build: [no_build, false], no_deps: [no_deps, false], no_start: [no_start, false]) run!('up', o, services) true end |
#version(short: false) ⇒ String, Hash
Determine the installed version of docker-compose.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/docker/compose/session.rb', line 210 def version(short: false) o = opts(short: [short, false]) result = run!('version', o, file: false, dir: false) if short result.strip else lines = result.split(/[\r\n]+/) lines.inject({}) do |h, line| kv = line.split(/: +/, 2) h[kv.first] = kv.last h end end end |