hotcell-client 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/hot_cell/cell.rb +2 -14
- data/lib/hot_cell/cells.rb +0 -7
- data/lib/hot_cell/client/version.rb +1 -1
- data/lib/hot_cell/client.rb +0 -5
- data/lib/hot_cell/install/Dockerfile.tt +33 -0
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c907b155be1d28cc8ca37320ac22f71689f581390e6aa45e77a5a7e31bce04f3
|
|
4
|
+
data.tar.gz: cb676888f838068d7b6671df95fc869a9bd5736d04556e0f2b0c9a8352e7e300
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d436910383ab67af5a826efd3854441c1c90d28bd792657bd6598c27940e7fffa80b1eb50c421eaba737152b4c93a1dd2d2f29243bb9529762ba25bf699bb26b
|
|
7
|
+
data.tar.gz: e3e71a17d0f2e152fb8a504c6966a9fcb1addf63dc3e383cfa021e402d9c322221c02545bfea92fa9f467952dd492e0bc8b3bc945bc787853df38c491b2b3998
|
data/lib/hot_cell/cell.rb
CHANGED
|
@@ -66,14 +66,13 @@ module HotCell
|
|
|
66
66
|
@on_contract_skew&.call error, self
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
# Static, and called once at boot.
|
|
70
|
-
# carry the operation it wants, which is otherwise an `unsupported` on the first real request.
|
|
69
|
+
# Static, and called once at boot.
|
|
71
70
|
#
|
|
72
71
|
# Boot must not fail when a cell does not answer. A cell that is down at app boot is a degraded
|
|
73
72
|
# deployment rather than a broken one, and an application that refuses to start because its thumbnail
|
|
74
73
|
# cell is restarting is worse than one that serves placeholders. So this warns and carries on.
|
|
75
74
|
#
|
|
76
|
-
# Nor when a cell answers something this client cannot read. The
|
|
75
|
+
# Nor when a cell answers something this client cannot read. The two warnings below reach into the
|
|
77
76
|
# description without checking types, so a cell that sends the wrong ones raises here — and the README
|
|
78
77
|
# calls `describe_cells` from `after_initialize`, where that is not a failed check but an application
|
|
79
78
|
# that does not boot. The process that wrote the description is the one that runs untrusted content.
|
|
@@ -86,7 +85,6 @@ module HotCell
|
|
|
86
85
|
|
|
87
86
|
response.result.tap do |described|
|
|
88
87
|
warn_about_timeout described
|
|
89
|
-
warn_about_missing_operations described
|
|
90
88
|
warn_about_group_skew described
|
|
91
89
|
end
|
|
92
90
|
rescue StandardError => error
|
|
@@ -164,16 +162,6 @@ module HotCell
|
|
|
164
162
|
"every operation that gives a tool a filename will fail with EACCES."
|
|
165
163
|
end
|
|
166
164
|
|
|
167
|
-
def warn_about_missing_operations(described)
|
|
168
|
-
carried = Array(described[:operations])
|
|
169
|
-
wanted = HotCell.clients.select { |client| client.hotcell == name }
|
|
170
|
-
|
|
171
|
-
wanted.reject { |client| carried.include?(client.operation) }.each do |client|
|
|
172
|
-
HotCell.logger.warn "hotcell #{name}: #{client} wants #{client.operation.inspect} and this cell " \
|
|
173
|
-
"carries #{carried.inspect}"
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
165
|
# A `nil` timeout reaches `Transport::Socket#receive` as `deadline: nil`, and reading with no deadline
|
|
178
166
|
# blocks: a cell that accepts the connection and then never answers holds this caller for good. At
|
|
179
167
|
# boot that is an application that never finishes starting, with no exception and nothing to rescue.
|
data/lib/hot_cell/cells.rb
CHANGED
|
@@ -60,13 +60,6 @@ module HotCell
|
|
|
60
60
|
cells.key?(name.to_s)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
# Every HotCell::Client subclass, so a boot check can tell which cell is expected to carry what. This
|
|
64
|
-
# records what the process has loaded rather than what it has configured, so resetting registrations
|
|
65
|
-
# leaves it alone: the classes are still defined either way.
|
|
66
|
-
def clients
|
|
67
|
-
@clients ||= []
|
|
68
|
-
end
|
|
69
|
-
|
|
70
63
|
# Call once at boot, after registering. Warns and carries on; see Cell#describe.
|
|
71
64
|
def describe_cells
|
|
72
65
|
warn_about_group
|
data/lib/hot_cell/client.rb
CHANGED
|
@@ -4,9 +4,21 @@
|
|
|
4
4
|
# A cell carries a Ruby runtime and every gem in its loaded graph, all inside the blast radius, so treat
|
|
5
5
|
# this file as a budget rather than an inventory. Which tools it holds is what decides its blast radius.
|
|
6
6
|
|
|
7
|
+
# The base image. This tag is mutable: `ruby:3.4-slim` moves as Debian and Ruby publish patches, so a
|
|
8
|
+
# clean build is only as reproducible and as patched as the tag on the day it runs. Build with
|
|
9
|
+
# `docker build --pull` to always take the newest patched base. If you also need to name the exact image
|
|
10
|
+
# you shipped, pin a digest (`FROM ruby:${RUBY_VERSION}-slim@sha256:…`) and refresh it on a schedule; the
|
|
11
|
+
# image scan in CI is what catches a base that has drifted into known-vulnerable either way.
|
|
7
12
|
ARG RUBY_VERSION=3.4
|
|
8
13
|
FROM ruby:${RUBY_VERSION}-slim
|
|
9
14
|
|
|
15
|
+
# Apply Debian's pending security patches. `--pull` takes the newest base tag, and the tag can still be
|
|
16
|
+
# behind an advisory that is already in `trixie-security`, because only a rebuild by docker-library/ruby
|
|
17
|
+
# moves it. Upgrading here makes the image's patch level its own rather than upstream's release cadence,
|
|
18
|
+
# and it is what keeps the image scan in CI passing on a fixable vulnerability the base has not picked up
|
|
19
|
+
# yet. It costs a layer and a little build time on every build.
|
|
20
|
+
RUN apt-get update && apt-get upgrade -y --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
|
21
|
+
|
|
10
22
|
# Install the tools and libraries your operations run — and nothing else. For example:
|
|
11
23
|
#
|
|
12
24
|
# RUN apt-get update && \
|
|
@@ -25,14 +37,28 @@ RUN mkdir -p /run/hotcell/cell /hotcell/operations && chown -R hotcell:hotcell /
|
|
|
25
37
|
|
|
26
38
|
# HOME is /tmp because the cell's user has no home directory, and bundler wants one. A worker replaces
|
|
27
39
|
# it with its slot's home before it serves anything.
|
|
40
|
+
#
|
|
41
|
+
# OpenMP sizes its thread pool from the host's core count, and a `cpus:` quota does not lower it, so an
|
|
42
|
+
# unbounded libvips or ImageMagick asks a 98-core host for 98 threads, each with an 8MB stack.
|
|
43
|
+
# `RLIMIT_DATA` charges those stacks, and libgomp calls `exit(1)` on the first `pthread_create` it cannot satisfy. Match
|
|
44
|
+
# OMP_NUM_THREADS to the container's `cpus:`: the number follows the allocation rather than being 2.
|
|
45
|
+
# OMP_THREAD_LIMIT bounds a library that raises the count itself, which is what ImageMagick does.
|
|
28
46
|
ENV HOME=/tmp \
|
|
29
47
|
BUNDLE_PATH=/hotcell/bundle \
|
|
30
48
|
BUNDLE_WITHOUT=development \
|
|
49
|
+
OMP_NUM_THREADS=2 \
|
|
50
|
+
OMP_THREAD_LIMIT=8 \
|
|
31
51
|
HOTCELL_OPERATIONS=/hotcell/operations \
|
|
32
52
|
HOTCELL_DIR=/run/hotcell/cell
|
|
33
53
|
|
|
34
54
|
WORKDIR /hotcell
|
|
35
55
|
|
|
56
|
+
# For a reproducible dependency graph, commit a Gemfile.lock next to the Gemfile so a clean build resolves
|
|
57
|
+
# the exact gems the lockfile names rather than whatever the sources offer that day. Generate it for the
|
|
58
|
+
# platform you deploy on — e.g. from a macOS checkout, `bundle lock --add-platform x86_64-linux` so the
|
|
59
|
+
# Linux image accepts it — and build frozen (`bundle install --frozen`, or set `BUNDLE_FROZEN=true`) to
|
|
60
|
+
# refuse a Gemfile that has drifted from the lockfile. Left off by default so a freshly installed scaffold
|
|
61
|
+
# builds before you have generated a lockfile.
|
|
36
62
|
COPY --chown=hotcell:hotcell Gemfile* ./
|
|
37
63
|
USER hotcell
|
|
38
64
|
RUN bundle install
|
|
@@ -46,6 +72,13 @@ COPY operations/ /hotcell/operations/
|
|
|
46
72
|
# root once the build is done. `read-only: true` covers this as well, and this holds without it.
|
|
47
73
|
USER root
|
|
48
74
|
RUN chown -R root:root /hotcell && chmod -R go-w /hotcell
|
|
75
|
+
|
|
76
|
+
# Strip the setuid and setgid bits off every binary the image carries (mount, umount, su, … from the base,
|
|
77
|
+
# plus anything a RUN above installed). The cell runs as an unprivileged user under `--cap-drop ALL` and
|
|
78
|
+
# `--security-opt no-new-privileges`, which already make these gadgets inert; removing the bits keeps a
|
|
79
|
+
# security image from shipping escalation tools it never uses. As the last root step it covers everything
|
|
80
|
+
# built above it. `-xdev` stays on the image's own filesystem; `chmod a-s` clears both bits.
|
|
81
|
+
RUN find / -xdev -type f -perm /06000 -exec chmod a-s {} +
|
|
49
82
|
USER hotcell
|
|
50
83
|
|
|
51
84
|
# Probes the supervisor's control socket from inside the container, where network: none does not apply.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hotcell-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Dalessio
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.3.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.
|
|
25
|
+
version: 0.3.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: activesupport
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -67,8 +67,8 @@ licenses:
|
|
|
67
67
|
- MIT
|
|
68
68
|
metadata:
|
|
69
69
|
homepage_uri: https://github.com/basecamp/hotcell
|
|
70
|
-
source_code_uri: https://github.com/basecamp/hotcell/tree/v0.
|
|
71
|
-
changelog_uri: https://github.com/basecamp/hotcell/blob/v0.
|
|
70
|
+
source_code_uri: https://github.com/basecamp/hotcell/tree/v0.3.0/hotcell-client
|
|
71
|
+
changelog_uri: https://github.com/basecamp/hotcell/blob/v0.3.0/CHANGELOG.md
|
|
72
72
|
bug_tracker_uri: https://github.com/basecamp/hotcell/issues
|
|
73
73
|
rubygems_mfa_required: 'true'
|
|
74
74
|
rdoc_options: []
|