-
Notifications
You must be signed in to change notification settings - Fork 780
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
Install openssl whenever the system openssl version is not supported by a Ruby #1974
Conversation
Thank you for the PR, I agree this is useful and needed, given ruby-core seems unwilling to add openssl 3 support to Ruby 3.0 and 2.7: https://bugs.ruby-lang.org/issues/18658#note-8 |
@znz I appreciate the effort that went into this, and I do agree that the current situation on Ubuntu is unfriendly for our users. However, I'd be hard to convince that this is the way to go. Our current
Basically, all of this would also happens on other platforms too if we started to extend this approach outside of just macOS. However, what I would ideally like to see is that ruby-build stops building or maintaining its own openssl versions. Instead, a ruby-build process should ideally just quickly error out if a compatible openssl version wasn't found on the system, with instructions on how the user should take initiative to fix it. For example, macOS users should ideally just install
We could optionally start to print these instructions, or equivalent instructions on other systems, with the idea being that the user should be responsible for this. Sure, that would result in users having more to do themselves, but I think it would be in their interest that they are in control. |
Certainly better than failing. Maybe we could install openssl in a well-known place which could be reused if the same openssl version is used by multiple Ruby versions.
This definitely sucks, but I think we'd get almost as much reports even without that. Failing to compile ruby feeks like 90% from openssl issues, and telling people to install manually wouldn't improve that, I don't see it likely people would report to upstream openssl, and they likely wouldn't be able to help with e.g. how ruby & ruby-build use that openssl.
That's a non-issue with this PR, because it symlinks the system certificates.
The problem is this is very annoying to do on Ubuntu 22.04 and other recent distros which default to openssl 3. The situation is already a pain and already existed for Ruby <= 2.3 (which doesn't compile with openssl 1.1 and needs 1.0), but those are old so it not so commonly a problem. But here it's simply not possible to build Ruby 3.0 on Ubuntu 22.04 with ruby-build, unless you manually download & compile openssl and link the certificates. There is another issue to not use the system openssl not mentioned above:
That reason is IMHO why Ruby 3.0 should support openssl 3, otherwise it's not possible/very difficult to use Ruby 3.0 with database drivers on Ubuntu 22.04. BTW on macOS I think ruby-build should use Homebrew's openssl by default to avoid this issue, because that's the "system libssl" of macOS for most users (i.e., they'd install mysql/postgres via brew and I think those link against the Homebrew openssl). But I don't know the details of openssl on macOS anymore, it seems it ships with LibreSSL nowadays? |
Related discussion: #1940 |
That would be great! If ruby-build is invoked in the context of rbenv, maybe we could have a shared openssl installation under
Ah, true; thanks for pointing that out. I guess this wasn't possible on macOS because there were no physical files to link to.
Agreed—in the ideal world. I don't have the expertise to know what would actually be involved with that. @eregon In the interest on making this changeset minimal, how would you feel about building this cross-platform openssl functionality into the old functions |
I guess you meant to ping @znz.
This then gives us all the flexibility in the check, and we will (most likely) never need to rename that again. |
Maybe simply |
No, I meant to ping you as a maintainer.
Sure, that's descriptive, but I find it verbose and scary-looking. How about something generic and simpler, since this is going to be repeated across hundreds of build definitions:
|
I'd be open to that, but it would break the unspoken contract of rbenv never writing to locations outside of
Like most features of ruby-build, I definitely agree it should be configurable via an environment variable. |
Right, but that is unavoidable if we want to share the openssl installation between different Ruby versions. For rbenv we could just have rbenv pass the path for where to put openssl ( BTW, I was thinking we'd install openssl e.g. in |
Non-rbenv users could set something like RUBY_BUILD_OPENSSL_DIR to keep openssl in a shared location. We do the same with speeding up downloads: rbenv users have ruby-build caching downloads to |
4a2f2b6
to
42ffd70
Compare
I like that I used to use |
That used to happen to me as well. I think this was because Homebrew by default does aggressive pruning of older versions of software whenever it installs a newer version. Once I've configured |
share/ruby-build/3.1.0
Outdated
@@ -1,2 +1,2 @@ | |||
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl | |||
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" openssl --if needs_openssl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For CRuby 3.1+, OpenSSL 3 is supported, so there we should not install a custom openssl but use the system openssl.
So this could remain --if has_broken_mac_openssl
.
I'm thinking we should have needs_openssl3
(3.0 or older, so not 4+), needs_openssl11
(1.1 or older, so not 3+), needs_openssl10
(1.0 or older, so not 1.1+).
For CRuby 3.1+ we'd use needs_openssl3
, for other CRuby versions which install_package "openssl-1.1
it'd be needs_openssl11
and for install_package "openssl-1.0
it'd be needs_openssl10
.
That could be done in this PR or later, but we should not install openssl for CRuby 3.1+ on non-macOS.
@mislav Could you do another review? I think we also need to choose, either:
|
@mislav Any thought on the above? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay! This is looking good. Some style suggestions and clarifying questions about Ruby 3.2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great; thank you for your work and patience!
As far as I'm concerned, this can ship. One final thought I have about all this is forwards compatibility: it seems that with this change, we've kicked the can down the street (by redefining the semantics that were previously only around OpenSSL v1 to be OpenSSL v3-aware), but if anything significantly changes with how OSs package OpenSSL in the future (e.g. they start shipping OpenSSL v4), we'll have a set of problems again because we've hardcoded that needs_openssl
in ruby-build means that it specifically needs OpenSSL v1 (and that it can't be Apple-patched OpenSSL/LibreSSL).
Ideally, in the future, needs_openssl
would understand the precise version that a Ruby version needs. To a human, that version requirement can be inferred from the formula itself:
install_package "openssl-<ver>" "https://www.openssl.org/source/openssl-<ver>.tar.gz#<sha>" openssl --if <condition>
except that when the condition is evaluated, it doesn't have access to the openssl-<ver>
bit. We could figure this out in subsequent changes.
For future travelers that find this and need to get ruby 3.0 installed on a system with openssl 3.0, here's one possible workaround: https://gist.github.com/yob/08d53a003181aa0fcce9812b1b533870 tl;dr trick ruby-build into install ruby without openssl, manually download the openssl 3.0 gem using wget and install it. Rather than install openssl 1.1 to compile ruby, is it possible to teach ruby-build an opt-in version of the above? |
Discussed in #1974 (comment) and https://bugs.ruby-lang.org/issues/18658#note-11. |
I will try to rebase this and finish reviewing this PR. I'll squash all commits because otherwise it seems impossible to rebase with the recent openssl update. Original commits at master...eregon:ruby-build:install-openssl_1-when-openssl_is_3-bak |
0b3d714
to
3131edc
Compare
3131edc
to
d7af98e
Compare
I've pushed a commit so the logic is intuitive and general:
And for that I also made all supported versions explicit with @mislav Could you review my Bash code added in ruby-build? |
* Make supported openssl versions explicit per definition.
70a388a
to
bd1c677
Compare
Actually, let me merge this and release it now, to make sure we don't get conflicts again. |
Details: * ruby/setup-ruby#333 (comment) * rbenv/ruby-build#1974 - we don't use rbenv, but I found this thread useful for describing the problem.
Ubuntu 22.04 includes openssl 3.0.2, and libssl-dev is also 3.0.2 only.
But Ruby < 3.1 does not support openssl 3.
So I want to install openssl 1 automatically.
I just tested
rbenv install 3.0.4
andrbenv install 2.7.6
with this on Ubuntu 22.04.Sorry if this makes trouble on other platforms.