class Object

Public Instance Methods

check_stayed_running(name) click to toggle source
# File lib/deployinator/helpers.rb, line 140
def check_stayed_running(name)
  sleep 3
  unless container_is_running?(name)
    fatal "Container #{name} on #{fetch(:domain)} did not stay running more than 3 seconds"
    exit
  end
  if container_is_restarting?(name)
    fatal "Container #{name} on #{fetch(:domain)} is stuck restarting itself."
    exit
  end
end
container_exists?(container_name) click to toggle source
# File lib/deployinator/helpers.rb, line 126
def container_exists?(container_name)
  test "bash", "-c", "\"docker", "inspect", container_name, "&>", "/dev/null\""
end
container_is_restarting?(container_name) click to toggle source
# File lib/deployinator/helpers.rb, line 135
def container_is_restarting?(container_name)
  test "[", "\"`docker", "inspect", "--format='{{.State.Restarting}}'",
    container_name, "2>&1`\"", "=", "\"true\"", "]"
end
container_is_running?(container_name) click to toggle source
# File lib/deployinator/helpers.rb, line 130
def container_is_running?(container_name)
  test "[", "\"`docker", "inspect", "--format='{{.State.Running}}'",
    "#{container_name} 2>&1`\"", "=", "\"true\"", "]"
end
deploy_assets_cleanup(host) click to toggle source
# File lib/deployinator/built-in.rb, line 190
def deploy_assets_cleanup(host)
  execute(
    "docker", "run", "--rm", "--tty",
    "-e", "RAILS_ENV=#{fetch(:rails_env)}",
    "-w", release_path,
    fetch(:deploy_custom_container_options),
    "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
    "--entrypoint", shared_path.join('bundle', 'bin', 'bundle'),
    fetch(:ruby_image_name), "exec", "rake", "assets:clean"
  )
end
deploy_assets_precompile(host) click to toggle source
# File lib/deployinator/built-in.rb, line 173
def deploy_assets_precompile(host)
  execute(
    "docker", "run", "--rm", "--tty", "--user", fetch(:webserver_username),
    "-e", "APP_STAGE=#{fetch(:stage)}",
    "-e", "RAILS_ROOT=#{current_path}",
    "-w", release_path,
    "--volume", "/home:/home:rw",
    "--volume", "/etc/passwd:/etc/passwd:ro",
    "--volume", "/etc/group:/etc/group:ro",
    "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
    fetch(:deploy_custom_container_options),
    "--entrypoint", "/bin/bash",
    fetch(:ruby_image_name), "-c",
    "\"umask", "0007", "&&", "#{shared_path.join('bundle', 'bin', 'rake')}",
    "assets:precompile\""
  )
end
deploy_bluepill_restart(host) click to toggle source
# File lib/deployinator/built-in.rb, line 89
def deploy_bluepill_restart(host)
  execute(
    "docker", "exec", "--tty",
    fetch(:ruby_container_name),
    shared_path.join('bundle', 'bin', 'bluepill'),
    fetch(:application), "restart"
  )
end
deploy_bluepill_stop(host) click to toggle source
# File lib/deployinator/built-in.rb, line 97
def deploy_bluepill_stop(host)
  execute(
    "docker", "exec", "--tty",
    fetch(:ruby_container_name),
    shared_path.join('bundle', 'bin', 'bluepill'),
    fetch(:application), "stop"
  )
end
deploy_install_bundler(host) click to toggle source
# File lib/deployinator/built-in.rb, line 214
def deploy_install_bundler(host)
  execute(
    "docker", "run", "--rm", "--tty", "--user", fetch(:deployment_username),
    "-e", "GEM_HOME=#{shared_path.join('bundle')}",
    "-e", "GEM_PATH=#{shared_path.join('bundle')}",
    "-e", "PATH=#{shared_path.join('bundle', 'bin')}:$PATH",
    "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
    "--volume", "/home:/home:rw",
    "--volume", "/etc/passwd:/etc/passwd:ro",
    "--volume", "/etc/group:/etc/group:ro",
    "--entrypoint", "/bin/bash",
    fetch(:ruby_image_name), "-c",
    "\"umask", "0007", "&&" "/usr/local/bin/gem", "install",
    "--install-dir", "#{shared_path.join('bundle')}",
    "--bindir", shared_path.join('bundle', 'bin'),
    "--no-ri", "--no-rdoc", "--quiet", "bundler", "-v'#{fetch(:bundler_version)}'\""
  )
end
deploy_rails_console(host) click to toggle source
# File lib/deployinator/built-in.rb, line 138
def deploy_rails_console(host)
  [
    "ssh", "-t", "#{host}", "\"docker", "exec", "--interactive", "--tty",
    fetch(:ruby_container_name),
    # "sudo", "-u", fetch(:webserver_username), TODO, make sure it works to add this line
    "bash", "-c", "'cd", current_path, "&&",
    shared_path.join('bundle', 'bin', 'rails'),
    "console", "#{fetch(:rails_env)}'\""
  ].join(' ')
end
deploy_rails_console_print(host) click to toggle source
# File lib/deployinator/built-in.rb, line 148
def deploy_rails_console_print(host)
  [
    "docker", "exec", "--interactive", "--tty",
    fetch(:ruby_container_name),
    "bash", "-c", "\"cd", current_path, "&&",
    shared_path.join('bundle', 'bin', 'rails'),
    "console", "#{fetch(:rails_env)}\""
  ].join(' ')
end
deploy_rake_db_migrate(host) click to toggle source
# File lib/deployinator/built-in.rb, line 201
def deploy_rake_db_migrate(host)
  execute(
    "docker", "run", "--rm", "--tty",
    "-w", release_path,
    "-e", "APP_STAGE=#{fetch(:stage)}",
    "-e", "RAILS_ROOT=#{current_path}",
    "-e", "RAILS_ENV=#{fetch(:rails_env)}",
    fetch(:deploy_custom_container_options),
    "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
    "--entrypoint", shared_path.join('bundle', 'bin', 'rake'),
    fetch(:ruby_image_name), "db:migrate"
  )
end
deploy_run_bluepill(host) click to toggle source

# TODO: fix from_local, right now you have to copy-paste the set_scm method to your deploy.rb # Use `cap <stage> deploy from_local=true` to deploy your locally changed code # instead of the code in the git repo. You can also add –trace. # You can set include_dir and exclude_dir settings (from capistrano-scm-copy gem). # These will only apply when using the from_local=true option # set :include_dir, '../.*' # set :exclude_dir, [“../.$”, “../..”, '.././infrastructure'] def set_scm

if ENV['from_local']
  if "#{fetch(:stage)}" == "production"
    run_locally do
      fatal("You are trying to deploy to production using from_local, " +
        "this should pretty much never be done.")
    end
    ask :yes_no, "Are you positive you want to continue?"
    case fetch(:yes_no).chomp.downcase
    when "yes"
    when "no"
      exit
    else
      warn "Please enter 'yes' or 'no'"
      set_scm
    end
  end
  set :scm, :copy
else
  set :scm, :git
end

end set_scm

# File lib/deployinator/built-in.rb, line 70
def deploy_run_bluepill(host)
  warn "Starting a new container named #{fetch(:ruby_container_name)} on #{host}"
  execute(
    "docker", "run", "--tty", "--detach",
    "--name", fetch(:ruby_container_name),
    "-e", "APP_STAGE=#{fetch(:stage)}",
    "-e", "RAILS_ROOT=#{current_path}",
    "-e", "GEM_HOME=#{shared_path.join('bundle')}",
    "-e", "GEM_PATH=#{shared_path.join('bundle')}",
    "-e", "BUNDLE_GEMFILE=#{current_path.join('Gemfile')}",
    "-e", "PATH=#{shared_path.join('bundle', 'bin')}:$PATH",
    fetch(:deploy_custom_container_options),
    "--restart", "always", "--memory", "#{fetch(:ruby_container_max_mem_mb)}m",
    "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
    "--entrypoint", shared_path.join('bundle', 'bin', 'bluepill'),
    fetch(:ruby_image_name), "load",
    current_path.join('config', 'bluepill.rb')
  )
end
deploy_run_bluepill_jobs(host) click to toggle source
# File lib/deployinator/built-in.rb, line 105
def deploy_run_bluepill_jobs(host)
  execute(
    "docker", "run", "--tty", "--detach",
    "-w", current_path,
    "--user", fetch(:webserver_username),
    "--name", fetch(:ruby_jobs_container_name),
    "-e", "APP_STAGE=#{fetch(:stage)}",
    "-e", "RAILS_ROOT=#{current_path}",
    "-e", "GEM_HOME=#{shared_path.join('bundle')}",
    "-e", "GEM_PATH=#{shared_path.join('bundle')}",
    "-e", "BUNDLE_GEMFILE=#{current_path.join('Gemfile')}",
    "-e", "PATH=#{shared_path.join('bundle', 'bin')}:$PATH",
    fetch(:deploy_custom_container_options),
    "--restart", "always", "--memory", "#{fetch(:ruby_jobs_container_max_mem_mb)}m",
    "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
    "--entrypoint", shared_path.join('bundle', 'bin', 'rabid_jobs_tasker'),
    fetch(:ruby_image_name), "--rails_root", current_path,
    "--environment", fetch(:rails_env), "--pid", "#{fetch(:webserver_socket_path)}/jobs.pid", "--maxworkers", "3"
  )
end
deploy_run_cadvisor(host) click to toggle source
# File lib/deployinator/built-in.rb, line 125
def deploy_run_cadvisor(host)
  execute(
    "docker", "run", "--detach",
    "--name", "cadvisor",
    "--volume", "/:/rootfs:ro",
    "--volume", "/var/run:/var/run:rw",
    "--volume", "/sys:/sys:ro",
    "--volume", "/var/lib/docker/:/var/lib/docker:ro",
    "--publish", "127.0.0.1:8080:8080",
    "--restart", "always",
    "google/cadvisor:latest"
  )
end
deployment_user_setup(templates_path) click to toggle source
# File lib/deployinator/helpers.rb, line 39
def deployment_user_setup(templates_path)
  require 'erb'
  name = fetch(:deployment_username)
  unix_user_add(name) unless unix_user_exists?(name)
  execute "usermod", "-a", "-G", "sudo,docker,#{fetch(:webserver_username)}", name
  execute "mkdir", "-p", "/home/#{name}/.ssh"
  template_path = File.expand_path("./#{templates_path}/deployment_authorized_keys.erb")
  generated_config_file = ERB.new(File.new(template_path).read).result(binding)
  # upload! does not yet honor "as" and similar scoping methods
  upload! StringIO.new(generated_config_file), "/tmp/authorized_keys"
  execute "mv", "-b", "/tmp/authorized_keys", "/home/#{name}/.ssh/authorized_keys"
  execute "chown", "-R", "#{name}:#{name}", "/home/#{name}"
  execute "chmod", "700", "/home/#{name}/.ssh"
  execute "chmod", "600", "/home/#{name}/.ssh/authorized_keys"
end
directory_exists?(dir) click to toggle source
# File lib/deployinator/helpers.rb, line 189
def directory_exists?(dir)
  test "[", "-d", dir, "]"
end
file_exists?(file) click to toggle source
# File lib/deployinator/helpers.rb, line 185
def file_exists?(file)
  test "[", "-f", file, "]"
end
files_in_directory?(dir) click to toggle source
# File lib/deployinator/helpers.rb, line 193
def files_in_directory?(dir)
  test("[", "\"$(ls", "-A", "#{dir})\"", "]")
end
localhost_port_responding?(port) click to toggle source
# File lib/deployinator/helpers.rb, line 164
def localhost_port_responding?(port)
  test "nc", "127.0.0.1", port, "<", "/dev/null", ">", "/dev/null;",
    "[", "`echo", "$?`", "-eq", "0", "]"
end
restart_container(name) click to toggle source
# File lib/deployinator/helpers.rb, line 158
def restart_container(name)
  warn "Restarting a running container named #{name}"
  execute("docker", "restart", name)
  check_stayed_running(name)
end
setup_file_permissions() click to toggle source

TODO when replacing this method with the new one, make sure the releases dir itself gets permissioned, just not it's contents.

# File lib/deployinator/helpers.rb, line 56
def setup_file_permissions

  ignore_options = fetch(:ignore_permissions_dirs).collect do |dir|
    ["-not", "-path", "\"#{dir}\"", "-not", "-path", "\"#{dir}/*\""]
  end
  ignore_options += ["-not", "-path", "\"#{fetch(:deploy_to)}/releases/*\""]
  chown_ignore_options = fetch(:webserver_owned_dirs).collect do |dir|
    ["-not", "-path", "\"#{dir}\"", "-not", "-path", "\"#{dir}/*\""]
  end

  # chown webserver owned
  fetch(:webserver_owned_dirs).each do |dir|
    if directory_exists?(dir)
      execute "find", dir, ignore_options,
        '\(', "-not", "-user", fetch(:webserver_username), "-or",
        "-not", "-group", fetch(:webserver_username), '\)',
        "-print0", "|", "xargs", "--no-run-if-empty", "--null",
        "chown", "#{fetch(:webserver_username)}:#{fetch(:webserver_username)}"
    else
      execute "mkdir", "-p", dir
      execute "chown", "#{fetch(:webserver_username)}:#{fetch(:webserver_username)}", dir
    end
  end

  # chown
  execute "find", fetch(:deploy_to), ignore_options, chown_ignore_options,
    '\(', "-not", "-user", fetch(:deployment_username), "-or",
    "-not", "-group", fetch(:webserver_username), '\)',
    "-print0", "|", "xargs", "--no-run-if-empty", "--null",
    "chown", "#{fetch(:deployment_username)}:#{fetch(:webserver_username)}"

  # chmod executable
  fetch(:webserver_executable_dirs).each do |dir|
    if directory_exists?(dir)
      execute "find", dir, "-type", "f",
        "-not", "-perm", "0750",
        "-print0", "|", "xargs", "--no-run-if-empty", "--null", "chmod", "0750"
    # else # don't do this mkdir because it gets run as root and doesn't chown parent dirs
    #   execute "mkdir", "-p", dir
    #   execute "chown", "#{fetch(:deployment_username)}:#{fetch(:webserver_username)}", dir
    end
    ignore_options += ["-not", "-path", "\"#{dir}\"", "-not", "-path", "\"#{dir}/*\""]
  end

  # chmod writable
  fetch(:webserver_writeable_dirs).each do |dir|
    if directory_exists?(dir)
      execute "find", "-L", dir, "-type", "d",
        "-not", "-perm", "2770",
        "-print0", "|", "xargs", "--no-run-if-empty", "--null", "chmod", "2770"
      execute "find", "-L", dir, "-type", "f",
        "-not", "-perm", "0660",
        "-print0", "|", "xargs", "--no-run-if-empty", "--null", "chmod", "0660"
    else
      execute "mkdir", "-p", dir
      execute "chown", "#{fetch(:deployment_username)}:#{fetch(:webserver_username)}", dir
      execute "chmod", "2770", dir
    end
    ignore_options += ["-not", "-path", "\"#{dir}\"", "-not", "-path", "\"#{dir}/*\""]
  end

  # chmod
  execute "find", fetch(:deploy_to), "-type", "d", ignore_options,
    "-not", "-perm", "2750",
    "-print0", "|", "xargs", "--no-run-if-empty", "--null", "chmod", "2750"
  execute "find", fetch(:deploy_to), "-type", "f", ignore_options,
    "-not", "-perm", "0640",
    "-print0", "|", "xargs", "--no-run-if-empty", "--null", "chmod", "0640"
end
sshkit_bundle_command_map() click to toggle source
# File lib/deployinator/built-in.rb, line 157
def sshkit_bundle_command_map
  [
    "/usr/bin/env docker run --rm --tty",
    "--user", fetch(:deployment_username),
    "-e", "GEM_HOME=#{shared_path.join('bundle')}",
    "-e", "GEM_PATH=#{shared_path.join('bundle')}",
    "-e", "PATH=#{shared_path.join('bundle', 'bin')}:$PATH",
    "--volume", "#{fetch(:deploy_to)}:#{fetch(:deploy_to)}:rw",
    "--volume", "$SSH_AUTH_SOCK:/ssh-agent:rw", "--env SSH_AUTH_SOCK=/ssh-agent",
    "--volume", "/home:/home:rw",
    "--volume", "/etc/passwd:/etc/passwd:ro",
    "--volume", "/etc/group:/etc/group:ro",
    "--entrypoint", "#{shared_path.join('bundle', 'bin', 'bundle')}",
    fetch(:ruby_image_name)
  ].join(' ')
end
start_container(name) click to toggle source
# File lib/deployinator/helpers.rb, line 152
def start_container(name)
  warn "Starting an existing but non-running container named #{name}"
  execute("docker", "start", name)
  check_stayed_running(name)
end
unix_user_add(user) click to toggle source
# File lib/deployinator/helpers.rb, line 173
def unix_user_add(user)
  execute "adduser", "--disabled-password", "--gecos", "\"\"", user
end
unix_user_exists?(user) click to toggle source
# File lib/deployinator/helpers.rb, line 169
def unix_user_exists?(user)
  test "bash", "-c", "\"id", user, "&>", "/dev/null\""
end
unix_user_get_gid(user) click to toggle source
# File lib/deployinator/helpers.rb, line 181
def unix_user_get_gid(user)
  capture("id", "-g", user).strip
end
unix_user_get_uid(user) click to toggle source
# File lib/deployinator/helpers.rb, line 177
def unix_user_get_uid(user)
  capture("id", "-u", user).strip
end