Module: HotCell
- Defined in:
- lib/hot_cell/cell.rb,
lib/hot_cell/cells.rb,
lib/hot_cell/client.rb,
lib/hot_cell/install.rb,
lib/hot_cell/railtie.rb,
lib/hot_cell/failures.rb,
lib/hot_cell/transport.rb,
lib/hot_cell/client/version.rb
Defined Under Namespace
Modules: Install, Transport Classes: Cell, Client, PermanentFailure, Railtie, TransientFailure
Class Attribute Summary collapse
-
.group ⇒ Object
The group both sides hold, so a cell can open a caller's file by name.
- .logger ⇒ Object
-
.root ⇒ Object
The directory a cell's name resolves under, holding one subdirectory per cell.
Class Method Summary collapse
- .cell(name) ⇒ Object
-
.cell?(name) ⇒ Boolean
Whether a name is registered, for a caller with a fallback rather than a requirement.
- .cells ⇒ Object
-
.clients ⇒ Object
Every HotCell::Client subclass, so a boot check can tell which cell is expected to carry what.
-
.describe_cells ⇒ Object
Call once at boot, after registering.
-
.register(name, **options) ⇒ Object
Cells are registered once.
-
.reset_registrations! ⇒ Object
Test support.
-
.warn_about_group ⇒ Object
A group this process does not hold cannot be given to a file, so without this the first conversion fails as EPERM from the client's own chown — after the deployment is live and carrying traffic.
Class Attribute Details
.group ⇒ Object
The group both sides hold, so a cell can open a caller's file by name. An operation that hands a tool
a filename re-opens the descriptor as /dev/fd/N, and the kernel rechecks that open against the
cell's own credentials rather than the caller's — so a file only this application can read fails with
EACCES however the descriptor was passed. Set this to the cell's gid and put the application in that
group; the client then narrows each descriptor's mode on the way out. See Client#wrap.
Leave it unset where both sides already run as one user, which is how development runs.
18 19 20 |
# File 'lib/hot_cell/cells.rb', line 18 def group @group end |
.logger ⇒ Object
31 32 33 |
# File 'lib/hot_cell/cells.rb', line 31 def logger @logger ||= Logger.new($stderr) end |
.root ⇒ Object
The directory a cell's name resolves under, holding one subdirectory per cell. Unset means no cell is reachable at all, which is the off position of the whole rollout.
9 10 11 |
# File 'lib/hot_cell/cells.rb', line 9 def root @root end |
Class Method Details
.cell(name) ⇒ Object
52 53 54 55 56 |
# File 'lib/hot_cell/cells.rb', line 52 def cell(name) cells.fetch(name.to_s) do raise UnregisteredCell, "no cell named #{name.to_s.inspect} is registered (#{cells.keys.inspect})" end end |
.cell?(name) ⇒ Boolean
Whether a name is registered, for a caller with a fallback rather than a requirement.
59 60 61 |
# File 'lib/hot_cell/cells.rb', line 59 def cell?(name) cells.key?(name.to_s) end |
.cells ⇒ Object
48 49 50 |
# File 'lib/hot_cell/cells.rb', line 48 def cells @cells ||= {} end |
.clients ⇒ Object
Every HotCell::Client subclass, so a boot check can tell which cell is expected to carry what. This records what the process has loaded rather than what it has configured, so resetting registrations leaves it alone: the classes are still defined either way.
66 67 68 |
# File 'lib/hot_cell/cells.rb', line 66 def clients @clients ||= [] end |
.describe_cells ⇒ Object
Call once at boot, after registering. Warns and carries on; see Cell#describe.
71 72 73 74 |
# File 'lib/hot_cell/cells.rb', line 71 def describe_cells warn_about_group cells.each_value.to_h { |cell| [ cell.name, cell.describe ] } end |
.register(name, **options) ⇒ Object
44 45 46 |
# File 'lib/hot_cell/cells.rb', line 44 def register(name, **) Cell.new(name, **).tap { |cell| cells[cell.name] = cell } end |
.reset_registrations! ⇒ Object
Test support. Named apart from the server gem's own reset, because both gems open this module and a shared name would mean whichever loaded last silently won.
91 92 93 94 95 |
# File 'lib/hot_cell/cells.rb', line 91 def reset_registrations! @cells = nil @root = nil @group = nil end |
.warn_about_group ⇒ Object
A group this process does not hold cannot be given to a file, so without this the first conversion
fails as EPERM from the client's own chown — after the deployment is live and carrying traffic. The
check is local and needs no cell, so it reports a missing group-add even when every cell is down.
79 80 81 82 83 84 85 86 87 |
# File 'lib/hot_cell/cells.rb', line 79 def warn_about_group return if group.nil? || group == Process.gid || group == Process.egid return if Process.groups.include?(group) logger.warn "hotcell: HotCell.group is #{group} and this process is in #{Process.groups.sort.inspect}, " \ "so it cannot put a descriptor in that group and every conversion will fail with EPERM. " \ "Add the group to this container (Kamal: `group-add` under the role's `options:`), or " \ "unset HotCell.group where both sides run as one user." end |