yamine 0.4.0 → 0.6.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/CHANGELOG.md +62 -0
- data/README.md +18 -4
- data/lib/ask/skills/yamine/SKILL.md +8 -5
- data/lib/yamine/cli/boot.rb +301 -45
- data/lib/yamine/cli/context.rb +1 -1
- data/lib/yamine/cli/system.rb +142 -4
- data/lib/yamine/cli.rb +6 -3
- data/lib/yamine/config.rb +12 -0
- data/lib/yamine/database.rb +216 -0
- data/lib/yamine/readiness.rb +232 -0
- data/lib/yamine/resolver.rb +4 -2
- data/lib/yamine/runner.rb +53 -5
- data/lib/yamine/version.rb +1 -1
- data/lib/yamine.rb +2 -0
- metadata +3 -1
data/lib/yamine/resolver.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Yamine
|
|
|
9
9
|
module_function
|
|
10
10
|
|
|
11
11
|
Result = Struct.new(:app, :tld, :host, :processes, :secrets,
|
|
12
|
-
:sources, :variant, keyword_init: true)
|
|
12
|
+
:sources, :variant, :db, :env, keyword_init: true)
|
|
13
13
|
|
|
14
14
|
def resolve(dir = Dir.pwd, variant: nil, tld: nil, host: nil)
|
|
15
15
|
config = Config.load(dir, variant: variant)
|
|
@@ -51,7 +51,9 @@ module Yamine
|
|
|
51
51
|
processes: processes,
|
|
52
52
|
secrets: config.secrets,
|
|
53
53
|
sources: sources,
|
|
54
|
-
variant: variant_name
|
|
54
|
+
variant: variant_name,
|
|
55
|
+
db: config.data["db"],
|
|
56
|
+
env: config.env_config
|
|
55
57
|
)
|
|
56
58
|
end
|
|
57
59
|
|
data/lib/yamine/runner.rb
CHANGED
|
@@ -91,22 +91,60 @@ module Yamine
|
|
|
91
91
|
|
|
92
92
|
# Run an arbitrary command with PORT + YAMINE_URL. Returns App.
|
|
93
93
|
# register: false spawns without a route (background processes).
|
|
94
|
+
# Child output goes to log/yamine-<name>.log so `--wait` failure
|
|
95
|
+
# payloads can tail it (same file the managed path uses).
|
|
94
96
|
def boot_run(name:, hostname:, url:, dir:, command:, port: nil, force: false,
|
|
95
|
-
rails_dev_host: nil, register: true)
|
|
97
|
+
rails_dev_host: nil, register: true, database_url: nil, spec: nil)
|
|
96
98
|
port ||= Ports.find_free
|
|
97
|
-
env = child_env(dir, url: url, port: port, rails_dev_host: rails_dev_host
|
|
98
|
-
|
|
99
|
+
env = child_env(dir, url: url, port: port, rails_dev_host: rails_dev_host,
|
|
100
|
+
database_url: database_url)
|
|
101
|
+
path = log_path(dir, name)
|
|
102
|
+
pid = with_clean_env { spawn(env, *command, chdir: dir, out: path, err: [:child, :out]) }
|
|
99
103
|
Process.detach(pid)
|
|
100
104
|
target = "127.0.0.1:#{port}"
|
|
101
105
|
if register
|
|
102
|
-
|
|
106
|
+
spec ||= { "dir" => File.expand_path(dir), "proc" => name }
|
|
107
|
+
@store.add_route(hostname, target, Process.pid, kind: "tcp",
|
|
108
|
+
force: force, spec: spec)
|
|
103
109
|
write_backend_pid(hostname, pid)
|
|
104
110
|
end
|
|
105
111
|
App.new(name: name, hostname: hostname, url: url, pid: pid,
|
|
106
112
|
target: target, kind: "tcp", command: command)
|
|
107
113
|
end
|
|
108
114
|
|
|
109
|
-
|
|
115
|
+
# Spawn without registering or waiting: the --wait path spins the
|
|
116
|
+
# whole tree up concurrently, then polls every route until healthy.
|
|
117
|
+
# Returns the placeholder App (target known before bind). Fate of
|
|
118
|
+
# the backend is decided by wait, not by spawn.
|
|
119
|
+
def spawn_http(name:, hostname:, url:, dir:, command:, port:, rails_dev_host: nil,
|
|
120
|
+
database_url: nil, force: false)
|
|
121
|
+
env = child_env(dir, url: url, port: port, rails_dev_host: rails_dev_host,
|
|
122
|
+
database_url: database_url)
|
|
123
|
+
path = log_path(dir, name)
|
|
124
|
+
pid = with_clean_env { spawn(env, *command, chdir: dir, out: path, err: [:child, :out]) }
|
|
125
|
+
Process.detach(pid)
|
|
126
|
+
App.new(name: name, hostname: hostname, url: url, pid: pid,
|
|
127
|
+
target: "127.0.0.1:#{port}", kind: "tcp", command: command)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Register an already-spawned backend: route + sidecar, together.
|
|
131
|
+
def adopt(hostname, app, force: false, spec: nil)
|
|
132
|
+
@store.add_route(hostname, app.target, Process.pid, kind: app.kind,
|
|
133
|
+
force: force, spec: spec)
|
|
134
|
+
write_backend_pid(hostname, app.pid)
|
|
135
|
+
nil
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Still running? A port that accepts is not proof of life, but a
|
|
139
|
+
# reaped/dead pid is proof of death — that is all wait needs.
|
|
140
|
+
def spawned?(pid)
|
|
141
|
+
Process.kill(0, pid)
|
|
142
|
+
true
|
|
143
|
+
rescue SystemCallError
|
|
144
|
+
false
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def child_env(dir, url:, port:, rails_dev_host: nil, database_url: nil)
|
|
110
148
|
env = { "YAMINE_URL" => url }
|
|
111
149
|
env["PORT"] = port.to_s if port
|
|
112
150
|
env["HOST"] = "127.0.0.1"
|
|
@@ -116,6 +154,10 @@ module Yamine
|
|
|
116
154
|
# proxied hostname so Rails apps boot behind yamine with zero
|
|
117
155
|
# config — this replaces the yamine-rails hosts patch.
|
|
118
156
|
env["RAILS_DEVELOPMENT_HOSTS"] = rails_dev_host if rails_dev_host
|
|
157
|
+
# Per-worktree database: every process in this worktree shares one
|
|
158
|
+
# isolated database. Frameworks that honor DATABASE_URL (Rails,
|
|
159
|
+
# Django, most Node) get isolation for free; others ignore it.
|
|
160
|
+
env["DATABASE_URL"] = database_url if database_url
|
|
119
161
|
env
|
|
120
162
|
end
|
|
121
163
|
|
|
@@ -212,6 +254,8 @@ module Yamine
|
|
|
212
254
|
end
|
|
213
255
|
end
|
|
214
256
|
|
|
257
|
+
# Log path for a process — public so the --wait failure payload
|
|
258
|
+
# can tail the right file for the phase that failed.
|
|
215
259
|
def log_path(dir, name)
|
|
216
260
|
path = File.expand_path(File.join(dir, "log", "yamine-#{name}.log"))
|
|
217
261
|
FileUtils.mkdir_p(File.dirname(path))
|
|
@@ -229,6 +273,8 @@ module Yamine
|
|
|
229
273
|
nil
|
|
230
274
|
end
|
|
231
275
|
|
|
276
|
+
# Last lines of a log file for failure payloads. Public so the
|
|
277
|
+
# --wait path can attribute the right tail to the failed phase.
|
|
232
278
|
def log_tail(path, lines: 10)
|
|
233
279
|
return "(no log file)" unless File.file?(path)
|
|
234
280
|
|
|
@@ -237,6 +283,8 @@ module Yamine
|
|
|
237
283
|
"(unreadable log)"
|
|
238
284
|
end
|
|
239
285
|
|
|
286
|
+
private
|
|
287
|
+
|
|
240
288
|
def stop_pid(pid)
|
|
241
289
|
Process.kill("TERM", pid)
|
|
242
290
|
rescue SystemCallError
|
data/lib/yamine/version.rb
CHANGED
data/lib/yamine.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative "yamine/version"
|
|
4
4
|
require_relative "yamine/errors"
|
|
5
5
|
require_relative "yamine/agent"
|
|
6
|
+
require_relative "yamine/database"
|
|
6
7
|
require_relative "yamine/sanitize"
|
|
7
8
|
require_relative "yamine/hostname"
|
|
8
9
|
require_relative "yamine/inference"
|
|
@@ -20,6 +21,7 @@ require_relative "yamine/proxy"
|
|
|
20
21
|
require_relative "yamine/proxy_control"
|
|
21
22
|
require_relative "yamine/supervisor"
|
|
22
23
|
require_relative "yamine/runner"
|
|
24
|
+
require_relative "yamine/readiness"
|
|
23
25
|
require_relative "yamine/resolver"
|
|
24
26
|
require_relative "yamine/trust"
|
|
25
27
|
require_relative "yamine/doctor"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yamine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kaka Ruto
|
|
@@ -91,6 +91,7 @@ files:
|
|
|
91
91
|
- lib/yamine/cli/system.rb
|
|
92
92
|
- lib/yamine/command.rb
|
|
93
93
|
- lib/yamine/config.rb
|
|
94
|
+
- lib/yamine/database.rb
|
|
94
95
|
- lib/yamine/doctor.rb
|
|
95
96
|
- lib/yamine/errors.rb
|
|
96
97
|
- lib/yamine/framework.rb
|
|
@@ -103,6 +104,7 @@ files:
|
|
|
103
104
|
- lib/yamine/procfile.rb
|
|
104
105
|
- lib/yamine/proxy.rb
|
|
105
106
|
- lib/yamine/proxy_control.rb
|
|
107
|
+
- lib/yamine/readiness.rb
|
|
106
108
|
- lib/yamine/resolver.rb
|
|
107
109
|
- lib/yamine/route_store.rb
|
|
108
110
|
- lib/yamine/runner.rb
|