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) ⇒ 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
224 225 226 227 228 229 |
# File 'lib/docker/compose/session.rb', line 224 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
100 101 102 |
# File 'lib/docker/compose/session.rb', line 100 def down run!('down') end |
#kill(*services, signal: 'KILL') ⇒ Object
Forcibly stop running services.
165 166 167 168 |
# File 'lib/docker/compose/session.rb', line 165 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.
142 143 144 |
# File 'lib/docker/compose/session.rb', line 142 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`.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/docker/compose/session.rb', line 185 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
106 107 108 |
# File 'lib/docker/compose/session.rb', line 106 def pull(*services) run!('pull', *services) end |
#restart(*services, timeout: 10) ⇒ Object
135 136 137 138 |
# File 'lib/docker/compose/session.rb', line 135 def restart(*services, timeout:10) o = opts(timeout: [timeout, 10]) run!('restart', o, *services) end |
#rm(*services, force: false, volumes: false) ⇒ Object
110 111 112 113 |
# File 'lib/docker/compose/session.rb', line 110 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.
128 129 130 131 132 133 |
# File 'lib/docker/compose/session.rb', line 128 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.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/docker/compose/session.rb', line 240 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.
93 94 95 96 97 |
# File 'lib/docker/compose/session.rb', line 93 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.
156 157 158 159 |
# File 'lib/docker/compose/session.rb', line 156 def stop(*services, timeout: 10) o = opts(timeout: [timeout, 10]) run!('stop', o, services) end |
#unpause(*services) ⇒ Object
Unpause running services.
148 149 150 |
# File 'lib/docker/compose/session.rb', line 148 def unpause(*services) run!('unpause', *services) end |
#up(*services, detached: false, timeout: 10, build: false, no_build: false, no_deps: false) ⇒ true
Idempotently up the given services in the project.
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/docker/compose/session.rb', line 79 def up(*services, detached: false, timeout: 10, build: false, no_build: false, no_deps: false) o = opts(d: [detached, false], timeout: [timeout, 10], build: [build, false], no_build: [no_build, false], no_deps: [no_deps, false]) run!('up', o, services) true end |
#version(short: false) ⇒ String, Hash
Determine the installed version of docker-compose.
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/docker/compose/session.rb', line 208 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 |