class RubyYacht::Runner::BuildImages

This command builds the images for the system.

Public Class Methods

command() click to toggle source

The identifier for the command.

# File lib/ruby_yacht/runner/build_images.rb, line 7
def self.command; 'build_images'; end
description() click to toggle source

The description for the command.

# File lib/ruby_yacht/runner/build_images.rb, line 10
def self.description
  "Build images for your environment"
end

Public Instance Methods

build_image(folder_name, image_name = nil) click to toggle source

This method builds an image.

This will copy a Dockerfile template from a folder underneath the ‘images` folder, as well as any other files in that folder, into the tmp folder. It will then evaluate the Dockerfile.erb file, using the binding from the current context, and write it to the Dockerfile in the tmp folder. It will then build the image, and clear out the tmp folder.

Depending on the image type, it may also copy and interpret other template files. For instance, for app containers we also have erb files for the ‘startup.bash` and `before_startup.bash` scripts.

### Parameters

  • **folder_name: String** The name of the folder containing the

    Dockerfile and related files.
  • **image_name: String** The name for the new image. If this is not

    provided, the image name will be the
    current project's prefix, followed by a
    dash, followed by the folder name.
# File lib/ruby_yacht/runner/build_images.rb, line 85
def build_image(folder_name, image_name = nil)
  Dir[File.join(File.dirname(File.dirname(__FILE__)), 'images', folder_name, '*')].each do |path|
    FileUtils.cp(path, File.join('tmp', File.basename(path)))
  end

  set_image_settings(folder_name)

  fetch_behaviors(@hook_servers, @hook_events).each do |behavior|
    next unless behavior.is_a?(RubyYacht::Hook::CopyFileBehavior)
    FileUtils.cp behavior.file_path, "tmp"
  end

  @templates.each do |template_name|
    File.open(File.join('tmp', template_name), 'w') do |file|
      template_contents = File.read(File.join('tmp', template_name + '.erb'))
      file_contents = ERB.new(template_contents, nil, '<>').result(binding)
      file_contents.gsub!(/\n\n\n+/, "\n\n")
      file_contents.gsub!(/\n*\Z/, "")
      file.write(file_contents)
    end
  end
  
  image_name ||= "#{@project.system_prefix}-#{folder_name}"

  docker "build -t #{image_name} tmp"
  
  FileUtils.rm(Dir[File.join("tmp", "*")])
end
build_images(project) click to toggle source

This method builds the images for a project.

### Parameters

  • **project: Project** The project we are building.

# File lib/ruby_yacht/runner/build_images.rb, line 37
def build_images(project)
  @project = project
  project.apps.map(&:server_type).uniq.each do |type_name|
    @server_type = RubyYacht.configuration.find_server_type(type_name)
    build_image 'app-dependencies', "#{@project.system_prefix}-#{@server_type.name}-app-dependencies"
  end
  
  @app_server_type = RubyYacht.configuration.find_server_type(project.apps.first.server_type)
  project.databases.select(&:local?).each do |database|
    @database = database
    @server_type = RubyYacht.configuration.find_server_type(@database.server_type)
    build_image 'database', @database.container_name
  end
  @database = nil
  
  @project.apps.each do |app|
    @app = app
    @server_type = RubyYacht.configuration.find_server_type(@app.server_type)
    build_image 'app', @app.container_name
  end
  @app = nil

  project.web_servers.each do |server|
    @server = server
    build_image 'web', @server.container_name
  end
end
copy_hooks(servers, event_types) click to toggle source

This method includes commands for copying script files for the hooks for the current app type.

### Parameters

  • **servers: Database/App/Array**: The server or servers whose hooks we

    are running.
  • **event_types: [Symbol]** The events whose hooks we should include.

### Returns

A String with the contents of the Dockerfile for copying the script.

# File lib/ruby_yacht/runner/build_images.rb, line 215
def copy_hooks(servers, event_types)
  result = ""
  
  fetch_behaviors(servers, event_types).each do |behavior|
    next unless behavior.is_a?(RubyYacht::Hook::CopyFileBehavior)
    result += behavior.dockerfile_command + "\n"
  end
  result
end
include_event(servers, event_type, times = [:before, :during, :after], options = {}) { || ... } click to toggle source

This method includes the hooks for an event in a Dockerfile.

It will run the commands for the before hooks, then the during hooks, then the after hooks.

### Parameters

  • **servers: Database/App/Array**: The server or servers whose hooks we

    are running.
  • **event_type: Symbol** The event whose hooks we are running.

  • **times: [Symbol]** The event times whose hooks we want to

    include. You can also pass a symbol to this
    method, which will cause it to include only
    that event time.
  • **options: [Hash]** Additional flags for customizing the output.

    At this time, the only option is `in_bash`,
    which indicates whether the commands are
    running in bash rather than a Dockerfile.
  • block This also takes a block, which should yield

    fixed contents for the "during" section of
    the event.

### Returns

A String with the contents of the Dockerfile for running the hooks.

# File lib/ruby_yacht/runner/build_images.rb, line 177
def include_event(servers, event_type, times = [:before, :during, :after], options = {})
  result = ""
  if times.is_a?(Symbol)
    times = [times]
  end
  times.each do |time|
    if time == :during && block_given?
      result += yield
      result += "\n"
      next
    end
    
    fetch_behaviors(servers, [event_type], time).each do |behavior|
      behavior.context = self
      if options[:in_bash]
        result += "#{behavior.shell_command}\n"
      else
        result += "#{behavior.dockerfile_command}\n"
      end
    end
  end
  
  result
end
run() click to toggle source

This method runs the logic for the command.

# File lib/ruby_yacht/runner/build_images.rb, line 15
def run
  FileUtils.mkdir_p 'tmp'
  
  projects.each do |project|
    log "Building images for #{project.name}"
    
    docker "network create #{project.system_prefix} 2> /dev/null"
    id_path = File.join(ENV['HOME'], '.ssh', 'id_rsa')
    tmp_id_path = File.join('tmp', 'id_rsa')
    FileUtils.cp(id_path, tmp_id_path) if File.exist?(id_path)

    build_images(project)
  end
  
  true
end
set_image_settings(folder_name) click to toggle source

This method establishes settings for building an image.

This will set the ‘@templates`, `@hook_events`, and `@hook_servers` instance variables.

### Parameters

  • **folder_name: String** The name of the folder containing the image

    files.
# File lib/ruby_yacht/runner/build_images.rb, line 123
def set_image_settings(folder_name)
  @templates = 
    case folder_name
    when 'app' then ['Dockerfile', 'before_startup.bash', 'startup.bash']
    when 'database' then ['Dockerfile', 'startup.bash']
    when 'web' then ['Dockerfile']
    else ['Dockerfile']
    end

  @hook_events =
    case folder_name
    when 'app' then [:startup, :build_checkout, :build_new_app, :cleanup]
    when 'app-dependencies' then [:initialize_app_environment, :install_libraries, :cleanup]
    when 'database' then [:create_databases, :install_libraries, :load_database_seeds, :cleanup]
    when 'web' then [:install_libraries, :add_project_landing, :add_app_config, :cleanup]
    else []
    end
    
  @hook_servers =
    case folder_name
    when 'database' then [@database]
    when 'app' then [@app]
    when 'app-dependencies' then @project.apps
    when 'web' then [@server]
    else []
    end
end

Private Instance Methods

fetch_behaviors(servers, event_types, event_time = nil) click to toggle source

This method fetches the behaviors for the hooks for an event.

  • **servers: Database/App/Array**: The server or servers whose hooks we

    are running.
  • **event_types: Array**: The events for the hooks we are running.

  • **event_time: Symbol**: The time relative to the event for the hooks

    we are running. If this is nil, it will
    include all event times.
# File lib/ruby_yacht/runner/build_images.rb, line 236
def fetch_behaviors(servers, event_types, event_time = nil)
  unless servers.is_a?(Array)
    servers = [servers]
  end
  hooks = servers.collect do |server|
    event_types.collect do |type|
      RubyYacht.configuration.fetch_hooks(server, type)
    end
  end.flatten.uniq
  hooks = hooks.select do |hook|
    event_time.nil? || event_time == hook.event_time
  end
  hooks.map(&:behaviors).flatten
end