Files
ubicloud/rhizome/common/lib/util.rb
Jeremy Evans e59d71e2f6 Restore Ruby 3.2 syntax to rhizome
Ubuntu 22.04 VmHosts use Ruby 3.0, and Ubunutu 24.04 use Ruby 3.2,
so 3.4 syntax would break either.  This was theoretically an issue
before, but I'm guessing there were no significant syntax changes
between 3.0 and 3.2 that Rubocop's rewriting would break.

This commits a rhizome/.rubocop.yml file that inherits the default
configuration, and overrides TargetRubyVersion.
2025-04-26 08:34:47 +09:00

81 lines
2.2 KiB
Ruby

# frozen_string_literal: true
require "bundler/setup"
require "open3"
require "shellwords"
require "digest"
class CommandFail < RuntimeError
attr_reader :stdout, :stderr
def initialize(message, stdout, stderr)
super(message)
@stdout = stdout
@stderr = stderr
end
def to_s
[super, "\n---STDOUT---", @stdout, "\n---STDERR---", @stderr].join("\n")
end
end
# rubocop:disable Lint/InheritException
class FsyncFail < Exception
end
# rubocop:enable Lint/InheritException
def r(commandline, stdin: "", expect: [0])
stdout, stderr, status = Open3.capture3(commandline, stdin_data: stdin)
fail CommandFail.new("command failed: " + commandline, stdout, stderr) unless expect.include?(status.exitstatus)
stdout
end
def rm_if_exists(path)
FileUtils.rm_r(path)
rescue Errno::ENOENT
# ignore if path doesn't exist, otherwise raise error
end
def fsync_or_fail(f)
# Throw a custom exception type inheriting directly from Exception,
# unlikely to be accidentally rescued as to better halt the program
# in event of fsync errors.
#
# The ultimate goal of fsync errors is to page. Halting progress is
# one roundabout but easy way of doing that.
#
# Note that IO::fsync raises an exception on error based on its source
# in the docs: https://ruby-doc.org/core-2.4.2/IO.html#method-i-fsync
f.fsync
rescue SystemCallError => e
raise FsyncFail.new(e.message)
end
def sync_parent_dir(f)
parent_dir = Pathname.new(f).parent.to_s
File.open(parent_dir) {
fsync_or_fail(_1)
}
end
def safe_write_to_file(filename, content = nil)
raise ArgumentError, "must provide either content or block" if (content.nil? && !block_given?) || (!content.nil? && block_given?)
temp_filename = filename + ".tmp"
lock_filename = "/tmp/#{Digest::SHA256.hexdigest(temp_filename)}.lock"
File.open(lock_filename, File::RDWR | File::CREAT) do |lock_file|
lock_file.flock(File::LOCK_EX)
if block_given?
File.open(temp_filename, File::RDWR | File::CREAT) do |f|
yield f
end
else
File.write(temp_filename, content)
end
File.rename(temp_filename, filename)
end
end
def curl_file(url, path)
r("bash -c 'curl -f -L3 #{url.shellescape} | tee >(openssl dgst -sha256) > #{path.shellescape}'").split(" ").last
end