require 'rubygems/package' require 'zlib' require 'picsolve_docker_builder/frame' require 'picsolve_docker_builder/builder/builder' module PicsolveDockerBuilder # Build a scala project class Scala < Frame def default_config c = super c['scala'] = { 'sbt' => { 'build_task' => [ 'clean test universal:packageZipTarball' ] } } c end def prepare_volumes volumes = volumes_sbt.map do |v| v[1] end cmd = [ 'chown', '-c', build_user, build_user_home ] cmd += volumes execute cmd end def docker_build_files f = [] f << Builder::File.new( 'app.tar.gz', source: universal_tar_gz, destination: '/opt' ) unless run_script.nil? f << Builder::File.new( run_script[:destination], run_script ) end f end def docker_builder Builder::Builder.new( base_image: image_name, maintainer: 'Picsolve Onlineops ', ports: [9000], hooks: { before_adds: [ '# add play users', 'RUN groupadd -r play && \\', ' useradd -r -g play play', '# create pid dir', 'RUN mkdir -p /var/run/play && \\', ' chown play:play /var/run/play' ], after_adds: [ '# chown app directories', 'RUN chown -R play:play /opt' ] }, command: ['gosu', 'play', bin_path], files: docker_build_files ) end def docker_build @docker_build = docker_builder.build end def dirs_sbt [ '.sbt', '.ivy2', '.m2' ] end def bin_path @bin_path ||= detect_bin_path end def detect_bin_path path = universal_bin_path unless path.nil? log.debug "run script detected in '#{path}'" return path end path = run_script unless path.nil? path = run_script[:destination] log.debug "run script detected in '#{path}'" return path end fail 'No run script detected' end def run_script @run_script ||= detect_run_script end def detect_run_script path = run_script_path return nil unless File.exist? path basename = ::File.basename(path) { basename: basename, source: path, destination: "/#{basename}" } end def run_script_path File.join(base_dir, 'run.sh') end def volumes_sbt dirs_sbt.map do |dir| [ File.join(base_dir, dir), File.join(build_user_home, dir) ] end end def volumes_array super + volumes_sbt end def sbt_command return @sbt_command unless @sbt_command.nil? runs = config['scala']['sbt']['build_task'].map do |tasks| "sbt #{tasks}" end runs.join ' && ' end def sbt_lib_snapshot @sbt_command = 'sbt clean update test publish' build end def sbt_lib_release @sbt_command = "sbt clean test \"release cross with-defaults\"" build end def asset_build log.info "start asset building with image #{image_name}" start prepare_volumes build_cmd = [ 'gosu', build_user, 'bash', '-c', sbt_command ] execute_attach build_cmd log.info "finished asset building with image #{image_name}" stop end def universal_bin_path Zlib::GzipReader.open(universal_tar_gz) do |gunzip| gunzip_io = StringIO.new(gunzip.read) Gem::Package::TarReader.new gunzip_io do |tar| tar.each do |entry| next unless entry.file? next unless entry.full_name.match(%r{/bin}) next if entry.full_name.match(/\.bat$/) return File.join('/opt', entry.full_name) end end end nil end def universal_tar_gz build_asset_glob = File.join(base_dir, 'target/**/*.tgz') tgz_files = Dir.glob(build_asset_glob) fail "no universal_tar_gz found: #{build_asset_glob}" \ if tgz_files.length < 1 fail "more than one universal_tar_gz found: #{build_asset_glob}" \ if tgz_files.length > 1 tgz_files[0] end end end