rb-portless 0.5.1 → 0.5.2
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 +13 -0
- data/lib/portless/route_store.rb +18 -3
- data/lib/portless/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8a45c842e40387472fcb2ea9bb452cdd1015566db6de7ee653824f881a522af1
|
|
4
|
+
data.tar.gz: 6b3c996607326c31b3abfb1fd8916cf3abe81ead74af7de13be36a8cc07bd119
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 593a5feaabae0a2781acd89831eeecb3ac03c99bc0e721c7626eeaf8f3a6c2b2f836d7160f04dffabae9645825753970bfd6545495a730c298a5f6eca9f06a71
|
|
7
|
+
data.tar.gz: 607dd39cc15026cbddcc0af63d5f6a4f21b536511a34174df10517e1ff0807db3d1bea0df7c5005a9c5aed3c60cddad83df2edb6f6c91aa840d9bb5042da7b94
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to this project are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/), and the project adheres to
|
|
5
5
|
[Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.5.2] — 2026-09-08
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **`run --force` killed the run doing the forcing.** Taking over a hostname
|
|
12
|
+
held by a *static alias* passed its pid straight to `kill`, and an alias
|
|
13
|
+
records pid 0 — which to `kill(2)` means "every process in my group". So
|
|
14
|
+
`bin/dev --force` TERMed itself and its shell job, printing `Terminated: 15`
|
|
15
|
+
before the dev server ever started. An alias has no owner process to displace,
|
|
16
|
+
so force now just takes the hostname over, and `terminate` refuses any pid
|
|
17
|
+
that isn't a real process. The conflict message you get *without* `--force`
|
|
18
|
+
now says "a static alias" instead of the unlookuppable "pid 0".
|
|
19
|
+
|
|
7
20
|
## [0.5.1]
|
|
8
21
|
|
|
9
22
|
### Security
|
data/lib/portless/route_store.rb
CHANGED
|
@@ -45,7 +45,9 @@ module Portless
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
# Register (or replace) a route. Conflicts with a *live* different owner raise
|
|
48
|
-
# unless force, which SIGTERMs the incumbent. Alias routes use pid 0
|
|
48
|
+
# unless force, which SIGTERMs the incumbent. Alias routes use pid 0: they
|
|
49
|
+
# count as live (never reaped) but have no process, so force just takes the
|
|
50
|
+
# hostname over. Public
|
|
49
51
|
# share URLs (tailscale/ngrok), when present, are recorded so `list` can show
|
|
50
52
|
# them while the run is active.
|
|
51
53
|
def add(hostname:, port:, pid:, force: false, tailscale: nil, ngrok: nil, lan: false)
|
|
@@ -55,7 +57,7 @@ module Portless
|
|
|
55
57
|
if existing && existing["pid"].to_i != pid.to_i && !dead?(existing["pid"])
|
|
56
58
|
unless force
|
|
57
59
|
raise RouteConflictError,
|
|
58
|
-
"#{hostname} is already served by
|
|
60
|
+
"#{hostname} is already served by #{owner(existing)} — pass --force to take it over"
|
|
59
61
|
end
|
|
60
62
|
terminate(existing["pid"])
|
|
61
63
|
end
|
|
@@ -154,8 +156,21 @@ module Portless
|
|
|
154
156
|
true # exists, owned by someone else (e.g. root proxy)
|
|
155
157
|
end
|
|
156
158
|
|
|
159
|
+
# Who to blame in a conflict message. An alias has no process behind it, so
|
|
160
|
+
# "pid 0" would be nonsense to read and impossible to go look up.
|
|
161
|
+
def owner(route)
|
|
162
|
+
route["pid"].to_i.zero? ? "a static alias" : "pid #{route['pid']}"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Displace the route's current owner. Only a real pid gets signalled: 0 means
|
|
166
|
+
# "my whole process group" and a negative one means "that group", so passing
|
|
167
|
+
# an alias route straight through would TERM the very run asking for the
|
|
168
|
+
# takeover (and its shell job with it) instead of the incumbent.
|
|
157
169
|
def terminate(pid)
|
|
158
|
-
|
|
170
|
+
pid = pid.to_i
|
|
171
|
+
return unless pid.positive?
|
|
172
|
+
|
|
173
|
+
Process.kill("TERM", pid)
|
|
159
174
|
rescue StandardError
|
|
160
175
|
nil
|
|
161
176
|
end
|
data/lib/portless/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rb-portless
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Afonso
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08
|
|
11
|
+
date: 2026-09-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: async
|