diff --git a/Gemfile.saas b/Gemfile.saas index 7cf23b264c..52251a26d5 100644 --- a/Gemfile.saas +++ b/Gemfile.saas @@ -11,9 +11,9 @@ gem "console1984", bc: "console1984" gem "audits1984", bc: "audits1984" # Attachment processing in an unprivileged sibling container -gem "hotcell-client", "~> 0.3.1" -gem "activestorage-hotcell-client", "~> 0.3.1" -gem "mini_magick", require: false # activestorage-hotcell-client 0.3.1 loads the ImageMagick transformer even when unused +gem "hotcell-client", "0.4.1" +gem "activestorage-hotcell-client", "0.4.1" +gem "mini_magick", require: false # activestorage-hotcell-client loads the ImageMagick transformer even when unused # Native push notifications (iOS/Android) gem "action_push_native" diff --git a/Gemfile.saas.lock b/Gemfile.saas.lock index 900a3d950e..ce65d27857 100644 --- a/Gemfile.saas.lock +++ b/Gemfile.saas.lock @@ -224,9 +224,9 @@ GEM activemodel (>= 7.0) activemodel-serializers-xml (~> 1.0) activesupport (>= 7.0) - activestorage-hotcell-client (0.3.1) + activestorage-hotcell-client (0.4.1) activestorage (>= 8.2.0.alpha) - hotcell-client (= 0.3.1) + hotcell-client (= 0.4.1) addressable (2.9.0) public_suffix (>= 2.0.2, < 8.0) ansi (1.6.0) @@ -343,10 +343,10 @@ GEM herb (0.10.3-x86_64-darwin) herb (0.10.3-x86_64-linux-gnu) herb (0.10.3-x86_64-linux-musl) - hotcell-client (0.3.1) + hotcell-client (0.4.1) activesupport (>= 7.1) - hotcell-core (= 0.3.1) - hotcell-core (0.3.1) + hotcell-core (= 0.4.1) + hotcell-core (0.4.1) http-2 (1.1.1) httpx (1.7.1) http-2 (>= 1.0.0) @@ -739,7 +739,7 @@ DEPENDENCIES action_push_native actionpack-xml_parser activeresource - activestorage-hotcell-client (~> 0.3.1) + activestorage-hotcell-client (= 0.4.1) audits1984! autotuner aws-sdk-s3 @@ -755,7 +755,7 @@ DEPENDENCIES fizzy-saas! geared_pagination (~> 1.2) gvltools - hotcell-client (~> 0.3.1) + hotcell-client (= 0.4.1) image_processing (~> 2.0) importmap-rails jbuilder @@ -825,7 +825,7 @@ CHECKSUMS activerecord (8.2.0.alpha) activeresource (6.2.0) sha256=818ca60d3cd1ff7bbb7277f41250ad4d61a7cdbe30fbf52b2145e1b66ed13900 activestorage (8.2.0.alpha) - activestorage-hotcell-client (0.3.1) sha256=57c62cf0825eddcb47970ffce4bae4d05ca1b63740a21b67f676313cc66a4cd7 + activestorage-hotcell-client (0.4.1) sha256=46e09962ea839044241b026153c2c27b2f786ad929d4f8e493bcde1965244e1c activesupport (8.2.0.alpha) addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 @@ -895,8 +895,8 @@ CHECKSUMS herb (0.10.3-x86_64-darwin) sha256=e02e43b3bb1977f4fd08f3330b5f2aa3292ca2d572a8bd59688eca8b79725f46 herb (0.10.3-x86_64-linux-gnu) sha256=cbb49b66f2bdc92d17109d1ea9452e88ba6a8ae52e9ddd5279deff83dcc4c66d herb (0.10.3-x86_64-linux-musl) sha256=c84482d6b57f13c2e1a0fa029649efb0e5fdc876a3fd564bae09cf42bd4d5ae1 - hotcell-client (0.3.1) sha256=bd1760634b532c660f1c37051eda20da2e0a4b0f8bfca239e04f5df1b4a32aff - hotcell-core (0.3.1) sha256=c72bc2b6d151a8bf22600eb2ad202b72baf6c5c454077684d63547db176c77ed + hotcell-client (0.4.1) sha256=45ad9c7e083a01df861d9906aa758efbd5dc1e2cf3fb6ba887b92bf57c14a019 + hotcell-core (0.4.1) sha256=5a5fff74264074122113a65080d09fe35d73bee6bed5c11e26562d050616eab6 http-2 (1.1.1) sha256=1141a5a03c2f4e6b8d2fa62394de581e1ff6387711cd7ed577212e9d95562bba httpx (1.7.1) sha256=ae380461539203c92f3ee65c13b22dfccb0d975156426869f57820505cacdf56 i18n (1.15.2) sha256=00f9eb62412fe593b2a65a97daa75300d37abb8f7202ec748e94b6d46a9dd1b5 diff --git a/saas/Procfile.dev b/saas/Procfile.dev index 2d7e7266a6..bec20c87ae 100644 --- a/saas/Procfile.dev +++ b/saas/Procfile.dev @@ -1,4 +1,4 @@ # SaaS development: the app plus a hotcell cell beside it. This file lives here rather than in the root # Procfile.dev because the cell is SaaS-only and the open-source checkout must never boot one. web: bin/rails server -b 0.0.0.0 -p ${PORT:-3006} -cell: env -u RUBYOPT -u RUBYLIB -u BUNDLER_SETUP -u BUNDLER_VERSION -u BUNDLE_BIN_PATH -u BUNDLE_LOCKFILE BUNDLE_GEMFILE=$PWD/saas/hotcell/Gemfile HOTCELL_DIR=$PWD/tmp/hotcell/active_storage HOTCELL_CONFIG=$PWD/saas/hotcell/config.rb HOTCELL_OPERATIONS=$PWD/saas/hotcell/operations bundle exec hotcell +cell: env -u RUBYOPT -u RUBYLIB -u BUNDLER_SETUP -u BUNDLER_VERSION -u BUNDLE_BIN_PATH -u BUNDLE_LOCKFILE BUNDLE_GEMFILE=$PWD/saas/hotcell/Gemfile HOTCELL_DIR=$PWD/tmp/hotcell/active_storage HOTCELL_CONFIG=$PWD/saas/hotcell/config.rb HOTCELL_OPERATIONS=$PWD/saas/hotcell/operations bundle exec hotcell --development diff --git a/saas/config/deploy.yml b/saas/config/deploy.yml index c94da0ffdb..cb2c7b074e 100644 --- a/saas/config/deploy.yml +++ b/saas/config/deploy.yml @@ -74,7 +74,7 @@ accessories: # would make what a host runs depend on when it last rebooted. saas/hotcell/bin/build writes this line; # saas/hotcell/bin/push publishes the tag. Until push has run the pull fails loudly, which is the right # way for an unbuilt image to fail. - image: registry.37signals.com/basecamp/fizzy-hotcell:d5cf91821660 + image: registry.37signals.com/basecamp/fizzy-hotcell:2f4ddc90eae3 roles: [ web, jobs ] # a descriptor cannot cross machines, so a cell lives on its caller's host # An accessory's own key, not one of the options below. Kamal always emits a --network of its own, # defaulting to `kamal`, so the same setting under `options:` is a second --network flag and Docker diff --git a/saas/hotcell/Gemfile b/saas/hotcell/Gemfile index 7cdc4e5c00..857127ba4c 100644 --- a/saas/hotcell/Gemfile +++ b/saas/hotcell/Gemfile @@ -9,5 +9,5 @@ source "https://rubygems.org" -gem "hotcell-server", "~> 0.3.1" -gem "activestorage-hotcell-server", "~> 0.3.1" +gem "hotcell-server", "0.4.1" +gem "activestorage-hotcell-server", "0.4.1" diff --git a/saas/hotcell/Gemfile.lock b/saas/hotcell/Gemfile.lock index 8b8c84d03d..eca02cd98c 100644 --- a/saas/hotcell/Gemfile.lock +++ b/saas/hotcell/Gemfile.lock @@ -1,10 +1,10 @@ GEM remote: https://rubygems.org/ specs: - activestorage-hotcell-server (0.3.1) - hotcell-server (= 0.3.1) - image_processing (>= 2.0) - mini_magick (>= 5.2.0) + activestorage-hotcell-server (0.4.1) + hotcell-server (= 0.4.1) + image_processing (>= 2.1.0) + mini_magick (>= 5.4.0) ruby-vips (>= 2.2.1) ffi (1.17.4) ffi (1.17.4-aarch64-linux-gnu) @@ -17,12 +17,12 @@ GEM ffi (1.17.4-x86_64-darwin) ffi (1.17.4-x86_64-linux-gnu) ffi (1.17.4-x86_64-linux-musl) - hotcell-core (0.3.1) - hotcell-server (0.3.1) - hotcell-core (= 0.3.1) - image_processing (2.0.3) + hotcell-core (0.4.1) + hotcell-server (0.4.1) + hotcell-core (= 0.4.1) + image_processing (2.1.0) logger (1.7.0) - mini_magick (5.3.3) + mini_magick (5.4.0) logger ruby-vips (2.3.0) ffi (~> 1.12) @@ -42,11 +42,11 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES - activestorage-hotcell-server (~> 0.3.1) - hotcell-server (~> 0.3.1) + activestorage-hotcell-server (= 0.4.1) + hotcell-server (= 0.4.1) CHECKSUMS - activestorage-hotcell-server (0.3.1) sha256=660839dc4ef34b7b5cc0b4b8733bc5b90b6667a469eee72ff2c07a41c7703935 + activestorage-hotcell-server (0.4.1) sha256=00a7d7691d2f03ca3dd4ad455fc1cf79b61cb7d37974f737e6e08e8ee8660f77 bundler (4.0.18) sha256=02d9a17429de1847b4e0c9f27a9ee4b20c0a74c0a641b4e77195d6019e3618ac ffi (1.17.4) sha256=bcd1642e06f0d16fc9e09ac6d49c3a7298b9789bcb58127302f934e437d60acf ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df @@ -59,11 +59,11 @@ CHECKSUMS ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496 ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e - hotcell-core (0.3.1) sha256=c72bc2b6d151a8bf22600eb2ad202b72baf6c5c454077684d63547db176c77ed - hotcell-server (0.3.1) sha256=170b68343d30c325392d86b24263507a69b2790e8e0a31a1e7063a2e0da89614 - image_processing (2.0.3) sha256=793e33f38470edd0a2d6bfd00acf8cb239c76284ba2e3dfb76633ac2b457f23a + hotcell-core (0.4.1) sha256=5a5fff74264074122113a65080d09fe35d73bee6bed5c11e26562d050616eab6 + hotcell-server (0.4.1) sha256=9badf6200106b878c2280ebd0ec4d655f977f3a4e24684466a6c8054e05a3e20 + image_processing (2.1.0) sha256=ca3814b1b909fc5fab68b261c50eaffef11e29a6907143e9cf1efc14b6dc6f47 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 - mini_magick (5.3.3) sha256=b3beed8a8cef36bd03666365f14b89cd344da0ecd373af53e617c71bfd426aab + mini_magick (5.4.0) sha256=f120af581d9ed4ec52c57f35a67a605d112bb1d8f582d1415b147fda42d11d78 ruby-vips (2.3.0) sha256=e685ec02c13969912debbd98019e50492e12989282da5f37d05f5471442f5374 BUNDLED WITH diff --git a/saas/lib/yabeda/hot_cell.rb b/saas/lib/yabeda/hot_cell.rb index 2934f44578..8bc5e9162d 100644 --- a/saas/lib/yabeda/hot_cell.rb +++ b/saas/lib/yabeda/hot_cell.rb @@ -78,6 +78,7 @@ def self.record_perform(event) ::Rails.logger.info " HotCell (#{duration_ms}ms) " + labels.merge( code: code || "ok", cause: event.payload[:cause], + stderr: event.payload[:stderr], perform_ms: event.payload[:perform_ms], duration_ms: duration_ms, bytes_in: event.payload[:bytes_in], diff --git a/saas/test/lib/yabeda/hot_cell_test.rb b/saas/test/lib/yabeda/hot_cell_test.rb index b3412d9600..7cfdf6c61b 100644 --- a/saas/test/lib/yabeda/hot_cell_test.rb +++ b/saas/test/lib/yabeda/hot_cell_test.rb @@ -107,6 +107,12 @@ class Yabeda::HotCellTest < ActiveSupport::TestCase assert_equal "fsize", logged["cause"] end + test "logs what a failed tool wrote to stderr" do + Yabeda::HotCell.record_perform perform_event(code: "killed", cause: "signal", stderr: "libgomp: Thread creation failed") + + assert_equal "libgomp: Thread creation failed", logged["stderr"] + end + test "does not report a failure to Sentry, because the raise already does" do Rails.error.expects(:report).never @@ -136,11 +142,11 @@ def stub_cell_metrics(counters) # duration_ms is measured by the event itself, not carried in the payload, so faking it takes the # same start/finish the real event has. - def perform_event(code: nil, perform_ms: 0, cause: nil, duration_ms: 0, bytes_in: nil, bytes_out: nil) + def perform_event(code: nil, perform_ms: 0, cause: nil, stderr: nil, duration_ms: 0, bytes_in: nil, bytes_out: nil) start = Time.now ActiveSupport::Notifications::Event.new("perform.hot_cell", start, start + duration_ms / 1000.0, nil, { cell: Fizzy::Saas::Cell::NAME, operation: "active_storage.transformers.image.vips", - code: code, cause: cause, perform_ms: perform_ms, bytes_in: bytes_in, bytes_out: bytes_out }) + code: code, cause: cause, stderr: stderr, perform_ms: perform_ms, bytes_in: bytes_in, bytes_out: bytes_out }) end def logged