class Lux::App

The Thor subclass containing useful tasks shared between the Lux standalone executable and Rake tasks.

Constants

EXCLUDE_VARS

Public Instance Methods

check() click to toggle source
# File lib/lux/app.rb, line 19
def check
  repobranch = `git symbolic-ref -q HEAD`.chomp.gsub(%r{^.*/},'')
  puts "Repository is on branch #{repobranch}"
  `git fetch --recurse-submodules=on-demand`
  nModuleErr = 0
  nModuleWarn = 0
  # Inspect any submodules currently checked out
  submodules = Hash[`git submodule status --recursive`.split(/\n/).map do |s|
    Lux.die "Bad submodule status #{s}" unless /^(?<flag>[-+U\s])(?<sha>[0-9a-f]{40})\s(?<path>\S+)(\s*\((?<ref>\S+)\))?$/ =~ s
    case flag
    when '-'
      Highline.say "Submodule at #{path} is <%= color('not initialized', RED) %>!"
      nModuleWarn += 1
    when '+'
      Highline.say "Submodule at #{path} is <%= color('not at correct commit', RED) %>!"
      nModuleErr += 1
    when 'U'
      Highline.say "Submodule at #{path} is <%= color('conflicted', RED) %>!"
      nModuleErr += 1
    else
      Highline.say "Submodule at #{path} is <%= color('OK', GREEN) %>"
    end
    [path, [flag, sha, ref]]
  end ]
  Lux.die "There were #{nModuleErr} submodule errors and #{nModuleWarn} warnings" if nModuleErr > 0
  # If the submodule status (above) was good, then we can ignore any submodule issues here
  changes = `git status --porcelain`.split(/\n/).reject do |ch|
    Lux.die "Bad status #{ch}" unless /^(?<x>.)(?<y>.)\s(?<path1>\S+)( -> (?<path2>\S+))?$/ =~ ch
    submodules.include? path1
  end
  if changes.size > 0
    Lux.die "Repository is not clean (#{changes.size} issues), use 'git status'"
  else
    HighLine.say "<%= color('Repository is clean', GREEN) %>"
  end
end
clean() click to toggle source
# File lib/lux/app.rb, line 100
def clean
  exited = `docker ps -q -f status=exited`.gsub! /\n/,' '
  if exited and not exited.empty?
    system "docker rm #{exited}"
  else
    puts "No exited containers"
  end
end
clobber() click to toggle source
# File lib/lux/app.rb, line 170
def clobber
  clean
  running = `docker ps -q -f status=running`.gsub! /\n/,' '
  if running and not running.empty?
    system "docker rm -f #{running}"
  else
    puts "No running containers"
  end
end
dockerip() click to toggle source
# File lib/lux/app.rb, line 184
def dockerip
  name, uri, info = Lux.dockerip
  return Lux.info "Docker is not available" unless name

  var = 'DOCKER_HOST'
  case uri.scheme
  when 'tcp'
    uri.host = name
    if STDOUT.isatty
      Lux.info "Please export: #{var}=#{uri.to_s}"
      Lux.info "(You can use '$(lux dockerip)' to do this)"
    else
      Lux.info "Exported: #{var}=#{uri.to_s}"
      puts "export #{var}=#{uri.to_s}"
    end
  when 'unix'
      Lux.info "Docker is running on a Unix socket"
  end
  Lux.info "Version #{info['Version']}, OS: #{info['Os']}, Arch: #{info['Arch']}, Kernel: #{info['KernelVersion']}" if info
end
exec(image, *command) click to toggle source
# File lib/lux/app.rb, line 86
def exec(image, *command)
  image = Lux.findimage image
  me, setup_cmd = user_setup_cmd
  Lux.die "You must be within your home directory!" unless relwd = Pathname.pwd.to_s.gsub!(/^#{ENV['HOME']}/,'~')
  command.map!{|m| m.start_with?('/') ? Pathname.new(m).relative_path_from(Pathname.pwd) : m }
  env = ENV.reject{|k,v| EXCLUDE_VARS.include? k or v =~/\s+/}.map{|k,v| "#{k}=#{v.shellescape}"}
  env += IO.readlines(options.env).grep(/^(?!#)/).map(&:rstrip) if options.env
  cmd = setup_cmd + "su - #{me} -c 'cd #{relwd}; env -i #{env.join(' ')} #{command.join(' ')}'"
  args = ["-v #{ENV['HOME']}:#{ENV['HOME']}"]
  args += "--privileged" if options.priv
  system "docker run --rm #{args.join(' ')} #{image} /bin/bash -c #{cmd.shellescape}"
end
lsimages(pattern=nil) click to toggle source
# File lib/lux/app.rb, line 121
def lsimages(pattern=nil)
  if options.regex
    pattern = '.*' unless pattern
    rx = Regexp.new(pattern)
    matcher = lambda {|s| rx.match(s)}
  else
    pattern = '*' unless pattern
    matcher = lambda {|s| File.fnmatch?(pattern, s)}
  end
  imagelines = `docker images`.split("\n")[1..-1].sort
  imagelines.each do |imageline|
    imageinfo = imageline.split(/\s+/)
    next if imageinfo[0] == '<none>'
    imagename = imageinfo[0]+':'+imageinfo[1]
    imagesize = imageinfo[-2]+' '+imageinfo[-1]
    imageage  = imageinfo[3..-3].join(' ')
    next unless matcher.call(imagename)
    printf "%-54s%-16s%10s\n", imagename, imageage, imagesize
  end
end
rmimages(pattern=nil) click to toggle source
# File lib/lux/app.rb, line 145
def rmimages(pattern=nil)
  if options.regex
    pattern = '.*' unless pattern
    rx = Regexp.new(pattern)
    matcher = lambda {|s| rx.match(s)}
  else
    pattern = '*' unless pattern
    matcher = lambda {|s| File.fnmatch?(pattern, s)}
  end
  imagelines = `docker images`.split("\n")[1..-1]
  imagelines.each do |imageline|
    imageinfo = imageline.split(/\s+/)
    next if imageinfo[0] == '<none>'
    imagename = imageinfo[0]+':'+imageinfo[1]
    imagesize = imageinfo[-2]+' '+imageinfo[-1]
    imageage  = imageinfo[3..-3].join(' ')
    next unless matcher.call(imagename)
    if options.force or (agree("Delete #{imagename} (#{imageage}, #{imagesize})? "){|q|q.echo=true})
      `docker rmi #{options.force ? '-f':''} #{imageinfo[2]}`
      HighLine.say "Image <%= color('#{imagename}', RED)%> deleted"
    end
  end
end
start(image) click to toggle source
# File lib/lux/app.rb, line 61
def start(image)
  image = Lux.findimage image
  raise "no image" if image.empty?
  puts "Starting #{image} container..."
  me, setup_cmd = Lux.user_setup_cmd()
  args = ["-v #{ENV['HOME']}:#{ENV['HOME']}"]
  args << "--env-file=#{options.env}" if options.env
  args << "--privileged" if options.priv
  args << "--name=#{options.name}" unless options.name == '<autogenerated>'
  args << (options.port ? "-p #{options.port}" : "-P")
  cid = `docker run -dit #{args.join(' ')} #{image} /bin/bash`.strip
  Lux.die "Container failed to start" unless cid =~ /^[a-z0-9]+$/
  system "docker exec #{cid} bash -c #{setup_cmd.shellescape}"
  puts "Your user and home directory are mapped into the container: Hit Enter then use 'su [-] #{me}'"
  Kernel.exec "docker attach #{cid}"
end
tidy() click to toggle source
# File lib/lux/app.rb, line 110
def tidy
  images = `docker images -f "dangling=true" -q`
  if images.size > 0
    system 'docker rmi $(docker images -f "dangling=true" -q)'
  else
    puts "No dangling images"
  end
end
version() click to toggle source
# File lib/lux/app.rb, line 14
def version
  puts "Version #{Lux::VERSION}"
end