Class: GDKBox::Docker
- Inherits:
-
Object
- Object
- GDKBox::Docker
- Defined in:
- lib/gdkbox/docker.rb
Overview
A small, focused wrapper around the docker CLI.
Only the verbs gdkbox needs are exposed. Every container created by gdkbox
is tagged with the gdkbox=true label plus a gdkbox.name label so they
can be discovered later without relying on local metadata alone.
Defined Under Namespace
Classes: PullProgress
Instance Method Summary collapse
- #available? ⇒ Boolean
-
#cp_into(name, src, dest) ⇒ Object
Copy a host path into a container at dest (a full destination path).
-
#exec(name, script, user: nil, workdir: nil, env: {}, input: nil, check: true) ⇒ Object
Run a bash script inside a running container.
-
#initialize(shell: Shell.new) ⇒ Docker
constructor
A new instance of Docker.
-
#list_names ⇒ Object
Names of all gdkbox-managed containers, derived from labels.
-
#pull(image, &block) ⇒ Object
Pull an image.
- #rm(name, force: true) ⇒ Object
-
#run_container(name:, image:, publish: [], labels: {}, env: {}, args: []) ⇒ Object
Start a detached container, returning its id.
- #start(name) ⇒ Object
-
#state(name) ⇒ Object
The container's lifecycle state, or :absent if it does not exist.
- #stop(name) ⇒ Object
Constructor Details
Instance Method Details
#available? ⇒ Boolean
14 15 16 |
# File 'lib/gdkbox/docker.rb', line 14 def available? !@shell.which("docker").nil? end |
#cp_into(name, src, dest) ⇒ Object
Copy a host path into a container at dest (a full destination path).
218 219 220 |
# File 'lib/gdkbox/docker.rb', line 218 def cp_into(name, src, dest) @shell.run!("docker", "cp", src, "#{name}:#{dest}") end |
#exec(name, script, user: nil, workdir: nil, env: {}, input: nil, check: true) ⇒ Object
Run a bash script inside a running container. The script is passed to
bash -lc as a single argument; values that vary (keys, usernames) are
passed through the environment to avoid quoting pitfalls.
When check is true (the default) a non-zero exit raises; pass check: false to capture output and exit status without raising, which is what agent runs want so the caller can surface the agent's output either way.
208 209 210 211 212 213 214 215 |
# File 'lib/gdkbox/docker.rb', line 208 def exec(name, script, user: nil, workdir: nil, env: {}, input: nil, check: true) cmd = ["docker", "exec", "-i"] cmd.push("-u", user) if user cmd.push("-w", workdir) if workdir env.each { |key, value| cmd.push("-e", "#{key}=#{value}") } cmd.push(name, "bash", "-lc", script) check ? @shell.run!(*cmd, input: input) : @shell.run(*cmd, input: input) end |
#list_names ⇒ Object
Names of all gdkbox-managed containers, derived from labels.
246 247 248 249 250 251 252 253 254 255 |
# File 'lib/gdkbox/docker.rb', line 246 def list_names result = @shell.run( "docker", "ps", "-a", "--filter", "label=gdkbox=true", "--format", '{{index .Labels "gdkbox.name"}}' ) return [] unless result.success? result.stdout.split("\n").map(&:strip).reject(&:empty?) end |
#pull(image, &block) ⇒ Object
Pull an image. With no block the pull runs quietly and the (captured)
Result is returned. With a block the pull is streamed and the block is
called with a PullProgress after every line of docker pull output, so a
caller can drive a progress bar. Raises CommandError on a non-zero exit.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/gdkbox/docker.rb', line 22 def pull(image, &block) return @shell.run!("docker", "pull", image) unless block tracker = PullProgress.new result = @shell.stream_tty("docker", "pull", image) do |line| tracker.ingest(line) block.call(tracker) end unless result.success? raise CommandError.new(["docker", "pull", image], result.status, result.stderr) end result end |
#rm(name, force: true) ⇒ Object
230 231 232 233 234 235 |
# File 'lib/gdkbox/docker.rb', line 230 def rm(name, force: true) cmd = ["docker", "rm"] cmd << "-f" if force cmd << name @shell.run(*cmd) end |
#run_container(name:, image:, publish: [], labels: {}, env: {}, args: []) ⇒ Object
Start a detached container, returning its id.
191 192 193 194 195 196 197 198 199 |
# File 'lib/gdkbox/docker.rb', line 191 def run_container(name:, image:, publish: [], labels: {}, env: {}, args: []) cmd = ["docker", "run", "-d", "--name", name] labels.each { |key, value| cmd.push("--label", "#{key}=#{value}") } env.each { |key, value| cmd.push("-e", "#{key}=#{value}") } publish.each { |mapping| cmd.push("-p", mapping) } cmd << image cmd.concat(args) @shell.run!(*cmd).stdout.strip end |
#start(name) ⇒ Object
222 223 224 |
# File 'lib/gdkbox/docker.rb', line 222 def start(name) @shell.run!("docker", "start", name) end |
#state(name) ⇒ Object
The container's lifecycle state, or :absent if it does not exist.
238 239 240 241 242 243 |
# File 'lib/gdkbox/docker.rb', line 238 def state(name) result = @shell.run("docker", "inspect", "-f", "{{.State.Status}}", name) return :absent unless result.success? result.stdout.strip.to_sym end |
#stop(name) ⇒ Object
226 227 228 |
# File 'lib/gdkbox/docker.rb', line 226 def stop(name) @shell.run!("docker", "stop", name) end |