Class: Dash::Commands::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/dash/commands/base.rb

Constant Summary collapse

NO_HEALTHCHECK =

Prefixed onto the docker state when the container declares no healthcheck at all, so "nothing is probing this container" stays distinguishable from "the probe passed" — both used to reach the poller as running. The state is kept after the prefix so a healthcheck-less container that died still reports why.

"no-healthcheck"
DOCKER_HEALTH_STATUS_FORMAT =
"'{{if .State.Health}}{{.State.Health.Status}}{{else}}#{NO_HEALTHCHECK}:{{.State.Status}}{{end}}'"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Base

Returns a new instance of Base.



15
16
17
# File 'lib/dash/commands/base.rb', line 15

def initialize(config)
  @config = config
end

Instance Attribute Details

#configObject

Returns the value of attribute config.



13
14
15
# File 'lib/dash/commands/base.rb', line 13

def config
  @config
end

Instance Method Details

#container_id_for(container_name:, only_running: false) ⇒ Object



23
24
25
# File 'lib/dash/commands/base.rb', line 23

def container_id_for(container_name:, only_running: false)
  docker :container, :ls, *("--all" unless only_running), "--filter", "'name=^#{container_name}$'", "--quiet"
end

#ensure_docker_installedObject



73
74
75
76
77
# File 'lib/dash/commands/base.rb', line 73

def ensure_docker_installed
  combine \
    ensure_local_docker_installed,
    ensure_local_buildx_installed
end

#ensure_run_directoryObject

Creates the run directory, renaming a pre-3b .kamal into place first.

Lives on Base because two unlocked paths reach the run directory before Dash::Cli::Base#ensure_run_directory does — the auditor records "Pulled image" during build:pull, and every mkdir -p .dash/... underneath it creates the parent. If any of them made the directory with a bare mkdir, .dash would exist by the time the guard ran and the legacy tree would be stranded. Everything that can be first must run the same command.

The migration is safe to repeat on every command:

  • Idempotent - once .dash exists the second guard is false forever.
  • Atomic - the two are siblings in the SSH user's home, so this is a rename within one filesystem, never a copy.
  • Invisible to running containers - a bind mount resolves to an inode, so the live proxy keeps serving from the renamed directory and only picks up the new path when it is next recreated.

test leads deliberately: SSHKit's command map passes if/test/time/ exec through untouched and prefixes everything else with /usr/bin/env. The trailing || true keeps the exit status zero when there is nothing to migrate, since callers execute this with raise_on_non_zero_exit on.



57
58
59
# File 'lib/dash/commands/base.rb', line 57

def ensure_run_directory
  combine migrate_legacy_run_directory, make_directory(config.run_directory)
end

#make_directory(path) ⇒ Object



31
32
33
# File 'lib/dash/commands/base.rb', line 31

def make_directory(path)
  [ :mkdir, "-p", path ]
end

#make_directory_for(remote_file) ⇒ Object



27
28
29
# File 'lib/dash/commands/base.rb', line 27

def make_directory_for(remote_file)
  make_directory Pathname.new(remote_file).dirname.to_s
end

#read_file(file, default: nil) ⇒ Object



69
70
71
# File 'lib/dash/commands/base.rb', line 69

def read_file(file, default: nil)
  combine [ :cat, file, "2>", "/dev/null" ], [ :echo, "\"#{default}\"" ], by: "||"
end

#remove_directory(path) ⇒ Object



61
62
63
# File 'lib/dash/commands/base.rb', line 61

def remove_directory(path)
  [ :rm, "-r", path ]
end

#remove_file(path) ⇒ Object



65
66
67
# File 'lib/dash/commands/base.rb', line 65

def remove_file(path)
  [ :rm, path ]
end

#run_over_ssh(*command, host:) ⇒ Object



19
20
21
# File 'lib/dash/commands/base.rb', line 19

def run_over_ssh(*command, host:)
  "ssh#{ssh_config_args}#{ssh_proxy_args}#{ssh_keys_args} -t #{config.ssh.user}@#{host} -p #{config.ssh.port} '#{command.join(" ").gsub("'", "'\\\\''")}'"
end