A while ago I did a little write-up on building a nice, dependency free, modern Ruby on SmartOS. I even ended up writing a script to do it automatically.
I use Puppet to manage my Solaris zones, and I thought it was high time to get upgraded to Ruby 2.x and Puppet 4, which is what I use on SmartOS. So, I tried to build Ruby 2.2.3 in exactly the same was as I build it on SmartOS. Well, almost the same way. I am so old fashioned that I still try to build stuff with Sun CC. I’ve lost some of the appetite to fight things, but old habits die hard.
$ CC=cc CFLAGS=-fast ./configure --prefix=/opt/ruby --disable-install-doc --enable-dtrace
...
$ gmake -j4
...
gmake[2]: Entering directory `/tmp/ruby-2.3.0/ext/openssl'
compiling ossl_ssl.c
ossl_ssl.c:107:27: error: 'SSLv2_method' undeclared here (not in a function)
OSSL_SSL_METHOD_ENTRY(SSLv2),
^
ossl_ssl.c:89:69: note: in definition of macro 'OSSL_SSL_METHOD_ENTRY'
#define OSSL_SSL_METHOD_ENTRY(name) { #name, (SSL_METHOD *(*)(void))name##_method }
^
ossl_ssl.c:108:27: error: 'SSLv2_server_method' undeclared here (not in a function)
OSSL_SSL_METHOD_ENTRY(SSLv2_server),
^
ossl_ssl.c:89:69: note: in definition of macro 'OSSL_SSL_METHOD_ENTRY'
#define OSSL_SSL_METHOD_ENTRY(name) { #name, (SSL_METHOD *(*)(void))name##_method }
^
ossl_ssl.c:109:27: error: 'SSLv2_client_method' undeclared here (not in a function)
OSSL_SSL_METHOD_ENTRY(SSLv2_client),
^
ossl_ssl.c:89:69: note: in definition of macro 'OSSL_SSL_METHOD_ENTRY'
#define OSSL_SSL_METHOD_ENTRY(name) { #name, (SSL_METHOD *(*)(void))name##_method }
Well. That kinda sucks. SSLv2? That’s gone the way of Solaris^W
the dinosaurs hasn’t it?
$ ggrep -r SSLv2_method /usr/include
/usr/include/openssl/ssl.h:DEPRECATED const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
interesting. Let’s see what SmartOS thinks:
$ ggrep -r SSLv2_method /opt/local/include
/opt/local/include/openssl/ssl.h:const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
So, it looks like SmartOS is happy to give me crappy SSLv2 functionality that I shouldn’t be trusted with, but Solaris 11.3 is not. Wow. Mark one up for Oracle.
But, I’m still in a fix. I can’t build Ruby, even with potentially
iffy SSL support. Looking at the code, the #ifdef
wrapping the
offending line suggests an easy, legitimate, fix.
#if defined(HAVE_SSLV2_METHOD) && defined(HAVE_SSLV2_SERVER_METHOD) && \
defined(HAVE_SSLV2_CLIENT_METHOD)
OSSL_SSL_METHOD_ENTRY(SSLv2),
OSSL_SSL_METHOD_ENTRY(SSLv2_server),
OSSL_SSL_METHOD_ENTRY(SSLv2_client),
#endif
It looks to me as if, rather than simply DEPRECATE
-ing the SSLv2
methods, we should pretend we don’t have them at all. There’s stuff
further down for SSLv3
, which we do have. So, let’s drop
#undef HAVE_SSLV2_METHOD
in at the top of the file and give it another go.
$ gsed -i '13i#undef HAVE_SSLV2_METHOD' ext/openssl/ossl_ssl.c
$ gmake -j4
...
linking ruby
gmake[2]: Leaving directory `/tmp/ruby-2.3.0'
gmake[1]: Leaving directory `/tmp/ruby-2.3.0'
$ gmake test
...
PASS all 1010 tests
...
All looks good. Let’s try it out.
# gmake install
$ /opt/ruby/bin/irb
irb(main):001:0> require 'openssl'
=> true
Looks good so far. I know gem
uses SSL stuff. So:
# /opt/ruby/bin/gem install puppet ruby-shadow
Note that I didn’t bother with --no-rdoc
etc. (And I don’t want
any docs: this is purely for an Omnibus style Puppet package.)
because:
$ cat ~/.gemrc
install: --no-rdoc --no-ri
update: --no-rdoc --no-ri
I distribute this to all my zones by lofs
mounting /opt/ruby
read-only everywhere. Then, when I want to push a new version, I can
do it from the global in one shot.