class CIDE::CLI

Command-line option-parsing and execution for cide

Constants

LINE_WIDTH

Public Instance Methods

clean() click to toggle source
# File lib/cide/cli.rb, line 285
def clean
  days_to_keep = options[:days]
  max_images = options[:count]

  # Delete failed images
  failed_filter = 'label=cide.build.complete=false'
  cide_failed_image_ids = docker_image_ids(filter_by: failed_filter)
  if cide_failed_image_ids.any?
    docker('rmi', '--force', *cide_failed_image_ids)
  end

  # Retrieve all other cide images
  cide_image_ids = docker_image_ids(filter_by: 'label=cide')

  if cide_image_ids.empty?
    puts 'No images found to be cleaned'
    return
  end

  x = docker('inspect', *cide_image_ids, capture: true)
  cide_images =
    JSON
    .parse(x.strip)
    .each { |image| image['Created'] = Time.iso8601(image['Created']) }
    .sort { |a, b| a['Created'] <=> b['Created'] }

  to_destroy = cide_images[max_images..-1]
  leftover_images = cide_images[0..(max_images - 1)]

  expire_from = Time.now - (days_to_keep * 24 * 60 * 60)
  to_destroy <<
    leftover_images.select { |image| image['Created'] < expire_from }

  to_destroy_ids = to_destroy.map { |image| image['Id'] }

  if to_destroy_ids.empty?
    puts 'No images found to be cleaned'
    return
  end

  docker('rmi', '--force', *to_destroy_ids)
end
debug() click to toggle source
# File lib/cide/cli.rb, line 248
def debug
  tag = name_to_tag options.name

  ## Config ##
  banner 'Config'
  config = ConfigFile.load(Dir.pwd)
  say_status :config, config.inspect

  ## Run ##
  banner 'Run'
  runner = Runner.new(
    command: ['bash'],
    env: config.env,
    links: config.links,
    tag: tag,
    user: options.user,
  )
  runner.run!(interactive: true)

rescue Docker::Error => ex
  exit ex.exitstatus
rescue RuntimeError => ex
  $stderr.puts ex.to_s
  exit 1
ensure
  runner.cleanup! if runner
end
exec() click to toggle source
# File lib/cide/cli.rb, line 59
def exec
  tag = name_to_tag options.name

  banner 'Config'
  config = ConfigFile.load(Dir.pwd)
  say_status :config, config.inspect

  ## Build ##
  banner 'Build'
  builder = Builder.new(config)
  builder.build(
    pull: options.pull,
    ssh_key: File.expand_path(options.ssh_key),
    tag: tag,
  )

  ## Run ##
  banner 'Run'

  command = options.run ? ['sh', '-e', '-c', options.run] : config.run

  runner = Runner.new(
    command: command,
    env: config.env,
    links: config.links,
    tag: tag,
  )
  runner.run!

  ## Export ##
  return unless options.export
  banner 'Export'

  guest_dir = options.guest_export_dir || config.export_dir
  if guest_dir.nil?
    puts 'Ignoring, missing export_dir'
    return
  end

  runner.export!(
    guest_dir: guest_dir,
    host_dir: options.export_dir || config.export_dir,
  )
rescue Docker::Error => ex
  exit ex.exitstatus
rescue RuntimeError => ex
  $stderr.puts ex.to_s
  exit 1
ensure
  runner.cleanup! if runner
end
init() click to toggle source
# File lib/cide/cli.rb, line 329
def init
  puts "Creating #{CONFIG_FILES.first} with default values"
  create_file CONFIG_FILES.first, File.read(DEFAULT_CIDEFILE)
end
package() click to toggle source
# File lib/cide/cli.rb, line 141
def package
  raise 'missing AWS_BUCKET' if options.upload && !options.aws_bucket

  tag = name_to_tag options.name

  build_root = File.expand_path('.package')
  guest_export_dir = '/cide/package'
  host_export_dir  = File.join(build_root, 'package')

  FileUtils.rm_rf(build_root)

  build_id = options.build_id || (
    timestamp = Time.now.strftime('%Y-%m-%d_%H%M%S')
    git_branch = `git symbolic-ref --short -q HEAD || echo unknown`.strip
    git_rev = `git rev-parse --short HEAD`.strip
    "#{timestamp}.#{git_branch}-#{git_rev}"
  )

  tar_name = "#{options.package}.#{build_id}.tar.gz"
  tar_path = File.join(build_root, tar_name)

  banner 'Config'
  config = ConfigFile.load(Dir.pwd)
  say_status :config, config.inspect

  version_data =
    case config.package && config.package.add_version
    when 'sha'
      `git rev-parse HEAD`.strip
    when 'short_sha'
      `git rev-parse --short HEAD`.strip
    when 'auto'
      build_id
    end

  ## Build ##
  banner 'Build'
  builder = Builder.new(config)
  builder.build(
    pull: options.pull,
    ssh_key: File.expand_path(options.ssh_key),
    tag: tag,
  )

  ## Run ##
  banner 'Run'
  runner = Runner.new(
    command: ['script/build', guest_export_dir],
    env: config.env,
    links: config.links,
    tag: tag,
  )
  runner.run!

  ## Export ##
  banner 'Export'

  runner.export!(
    guest_dir: guest_export_dir,
    host_dir: host_export_dir,
  )

  ## Set version ##
  if version_data
    version_file = File.join(host_export_dir, '.packager', 'version')
    FileUtils.mkdir_p(File.dirname(version_file))
    File.open(version_file, 'w') do |f|
      f.puts version_data
    end
  end

  # Create archive
  puts "Package: #{tar_name}"
  system('tar', '-czf', tar_path, '-C', host_export_dir, '.')

  ## Upload ##

  return unless options.upload
  banner 'Upload'

  require 'aws-sdk'
  s3 = Aws::S3::Client.new
  resp = s3.put_object(
    bucket: options.aws_bucket,
    key: tar_name,
    body: File.open(tar_path),
  )
  p resp
rescue Docker::Error => ex
  exit ex.exitstatus
rescue RuntimeError => ex
  $stderr.puts ex.to_s
  exit 1
ensure
  FileUtils.rm_rf(build_root) if options.upload

  runner.cleanup! if runner
end

Private Instance Methods

banner(text) click to toggle source
name_to_tag(name) click to toggle source

Prefixes the tag to make it recognizable by the cleaner Makes sure it's a valid tag

# File lib/cide/cli.rb, line 338
def name_to_tag(name)
  "cide/#{CIDE::Docker.id name}"
end