Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vendor libpq5.12.1 into Slugs - Heroku 18 only #936

Merged
merged 13 commits into from
Dec 11, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## v207 (unreleased)

* Vendor in libpq 5.12.1 for Heroku-18 (https://github.com/heroku/heroku-buildpack-ruby/pull/936)
* Remove possibilities of false exceptions being raised by removing `BUNDLED WITH` from the `Gemfile.lock` (https://github.com/heroku/heroku-buildpack-ruby/pull/928)

## v206 (10/15/2019)
Expand Down
15 changes: 15 additions & 0 deletions changelogs/v207/vendor_libpq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Postgresql client library libpq version 5.12.1 now vendored into Ruby applications on Heroku-18

Ruby applications deploying to Heroku-18 will get a vendored version of the libpq client library version 5.12.1 starting today. For more information about the reasons for this change and the possible effects see:

https://devcenter.heroku.com/articles/libpq-5-12-1-breaking-connection-behavior

If your application breaks due to this change you can rollback to your last build. You can also temporarially opt out of this behavior by setting:

```
$ heroku config:set HEROKU_SKIP_LIBPQ12=1
```

In the future libpq 5.12 will be the default on the platform and you will not be able to opt-out of the library. For more information see:

https://devcenter.heroku.com/articles/libpq-5-12-1-breaking-connection-behavior
3 changes: 2 additions & 1 deletion hatchet.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"sharpstone/jruby-minimal",
"sharpstone/empty-procfile",
"sharpstone/bad_ruby_version",
"sharpstone/activerecord41_scaffold"
"sharpstone/activerecord41_scaffold",
"sharpstone/libpq_connection_error"
],
"jruby": [
"sharpstone/jruby_naether"
Expand Down
2 changes: 2 additions & 0 deletions hatchet.lock
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@
- 7cae0aae424c2028b81b5d37ee24d42db8e545b9
- - "./repos/ruby/jruby-minimal"
- f79860bc2866449fe065484f1542aaadd3f7cfd2
- - "./repos/ruby/libpq_connection_error"
- c211c245f09d8335a520cd7a0b5360897d4988eb
- - "./repos/ruby/mri_187"
- 43cecfacbedda64f09310a4408ce73c5dc3a9c44
- - "./repos/ruby/mri_193_p547"
Expand Down
9 changes: 9 additions & 0 deletions lib/language_pack/metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ def touch(key)
write(key, "true")
end

def fetch(key)
return read(key) if exists?(key)

value = yield

write(key, value.to_s)
return value
end

def save
@cache ? @cache.add(FOLDER) : false
end
Expand Down
50 changes: 50 additions & 0 deletions lib/language_pack/ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def compile
setup_export
setup_profiled
allow_git do
vendor_libpq
install_bundler_in_app
build_bundler("development:test")
post_bundler
Expand All @@ -117,6 +118,55 @@ def compile
raise e
end

def vendor_libpq
# Check for existing libraries
return unless File.exist?("/usr/lib/x86_64-linux-gnu/libpq.so.5.11")
return unless ENV['STACK'] == 'heroku-18'

topic("Vendoring libpq 5.12.1")

@metadata.fetch("vendor_libpq12") do
warn(<<~EOF)
Replacing libpq with version libpq 5.12.1

This version includes a bug fix that can cause an exception
on boot for applications with incorrectly configured connection
values. For more information see:

https://devcenter.heroku.com/articles/libpq-5-12-1-breaking-connection-behavior

If your application breaks you can rollback to your last build.
You can also temporarially opt out of this behavior by setting:

```
$ heroku config:set HEROKU_SKIP_LIBPQ12=1
```

In the future libpq 5.12 will be the default on the platform and
you will not be able to opt-out of the library. For more information see:

https://devcenter.heroku.com/articles/libpq-5-12-1-breaking-connection-behavior
EOF

"true" # Set future cache value
end

Dir.chdir("vendor") do
@fetchers[:mri].fetch("libpq5_12.1-1.deb")
run!("dpkg -x libpq5_12.1-1.deb .")
run!("rm libpq5_12.1-1.deb")

load_libpq_12_unless_env_var = <<~EOF
if [ "$HEROKU_SKIP_LIBPQ12" == "" ]; then
export LD_LIBRARY_PATH="$HOME/vendor/usr/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH"
fi
EOF
add_to_export load_libpq_12_unless_env_var
add_to_profiled load_libpq_12_unless_env_var
ENV["LD_LIBRARY_PATH"] = Dir.pwd + "/usr/lib/x86_64-linux-gnu:#{ENV["LD_LIBRARY_PATH"]}"
end
end

def cleanup
end

Expand Down
18 changes: 18 additions & 0 deletions spec/hatchet/ruby_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
require_relative '../spec_helper'

describe "Ruby apps" do
describe "vendoring libpq" do
it "works on heroku-16" do
skip "Blocked on getting heroku-16 docker example to work https://github.com/schneems/libpq_heroku_16_reproduction/tree/schneems/manually-download-install"

Hatchet::Runner.new("libpq_connection_error", stack: "heroku-16").deploy do |app|
out = app.run("ruby reproduce_error.rb")
expect(out).to match(%Q{invalid integer value "15s"})
end
end

it "works on heroku-18" do
Hatchet::Runner.new("libpq_connection_error", stack: "heroku-18").deploy do |app|
out = app.run("ruby reproduce_error.rb")
expect(out).to match(%Q{invalid integer value "15s"})
end
end
end

describe "running Ruby from outside the default dir" do
it "works" do
Hatchet::Runner.new('cd_ruby', stack: DEFAULT_STACK).deploy do |app|
Expand Down