class DG::Docker
Constants
- BASEPATH
- CACHE_FILES
- FIG_GEN_PATH
- FIG_YML_PATH
- SUDO
Public Class Methods
build()
click to toggle source
# File lib/dg/docker.rb, line 24 def build reset_mtimes build_docker_image_with_tag end
debug()
click to toggle source
# File lib/dg/docker.rb, line 29 def debug generate_fig_yaml debug_app end
deploy()
click to toggle source
# File lib/dg/docker.rb, line 59 def deploy required_envs = %w(GO_HOST GO_USER GO_PWD) unless required_envs.reduce{ |acc, e| acc && ENV[e] } error!( RuntimeError.new("Environment variables {#{required_envs.join(', ')}} must be set"), 'triggering pipeline' ) end puts "Triggering deploys for: #{deploy_stages.inspect}" deploy_stages.each do |deploy_stage| schedule_pipeline(project_name, deploy_stage, git_image_name) end end
deploy_check()
click to toggle source
# File lib/dg/docker.rb, line 43 def deploy_check required_envs = %w(GO_HOST GO_USER GO_PWD) unless required_envs.reduce{ |acc, e| acc && ENV[e] } error!( RuntimeError.new("Environment variables {#{required_envs.join(', ')}} must be set"), 'checking if pipeline exists' ) end puts "Checking existance of pipeline docker-#{project_name}-{#{deploy_stages.join('|')}}" deploy_stages.each do |deploy_stage| pipeline_check(project_name, deploy_stage) end end
deploy_stages()
click to toggle source
# File lib/dg/docker.rb, line 75 def deploy_stages @@deploy_stages_cached ||= begin generate_fig_yaml branch = ENV['GIT_BRANCH'] || `git symbolic-ref --short -q HEAD`.strip run_with_output( %(docker run --entrypoint=ruby -e GIT_BRANCH=#{branch} #{git_image_name} /u/app/deploy-to.rb), capture = true ).strip.split(',') end end
purge()
click to toggle source
# File lib/dg/docker.rb, line 34 def purge run_with_output("docker rm $(docker ps -a -q) && docker rmi $(docker images -q)") end
push()
click to toggle source
# File lib/dg/docker.rb, line 38 def push run_with_output("docker push #{git_image_name}") run_with_output("docker push #{latest_image_name}") end
run()
click to toggle source
# File lib/dg/docker.rb, line 88 def run generate_fig_yaml run_app end
test()
click to toggle source
# File lib/dg/docker.rb, line 93 def test generate_fig_yaml run_tests end
version()
click to toggle source
# File lib/dg/docker.rb, line 98 def version puts "v#{DG::VERSION}" end
Also aliased as: v
Private Class Methods
build_docker_image_with_tag()
click to toggle source
# File lib/dg/docker.rb, line 206 def build_docker_image_with_tag run_with_output("docker build -t #{git_image_name} #{BASEPATH}") run_with_output("docker tag #{git_image_name} #{latest_image_name}") rescue => e error!(e, "building docker image") end
debug_app()
click to toggle source
# File lib/dg/docker.rb, line 223 def debug_app puts "docker run -it --entrypoint=/bin/bash #{git_image_name}" end
error!(e, step = "executing")
click to toggle source
# File lib/dg/docker.rb, line 111 def error!(e, step = "executing") STDERR.puts "An error occurred while #{step}: #{e.message}" exit 1 end
fig_binary()
click to toggle source
# File lib/dg/docker.rb, line 105 def fig_binary @@fig_binary_cached ||= %w(docker-compose fig).detect do |binary| run_with_output(%(which #{binary}), false, return_hash = true)[:status_code] == 0 end end
fig_yml()
click to toggle source
# File lib/dg/docker.rb, line 146 def fig_yml @@fig_yml ||= File.read(FIG_YML_PATH) rescue => e error!(e, "reading fig.yml from #{FIG_YML_PATH}") end
generate_fig_yaml()
click to toggle source
# File lib/dg/docker.rb, line 172 def generate_fig_yaml File.write( FIG_GEN_PATH, fig_yml.sub(image_name, git_image_name) ) rescue => e error!(e, "generating new fig.yml") end
git_image_name()
click to toggle source
Add the git commit hash to the image name
# File lib/dg/docker.rb, line 162 def git_image_name @@git_image_name ||= "#{image_name}:#{ENV['GIT_COMMIT'] || `git rev-parse HEAD`.strip}" end
help()
click to toggle source
# File lib/dg/docker.rb, line 277 def help puts "Usage: dg COMMAND A helper for building, testing, and running docker images via docker & fig. Commands: build Build an image based on your fig.yml (tags with the project's Git commit hash) debug Debug a previously built image (!) THIS MUST BE RUN IN A SUBSHELL: `$(dg debug)` deploy Trigger the GoCD pipeline for this project help Display this help text purge Remove ALL docker containers and images (not just for this project!) push Push the image to your docker registry run Run the image using your fig.yml's `web` config test Run the image using your fig.yml's `test` config version Display the current dg version ".gsub(/^ {6}/,'') end
Also aliased as: h
image_name()
click to toggle source
Infer the project name from the image specified in the fig.yml
# File lib/dg/docker.rb, line 157 def image_name @@image_name ||= fig_yml.match(/\s+image: (.*)/)[1] end
latest_image_name()
click to toggle source
# File lib/dg/docker.rb, line 168 def latest_image_name "#{image_name}:latest" end
pipeline_check(project_name, deploy_stage)
click to toggle source
# File lib/dg/docker.rb, line 227 def pipeline_check(project_name, deploy_stage) pipeline_name = "docker-#{project_name}-#{deploy_stage}" uri = URI("https://#{ENV['GO_HOST']}/go/api/pipelines/#{pipeline_name}/status") request = Net::HTTP::Get.new(uri.path) request.basic_auth ENV['GO_USER'], ENV['GO_PWD'] response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| http.verify_mode = OpenSSL::SSL::VERIFY_NONE http.ssl_version = :SSLv3 http.request(request) end if response.code.to_i == 200 puts "Pipeline [#{pipeline_name}] exists" else error!( RuntimeError.new( "response code was #{response.code}: #{response.body.strip}" ), "checking pipeline status for [#{pipeline_name}]" ) end end
project_name()
click to toggle source
# File lib/dg/docker.rb, line 152 def project_name @@project_name ||= ENV['GO_PIPELINE_NAME'] || image_name.split('/').last end
reset_mtimes()
click to toggle source
# File lib/dg/docker.rb, line 181 def reset_mtimes CACHE_FILES.each do |file| next unless File.exist?(file) revision = run_with_output( %(git rev-list -n 1 HEAD '#{file}'), capture = true, return_hash = true ) if revision[:status_code] == 0 # File exists, find out its last modified time from git # FileUtils.touch('example.txt', mtime: Time.now) time = Time.parse( run_with_output( %(git show --pretty=format:%ai --abbrev-commit #{ revision[:stdout].strip} | head -n 1), capture = true, return_hash = true )[:stdout].strip ) FileUtils.touch(file, mtime: time) puts "Setting mtime for #{file} to #{time}" end end end
run_app()
click to toggle source
# File lib/dg/docker.rb, line 219 def run_app run_with_output("#{fig_binary} -f #{FIG_GEN_PATH} up -d web") end
run_tests()
click to toggle source
# File lib/dg/docker.rb, line 213 def run_tests run_with_output("#{fig_binary} -f #{FIG_GEN_PATH} run --rm test") rescue => e error!(e, "running tests") end
run_with_output(command, capture = false, return_hash = false)
click to toggle source
# File lib/dg/docker.rb, line 116 def run_with_output(command, capture = false, return_hash = false) sudo_command = SUDO ? "sudo -E bash -c '#{command}'" : command puts "Running `#{sudo_command}` #{return_hash ? '(quietly)' : ''} in #{Dir.pwd}" begin buffer = '' PTY.spawn(sudo_command) do |stdout, stdin, pid| callback = (capture || return_hash) ? ->(char) { print char unless return_hash buffer << char } : ->(char) { print char } stdout.each_char(&callback) rescue Errno::EIO Process.wait(pid) end status_code = $?.exitstatus error!( RuntimeError.new("exit code was #{status_code}"), "executing #{command}" ) if !return_hash && status_code != 0 return { stdout: buffer, status_code: status_code } if return_hash return capture ? buffer : status_code rescue PTY::ChildExited puts "The child process exited!" end end
schedule_pipeline(project_name, deploy_stage, image_id)
click to toggle source
# File lib/dg/docker.rb, line 251 def schedule_pipeline(project_name, deploy_stage, image_id) pipeline_name = "docker-#{project_name}-#{deploy_stage}" puts "Triggering pipeline: #{pipeline_name} on #{ENV['GO_HOST']}" uri = URI("https://#{ENV['GO_HOST']}/go/api/pipelines/#{pipeline_name}/schedule") request = Net::HTTP::Post.new(uri.path) request.basic_auth ENV['GO_USER'], ENV['GO_PWD'] request.set_form_data({ 'variables[IMAGE_ID]' => git_image_name }) response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| http.verify_mode = OpenSSL::SSL::VERIFY_NONE http.ssl_version = :SSLv3 http.request(request) end if response.code.to_i == 202 puts response.body.strip else error!( RuntimeError.new( "response code was #{response.code}: #{response.body.strip}" ), "scheduling pipeline" ) end end