Files
ubicloud/prog/install_rhizome.rb
Daniel Farina 19b29b85b0 Core classes freezing, try three
After 4cfcceb22c, another run-time code
modification was found, yielding a revert in
d6e5d9dd69.  This time, the break was in
`InstallRhizome` and in the rubygems code that we use for tar stream
generation.

You can produce the crash like this:

    [1] clover-development(main)> require 'rubygems'; require 'refrigerator'; Refrigerator.freeze_core; Gem.source_date_epoch

    FrozenError: can't modify frozen #<Class:Gem>: Gem
    from /home/fdr/.asdf/installs/ruby/3.2.3/lib/ruby/3.2.0/rubygems.rb:1139:in `source_date_epoch_string'

With a backtrace like:

    ruby/3.2.0/rubygems.rb:1139:in `source_date_epoch_string'
    ruby/3.2.0/rubygems.rb:1157:in `source_date_epoch'
    (pry):1:in `__pry__'

In addition, unless rubygems is required before freezing, there is
another reopening of the `Gem` module, to define some OpenSSL related
constants:

    ruby/3.2.0/rubygems/openssl.rb:6:in `<module:Gem>'
    ruby/3.2.0/rubygems/openssl.rb:5:in `<top (required)>'
    ruby/3.2.0/rubygems/security.rb:10:in `require_relative'
    ruby/3.2.0/rubygems/security.rb:10:in `<top (required)>'
    ruby/3.2.0/rubygems/package.rb:9:in `require_relative'
    ruby/3.2.0/rubygems/package.rb:9:in `<top (required)>'

To fix that, I move the `require` of `rubygems` to the customary place
for `require`, at the top of the file, rather than making it so lazy
as to wait for a method call to do so.
2024-02-21 09:23:15 -08:00

45 lines
1.1 KiB
Ruby

# frozen_string_literal: true
require "rubygems/package"
require "stringio"
class Prog::InstallRhizome < Prog::Base
subject_is :sshable
label def start
tar = StringIO.new
Gem::Package::TarWriter.new(tar) do |writer|
base = Config.root + "/rhizome"
Dir.glob(["Gemfile", "Gemfile.lock", "common/**/*", "#{frame["target_folder"]}/**/*"], base: base).map do |file|
next if !frame["install_specs"] && file.end_with?("_spec.rb")
full_path = base + "/" + file
stat = File.stat(full_path)
if stat.directory?
writer.mkdir(file, stat.mode)
elsif stat.file?
writer.add_file(file, stat.mode) do |tf|
File.open(full_path, "rb") do
IO.copy_stream(_1, tf)
end
end
else
# :nocov:
fail "BUG"
# :nocov:
end
end
end
payload = tar.string.freeze
sshable.cmd("tar xf -", stdin: payload)
hop_install_gems
end
label def install_gems
sshable.cmd("bundle config set --local path vendor/bundle")
sshable.cmd("bundle install")
pop "installed rhizome"
end
end