Files
kamal/lib/mrsk/commands/app.rb
David Heinemeier Hansson 93423f2f20 Merge branch 'main' into pr/99
* main:
  Wording
  Remove accessory images using tags rather than labels
  Update readme to point to ghcr.io/mrsked/mrsk
  Validate that all roles have hosts
  Commander needn't accumulate configuration
  Pull latest image tag, so we can identity it
  Default to deploying the config version
  Remove unneeded Dockerfile.dind, update Readme
  add D-in-D dockerfile, update Readme
2023-03-24 14:26:31 +01:00

144 lines
3.5 KiB
Ruby

class Mrsk::Commands::App < Mrsk::Commands::Base
attr_reader :role
def initialize(config, role: nil)
super(config)
@role = role
end
def run
role = config.role(self.role)
docker :run,
"--detach",
"--restart unless-stopped",
"--log-opt", "max-size=#{MAX_LOG_SIZE}",
"--name", service_with_version_and_destination_and_role,
"-e", "MRSK_CONTAINER_NAME=\"#{service_with_version_and_destination_and_role}\"",
*role.env_args,
*config.volume_args,
*role.label_args,
*role.option_args,
config.absolute_image,
role.cmd
end
def start
docker :start, service_with_version_and_destination_and_role
end
def stop(version: nil)
pipe \
version ? container_id_for_version(version) : current_container_id,
xargs(docker(:stop))
end
def info
docker :ps, *filter_args
end
def logs(since: nil, lines: nil, grep: nil)
pipe \
current_container_id,
"xargs docker logs#{" --since #{since}" if since}#{" --tail #{lines}" if lines} 2>&1",
("grep '#{grep}'" if grep)
end
def follow_logs(host:, grep: nil)
run_over_ssh \
pipe(
current_container_id,
"xargs docker logs --timestamps --tail 10 --follow 2>&1",
(%(grep "#{grep}") if grep)
),
host: host
end
def execute_in_existing_container(*command, interactive: false)
docker :exec,
("-it" if interactive),
service_with_version_and_destination_and_role,
*command
end
def execute_in_new_container(*command, interactive: false)
docker :run,
("-it" if interactive),
"--rm",
*config.env_args,
*config.volume_args,
config.absolute_image,
*command
end
def execute_in_existing_container_over_ssh(*command, host:)
run_over_ssh execute_in_existing_container(*command, interactive: true), host: host
end
def execute_in_new_container_over_ssh(*command, host:)
run_over_ssh execute_in_new_container(*command, interactive: true), host: host
end
def current_container_id
docker :ps, "--quiet", *filter_args
end
def current_running_version
# FIXME: Find more graceful way to extract the version from "app-version" than using sed and tail!
pipe \
docker(:ps, *filter_args, "--format", '"{{.Names}}"'),
%(sed 's/-/\\n/g'),
"tail -n 1"
end
def list_containers
docker :container, :ls, "--all", *filter_args
end
def list_container_names
[ *list_containers, "--format", "'{{ .Names }}'" ]
end
def remove_container(version:)
pipe \
container_id_for(container_name: service_with_version_and_destination_and_role(version)),
xargs(docker(:container, :rm))
end
def remove_containers
docker :container, :prune, "--force", *filter_args
end
def list_images
docker :image, :ls, config.repository
end
def remove_images
docker :image, :prune, "--all", "--force", *filter_args
end
private
def service_with_version_and_destination_and_role(version = nil)
[ config.service, role, config.destination, version || config.version ].compact.join("-")
end
def container_id_for_version(version)
container_id_for(container_name: service_with_version_and_destination_and_role(version))
end
def filter_args
argumentize "--filter", filters
end
def filters
[ "label=service=#{config.service}" ].tap do |filters|
filters << "label=destination=#{config.destination}" if config.destination
filters << "label=role=#{role}" if role
end
end
end