aws / aws-codedeploy-agent

Host Agent for AWS CodeDeploy
https://aws.amazon.com/codedeploy
Apache License 2.0
329 stars 187 forks source link

Must explicitly specify gemfile if using bundler inside hook scripts #7

Closed ejhayes closed 9 years ago

ejhayes commented 9 years ago

I noticed this issue with on of my hook scripts and didn't seem to find this gotcha mentioned in the docs. Maybe this is an obivous thing to know, but I figured I'd put a note here just incase someone else runs into this:

Here's what I was attempting to run in my hook script:

...
bundle --deployment
...

Seemed pretty normal except I kept getting error messages like this:

...
[stdout]The --deployment flag requires a Gemfile.lock. Please make sure you have checked
[stdout]your Gemfile.lock into version control before deploying.
...

I went to go look at the source and found that a Gemfile is actually getting set here: https://github.com/aws/aws-codedeploy-agent/blob/master/lib/instance_agent.rb#L9

This means that bundler is set to use that Gemfile even if we are running bundler from a different directory in our hook scripts. This issue was discussed in this ticket:

https://github.com/bundler/bundler/issues/1981

Here's the area where the codedeploy-agent shells out to the hook scripts:

https://github.com/aws/aws-codedeploy-agent/blob/master/lib/instance_agent/codedeploy_plugin/hook_executor.rb#L113

...
Open3.popen3(script_command, :pgroup => true) do |stdin, stdout, stderr, wait_thr|
  stdin.close
  stdout_thread = Thread.new{stdout.each_line { |line| log_script("[stdout]" + line.to_s, script_log_file)}}
  stderr_thread = Thread.new{stderr.each_line { |line| log_script("[stderr]" + line.to_s, script_log_file)}}
  if !wait_thr.join(script.timeout)
    Process.kill('-TERM', wait_thr.pid) #kill the process group instead of pid
    raise Timeout::Error
  end
  stdout_thread.join
  stderr_thread.join
  exit_status = wait_thr.value.exitstatus
end
...

Here's some options I found that can resolve this issue:

BUNDLE_GEMFILE=$PWD/Gemfile bundle
...
tmp_gemfile = ENV.delete('BUNDLER_GEMFILE')
Open3.popen3(script_command, :pgroup => true) do |stdin, stdout, stderr, wait_thr|
  stdin.close
  stdout_thread = Thread.new{stdout.each_line { |line| log_script("[stdout]" + line.to_s, script_log_file)}}
  stderr_thread = Thread.new{stderr.each_line { |line| log_script("[stderr]" + line.to_s, script_log_file)}}
  if !wait_thr.join(script.timeout)
    Process.kill('-TERM', wait_thr.pid) #kill the process group instead of pid
    raise Timeout::Error
  end
  stdout_thread.join
  stderr_thread.join
  exit_status = wait_thr.value.exitstatus
end
ENV['BUNDLER_GEMFILE'] = tmp_gemfile unless tmp_gemfile.nil?
...
suryanarayanan commented 9 years ago

Hi,

Thanks for reporting this. This is a known issue on our end and we have a fix for it. It will be available in the next release of codedeploy-agent.

Thanks, Surya.

suryanarayanan commented 9 years ago

This issue has been fixed. Resolving.