tina4ruby 3.13.83 → 3.13.84
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/CHANGELOG.md +25 -27
- data/lib/tina4/cli.rb +70 -7
- data/lib/tina4/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a44456ebacba7cc7b8a9b8ffe8a973411c13f8055e3297a9bfb1cbb370d4397b
|
|
4
|
+
data.tar.gz: 1fce4c668f1439fd7c057a4b94e804670d7ce4672a0641f0a325e343e44bba3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9d18d9143115b94beb1f6a4c4e067702f3127c2f05b24dc29a0c9efe04419622d2bb3c8bf94a19c61d1dad38f75ba2cc76d3d15fd530e51ee22198990584173d
|
|
7
|
+
data.tar.gz: 506e937dc17782c347efc91af039b21ea9e73e76fd92457bc8eab345ab27a7f6bc454eafca2d999a930053494926450f5d615eb871463577f2b5983d127f5f6c
|
data/CHANGELOG.md
CHANGED
|
@@ -12,13 +12,6 @@ UNRELEASED work. When a version ships, its notes go to the release notes above.
|
|
|
12
12
|
|
|
13
13
|
## Unreleased
|
|
14
14
|
|
|
15
|
-
### Added
|
|
16
|
-
|
|
17
|
-
- **MQTT 3.1.1 client** (`Tina4::Mqtt` / `Tina4::MqttMessage`), zero-dependency (stdlib `socket` +
|
|
18
|
-
lazily-required `openssl`), verified against a real broker with no mocks. publish/subscribe/consume,
|
|
19
|
-
QoS 0/1, retained, Last Will, per-client TLS, QoS 2 refused loudly. Ruby ships all 97 shared
|
|
20
|
-
features plus its native ERB engine, for **98 built-in features**.
|
|
21
|
-
|
|
22
15
|
### Changed
|
|
23
16
|
|
|
24
17
|
- Internal: the SQL dialect-translation file is renamed
|
|
@@ -30,26 +23,31 @@ UNRELEASED work. When a version ships, its notes go to the release notes above.
|
|
|
30
23
|
|
|
31
24
|
### Fixed
|
|
32
25
|
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
framework's own
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
26
|
+
- **`tina4 deploy docker` produced images that could not start.** Of the eight
|
|
27
|
+
Dockerfile generators in the stack (four templates in the `tina4` CLI plus one
|
|
28
|
+
in each framework's own CLI), exactly one was correct. Python named
|
|
29
|
+
`python -m tina4_python.cli`, a package with no `__main__.py`, so the container
|
|
30
|
+
died on startup; PHP ran `php index.php <addr>`, but `App::run(?host, port)`
|
|
31
|
+
never reads argv so the address was dropped and production never engaged;
|
|
32
|
+
Node named a path that exists only inside the tina4-nodejs monorepo and
|
|
33
|
+
depended on tsx, which `npm ci --omit=dev` strips. Every generator now names a
|
|
34
|
+
published entry point and requests production. Verified by scaffolding,
|
|
35
|
+
generating, building and running a container for all four languages.
|
|
36
|
+
- **`serve` no longer kills PID 1.** The port-reclaim step read `lsof -ti`
|
|
37
|
+
without validating it. Where lsof prints a different shape, a non-numeric field
|
|
38
|
+
coerced to 0 or 1 -- and signalling PID 0 hits every process in the caller's
|
|
39
|
+
own process group. In a container the server IS PID 1, so it killed itself
|
|
40
|
+
(Node logged "Killed existing process on port 7148 (PID: 1 ...)" then exited
|
|
41
|
+
143; PHP logged the same attempt and survived by luck). Reclaiming is now
|
|
42
|
+
skipped inside a container, only all-digit PIDs are accepted, and PID 0, PID 1
|
|
43
|
+
and the current process are never signalled.
|
|
44
|
+
- **The Ruby image builds.** The builder stage was `ruby:3.3-slim`, which has no
|
|
45
|
+
compiler, so `bundle install` failed with `Gem::Ext::BuildError` on the first
|
|
46
|
+
native extension (date, json, nio4r, sqlite3 are all in the default set). The
|
|
47
|
+
builder is now the full `ruby:3.3` image and the slim runtime installs
|
|
48
|
+
`libsqlite3-0`. Bundler's `deployment true` is gone: it demands a lockfile
|
|
49
|
+
matching the image's bundler exactly, so a lockfile from a newer bundler on a
|
|
50
|
+
developer machine hard-failed the build.
|
|
53
51
|
|
|
54
52
|
## Earlier history (pre-3.x)
|
|
55
53
|
|
data/lib/tina4/cli.rb
CHANGED
|
@@ -340,18 +340,81 @@ module Tina4
|
|
|
340
340
|
end
|
|
341
341
|
|
|
342
342
|
# Kill any process listening on the given port. Returns true if killed.
|
|
343
|
+
# True when this process is running inside a container.
|
|
344
|
+
#
|
|
345
|
+
# Reclaiming a port makes sense on a dev machine, where a previous
|
|
346
|
+
# `tina4 serve` may still hold it. Inside a container the server IS the
|
|
347
|
+
# container, so there is no stale sibling to reclaim from -- and trying is
|
|
348
|
+
# actively dangerous (see #kill_process_on_port).
|
|
349
|
+
def in_container?
|
|
350
|
+
return true if File.exist?("/.dockerenv") || File.exist?("/run/.containerenv")
|
|
351
|
+
|
|
352
|
+
blob = File.read("/proc/1/cgroup")
|
|
353
|
+
blob.include?("docker") || blob.include?("containerd") || blob.include?("kubepods")
|
|
354
|
+
rescue SystemCallError
|
|
355
|
+
false
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
# Kill any process listening on `port`. Returns true if anything was killed.
|
|
359
|
+
#
|
|
360
|
+
# Every PID is validated before use. `pid.to_i` on a non-numeric field
|
|
361
|
+
# yields 0, and Process.kill("TERM", 0) signals EVERY process in the
|
|
362
|
+
# caller's own process group -- the server kills itself. That is exactly
|
|
363
|
+
# what happened in a container: "Killed existing process on port 7148
|
|
364
|
+
# (PID: 1 ...)" followed by exit 143.
|
|
365
|
+
#
|
|
366
|
+
# So: skip entirely in a container, accept only all-digit PIDs, and never
|
|
367
|
+
# signal 0 (our process group), 1 (init), or ourselves.
|
|
368
|
+
# The PIDs from `lsof -ti` output that are safe to signal.
|
|
369
|
+
#
|
|
370
|
+
# Pure so the safety rule can be tested directly. An unvalidated parse is a
|
|
371
|
+
# footgun with real teeth: where lsof prints a different shape than -ti
|
|
372
|
+
# implies, a non-numeric field becomes 0, and signalling PID 0 hits EVERY
|
|
373
|
+
# process in the caller's own process group -- the server kills itself.
|
|
374
|
+
#
|
|
375
|
+
# Accept only all-digit tokens; never PID 0 (our group), PID 1 (init),
|
|
376
|
+
# ourselves, or our own process group.
|
|
377
|
+
def selectable_pids(lsof_output, me, my_group = nil)
|
|
378
|
+
pids = []
|
|
379
|
+
lsof_output.split(/\s+/).each do |token|
|
|
380
|
+
next unless token.match?(/\A\d+\z/) # never coerce junk into a PID
|
|
381
|
+
|
|
382
|
+
pid = token.to_i
|
|
383
|
+
next if pid <= 1 || pid == me # 0 = our group, 1 = init, me = suicide
|
|
384
|
+
next if !my_group.nil? && pid == my_group
|
|
385
|
+
|
|
386
|
+
pids << pid unless pids.include?(pid)
|
|
387
|
+
end
|
|
388
|
+
pids
|
|
389
|
+
end
|
|
390
|
+
|
|
343
391
|
def kill_process_on_port(port)
|
|
392
|
+
return false if in_container?
|
|
393
|
+
|
|
344
394
|
result = `lsof -ti :#{port} 2>/dev/null`.strip
|
|
345
395
|
return false if result.empty?
|
|
346
396
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
Process.
|
|
350
|
-
rescue
|
|
351
|
-
|
|
397
|
+
me = Process.pid
|
|
398
|
+
my_group = begin
|
|
399
|
+
Process.getpgrp
|
|
400
|
+
rescue StandardError
|
|
401
|
+
nil
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
killed = []
|
|
405
|
+
selectable_pids(result, me, my_group).each do |pid|
|
|
406
|
+
begin
|
|
407
|
+
Process.kill("TERM", pid)
|
|
408
|
+
killed << pid.to_s
|
|
409
|
+
rescue Errno::ESRCH, Errno::EPERM
|
|
410
|
+
# Process already gone or no permission
|
|
411
|
+
end
|
|
352
412
|
end
|
|
413
|
+
|
|
414
|
+
return false if killed.empty?
|
|
415
|
+
|
|
353
416
|
sleep 0.5
|
|
354
|
-
puts " Killed existing process on port #{port} (PID: #{
|
|
417
|
+
puts " Killed existing process on port #{port} (PID: #{killed.join(', ')})"
|
|
355
418
|
true
|
|
356
419
|
rescue Errno::ENOENT
|
|
357
420
|
false
|
|
@@ -3136,7 +3199,7 @@ module Tina4
|
|
|
3136
3199
|
ENV SWAGGER_DESCRIPTION="Auto-generated API documentation"
|
|
3137
3200
|
|
|
3138
3201
|
# Start the server on all interfaces
|
|
3139
|
-
CMD ["bundle", "exec", "tina4ruby", "start", "-p", "7147", "-h", "0.0.0.0"]
|
|
3202
|
+
CMD ["bundle", "exec", "tina4ruby", "start", "-p", "7147", "-h", "0.0.0.0", "--production"]
|
|
3140
3203
|
DOCKERFILE
|
|
3141
3204
|
end
|
|
3142
3205
|
|
data/lib/tina4/version.rb
CHANGED