kuby-core 0.11.14 → 0.13.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 +29 -0
- data/Gemfile +2 -2
- data/README.md +2 -1
- data/bin/kuby +2 -0
- data/kuby-core.gemspec +2 -2
- data/lib/kuby/basic_logger.rb +1 -1
- data/lib/kuby/cli_base.rb +9 -4
- data/lib/kuby/commands.rb +16 -69
- data/lib/kuby/docker/alpine.rb +2 -1
- data/lib/kuby/docker/app_image.rb +19 -0
- data/lib/kuby/docker/bundler_phase.rb +9 -3
- data/lib/kuby/docker/cli.rb +4 -12
- data/lib/kuby/docker/docker_uri.rb +18 -7
- data/lib/kuby/docker/errors.rb +1 -19
- data/lib/kuby/docker/image.rb +115 -0
- data/lib/kuby/docker/layer.rb +0 -7
- data/lib/kuby/docker/local_tags.rb +9 -10
- data/lib/kuby/docker/package_phase.rb +0 -5
- data/lib/kuby/docker/packages.rb +1 -0
- data/lib/kuby/docker/remote_tags.rb +10 -5
- data/lib/kuby/docker/setup_phase.rb +17 -9
- data/lib/kuby/docker/spec.rb +29 -62
- data/lib/kuby/docker/timestamp_tag.rb +8 -1
- data/lib/kuby/docker/timestamped_image.rb +113 -0
- data/lib/kuby/docker/yarn_phase.rb +2 -2
- data/lib/kuby/docker.rb +27 -25
- data/lib/kuby/environment.rb +1 -10
- data/lib/kuby/kubernetes/bare_metal_provider.rb +53 -0
- data/lib/kuby/kubernetes/deployer.rb +2 -1
- data/lib/kuby/kubernetes/docker_desktop_provider.rb +0 -15
- data/lib/kuby/kubernetes/spec.rb +21 -17
- data/lib/kuby/kubernetes.rb +1 -0
- data/lib/kuby/plugin.rb +2 -2
- data/lib/kuby/plugins/rails_app/assets.rb +60 -70
- data/lib/kuby/plugins/rails_app/assets_image.rb +55 -0
- data/lib/kuby/plugins/rails_app/plugin.rb +54 -213
- data/lib/kuby/plugins/rails_app.rb +1 -0
- data/lib/kuby/tasks.rb +30 -69
- data/lib/kuby/version.rb +1 -1
- data/lib/kuby.rb +3 -20
- data/spec/docker/spec_spec.rb +21 -118
- data/spec/docker/timestamped_image_spec.rb +123 -0
- data/spec/spec_helper.rb +10 -11
- metadata +11 -14
- data/lib/kuby/dev_setup.rb +0 -346
- data/lib/kuby/docker/dev_spec.rb +0 -202
- data/lib/kuby/docker/metadata.rb +0 -90
- data/lib/kuby/docker/tags.rb +0 -92
- data/lib/kuby/rails_commands.rb +0 -84
- data/spec/docker/metadata_spec.rb +0 -73
- data/spec/dummy/Gemfile.lock +0 -223
- data/spec/dummy/config/master.key +0 -1
- data/spec/dummy/tmp/cache/bootsnap-load-path-cache +0 -0
data/lib/kuby/dev_setup.rb
DELETED
@@ -1,346 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
|
-
module Kuby
|
4
|
-
class Spinner
|
5
|
-
extend T::Sig
|
6
|
-
|
7
|
-
PIECES = T.let(%w(- \\ | /).freeze, T::Array[String])
|
8
|
-
INTERVAL = T.let(0.2, Float) # seconds
|
9
|
-
|
10
|
-
sig {
|
11
|
-
params(
|
12
|
-
message: String,
|
13
|
-
block: T.proc.params(spinner: Spinner).void
|
14
|
-
)
|
15
|
-
.void
|
16
|
-
}
|
17
|
-
def self.spin(message, &block)
|
18
|
-
yield new(message)
|
19
|
-
end
|
20
|
-
|
21
|
-
sig { returns(String) }
|
22
|
-
attr_reader :message
|
23
|
-
|
24
|
-
sig { returns(Symbol) }
|
25
|
-
attr_reader :status
|
26
|
-
|
27
|
-
sig { params(message: String).void }
|
28
|
-
def initialize(message)
|
29
|
-
@message = T.let(message, String)
|
30
|
-
@status = T.let(:running, Symbol)
|
31
|
-
@thread = T.let(Thread.new do
|
32
|
-
counter = 0
|
33
|
-
|
34
|
-
while true
|
35
|
-
case status
|
36
|
-
when :running
|
37
|
-
piece = PIECES[counter % PIECES.size]
|
38
|
-
STDOUT.write "\r[#{piece}] #{message}"
|
39
|
-
sleep INTERVAL
|
40
|
-
counter += 1
|
41
|
-
when :success
|
42
|
-
STDOUT.write("\r[+] #{message}")
|
43
|
-
break
|
44
|
-
when :failure
|
45
|
-
STDOUT.write("\r[×] #{message}")
|
46
|
-
break
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
puts
|
51
|
-
end, Thread)
|
52
|
-
end
|
53
|
-
|
54
|
-
sig { void }
|
55
|
-
def success
|
56
|
-
@status = :success
|
57
|
-
@thread.join
|
58
|
-
end
|
59
|
-
|
60
|
-
sig { void }
|
61
|
-
def failure
|
62
|
-
@status = :failure
|
63
|
-
@thread.join
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
class SetupTask
|
68
|
-
extend T::Sig
|
69
|
-
|
70
|
-
sig { returns(String) }
|
71
|
-
attr_reader :message
|
72
|
-
|
73
|
-
sig { returns(T.proc.void) }
|
74
|
-
attr_reader :callable
|
75
|
-
|
76
|
-
sig { params(message: String, callable: T.proc.void).void }
|
77
|
-
def initialize(message, callable)
|
78
|
-
@message = message
|
79
|
-
@callable = callable
|
80
|
-
end
|
81
|
-
|
82
|
-
sig { void }
|
83
|
-
def run
|
84
|
-
callable.call
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
class Pipe
|
89
|
-
extend T::Sig
|
90
|
-
|
91
|
-
sig { returns(Symbol) }
|
92
|
-
attr_reader :name
|
93
|
-
|
94
|
-
sig { returns(T.untyped) }
|
95
|
-
attr_reader :cli
|
96
|
-
|
97
|
-
sig { returns(StringIO) }
|
98
|
-
attr_reader :out
|
99
|
-
|
100
|
-
sig { returns(StringIO) }
|
101
|
-
attr_reader :err
|
102
|
-
|
103
|
-
sig { params(name: Symbol, cli: T.untyped).void }
|
104
|
-
def initialize(name, cli)
|
105
|
-
@name = T.let(name, Symbol)
|
106
|
-
@cli = T.let(cli, T.untyped)
|
107
|
-
@out = T.let(StringIO.new, StringIO)
|
108
|
-
@err = T.let(StringIO.new, StringIO)
|
109
|
-
end
|
110
|
-
|
111
|
-
sig { params(block: T.proc.void).void }
|
112
|
-
def wrap(&block)
|
113
|
-
cli.with_pipes(out, err) do
|
114
|
-
block.call
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
sig { returns(T::Boolean) }
|
119
|
-
def success?
|
120
|
-
cli.last_status.nil? || cli.last_status.success?
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
class Pipes
|
125
|
-
extend T::Sig
|
126
|
-
extend T::Generic
|
127
|
-
|
128
|
-
include Enumerable
|
129
|
-
|
130
|
-
Elem = type_member(fixed: Pipe)
|
131
|
-
|
132
|
-
sig { returns(T::Array[Pipe]) }
|
133
|
-
attr_reader :pipes
|
134
|
-
|
135
|
-
sig { returns(T.nilable(StandardError)) }
|
136
|
-
attr_reader :ex
|
137
|
-
|
138
|
-
sig { params(clis: T::Hash[Symbol, T.untyped]).returns(Pipes) }
|
139
|
-
def self.build(clis)
|
140
|
-
new(clis.map { |name, cli| Pipe.new(name, cli) })
|
141
|
-
end
|
142
|
-
|
143
|
-
sig { params(pipes: T::Array[Pipe]).void }
|
144
|
-
def initialize(pipes)
|
145
|
-
@ex = T.let(@ex, T.nilable(StandardError))
|
146
|
-
@pipes = T.let(pipes, T::Array[Pipe])
|
147
|
-
end
|
148
|
-
|
149
|
-
sig {
|
150
|
-
override.params(
|
151
|
-
block: T.proc.params(package: Pipe).void
|
152
|
-
)
|
153
|
-
.void
|
154
|
-
}
|
155
|
-
def each(&block)
|
156
|
-
pipes.each(&block)
|
157
|
-
end
|
158
|
-
|
159
|
-
sig { params(block: T.proc.void).void }
|
160
|
-
def wrap(&block)
|
161
|
-
do_wrap(pipes, &block)
|
162
|
-
end
|
163
|
-
|
164
|
-
sig { returns(T::Boolean) }
|
165
|
-
def success?
|
166
|
-
pipes.all?(&:success?) && !ex
|
167
|
-
end
|
168
|
-
|
169
|
-
private
|
170
|
-
|
171
|
-
sig {
|
172
|
-
params(
|
173
|
-
remaining_pipes: T::Array[Pipe],
|
174
|
-
block: T.proc.void
|
175
|
-
)
|
176
|
-
.void
|
177
|
-
}
|
178
|
-
def do_wrap(remaining_pipes, &block)
|
179
|
-
if remaining_pipes.empty?
|
180
|
-
begin
|
181
|
-
yield
|
182
|
-
rescue => e
|
183
|
-
@ex = e
|
184
|
-
end
|
185
|
-
|
186
|
-
return
|
187
|
-
end
|
188
|
-
|
189
|
-
T.must(remaining_pipes[0]).wrap do
|
190
|
-
do_wrap(T.must(remaining_pipes[1..-1]), &block)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
class SetupTaskList
|
196
|
-
extend T::Sig
|
197
|
-
|
198
|
-
sig { returns(T::Array[SetupTask]) }
|
199
|
-
attr_reader :tasks
|
200
|
-
|
201
|
-
sig { returns T::Hash[Symbol, T.untyped] }
|
202
|
-
attr_reader :clis
|
203
|
-
|
204
|
-
sig { params(tasks: T::Array[SetupTask], clis: T::Hash[Symbol, T.untyped]).void }
|
205
|
-
def initialize(tasks, clis)
|
206
|
-
@tasks = tasks
|
207
|
-
@clis = clis
|
208
|
-
end
|
209
|
-
|
210
|
-
sig { void }
|
211
|
-
def run
|
212
|
-
tasks.each do |task|
|
213
|
-
pipes = Pipes.build(clis)
|
214
|
-
|
215
|
-
Spinner.spin(task.message) do |spinner|
|
216
|
-
pipes.wrap { task.run }
|
217
|
-
|
218
|
-
if pipes.success?
|
219
|
-
spinner.success
|
220
|
-
else
|
221
|
-
spinner.failure
|
222
|
-
print_error(pipes.ex)
|
223
|
-
|
224
|
-
pipes.each do |pipe|
|
225
|
-
print_streams(pipe)
|
226
|
-
end
|
227
|
-
|
228
|
-
return false
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
true
|
234
|
-
end
|
235
|
-
|
236
|
-
private
|
237
|
-
|
238
|
-
sig { params(pipe: Pipe).void }
|
239
|
-
def print_streams(pipe)
|
240
|
-
unless pipe.out.string.strip.empty?
|
241
|
-
puts("========= #{pipe.name.upcase} STDOUT ========")
|
242
|
-
puts pipe.out.string
|
243
|
-
end
|
244
|
-
|
245
|
-
unless pipe.err.string.strip.empty?
|
246
|
-
puts("========= #{pipe.name.upcase} STDERR ========")
|
247
|
-
puts pipe.err.string
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
sig { params(ex: T.nilable(StandardError)).void }
|
252
|
-
def print_error(ex)
|
253
|
-
return unless ex
|
254
|
-
puts("========= RUBY ERROR ========")
|
255
|
-
puts(ex.message)
|
256
|
-
puts(T.must(ex.backtrace).join("\n"))
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
class DevSetup
|
261
|
-
extend T::Sig
|
262
|
-
|
263
|
-
sig { returns(Environment) }
|
264
|
-
attr_reader :environment
|
265
|
-
|
266
|
-
sig { params(environment: Environment).void }
|
267
|
-
def initialize(environment)
|
268
|
-
@environment = T.let(environment, Environment)
|
269
|
-
@setup_tasks = T.let(@setup_tasks, T.nilable(T::Array[SetupTask]))
|
270
|
-
@clis = T.let(@clis, T.nilable(T::Hash[Symbol, T.untyped]))
|
271
|
-
@tasks = T.let(@tasks, T.nilable(Tasks))
|
272
|
-
end
|
273
|
-
|
274
|
-
sig { void }
|
275
|
-
def run
|
276
|
-
SetupTaskList.new(setup_tasks, clis).run
|
277
|
-
end
|
278
|
-
|
279
|
-
private
|
280
|
-
|
281
|
-
sig { returns(T::Array[SetupTask]) }
|
282
|
-
def setup_tasks
|
283
|
-
@setup_tasks ||= [
|
284
|
-
SetupTask.new(
|
285
|
-
'Building dev Docker image', -> { tasks.build }
|
286
|
-
),
|
287
|
-
|
288
|
-
SetupTask.new(
|
289
|
-
'Setting up local Kubernetes cluster', -> { tasks.setup }
|
290
|
-
),
|
291
|
-
|
292
|
-
SetupTask.new(
|
293
|
-
'Deploying dev environment', -> { tasks.deploy }
|
294
|
-
),
|
295
|
-
|
296
|
-
SetupTask.new(
|
297
|
-
'Installing bundler', -> {
|
298
|
-
tasks.remote_system("gem install bundler -v #{Bundler::VERSION}")
|
299
|
-
}
|
300
|
-
),
|
301
|
-
|
302
|
-
SetupTask.new(
|
303
|
-
'Installing bundled gems', -> { tasks.remote_system('bundle install') }
|
304
|
-
),
|
305
|
-
|
306
|
-
SetupTask.new(
|
307
|
-
'Installing Javascript packages', -> { tasks.remote_system('yarn install') }
|
308
|
-
),
|
309
|
-
|
310
|
-
SetupTask.new(
|
311
|
-
'Creating database', -> { tasks.remote_system('bundle exec rake db:create') }
|
312
|
-
),
|
313
|
-
|
314
|
-
SetupTask.new(
|
315
|
-
'Migrating database', -> { tasks.remote_system('bundle exec rake db:migrate') }
|
316
|
-
)
|
317
|
-
]
|
318
|
-
end
|
319
|
-
|
320
|
-
sig { returns(Kubernetes::Spec) }
|
321
|
-
def kubernetes
|
322
|
-
environment.kubernetes
|
323
|
-
end
|
324
|
-
|
325
|
-
sig { returns(Docker::Spec) }
|
326
|
-
def docker
|
327
|
-
environment.docker
|
328
|
-
end
|
329
|
-
|
330
|
-
sig { returns T::Hash[Symbol, T.untyped] }
|
331
|
-
def clis
|
332
|
-
@clis ||= {
|
333
|
-
kubectl: kubernetes.provider.kubernetes_cli,
|
334
|
-
helm: kubernetes.provider.helm_cli,
|
335
|
-
krane: kubernetes.provider.deployer,
|
336
|
-
docker: docker.cli,
|
337
|
-
kuby: Kuby.logger
|
338
|
-
}
|
339
|
-
end
|
340
|
-
|
341
|
-
sig { returns(Tasks) }
|
342
|
-
def tasks
|
343
|
-
@tasks ||= Kuby::Tasks.new(environment)
|
344
|
-
end
|
345
|
-
end
|
346
|
-
end
|
data/lib/kuby/docker/dev_spec.rb
DELETED
@@ -1,202 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
|
-
module Kuby
|
4
|
-
module Docker
|
5
|
-
class WebserverDevPhase < Layer
|
6
|
-
extend T::Sig
|
7
|
-
|
8
|
-
DEFAULT_PORT = T.let(3000, Integer)
|
9
|
-
|
10
|
-
sig { params(port: Integer).void }
|
11
|
-
attr_writer :port
|
12
|
-
|
13
|
-
sig { params(environment: Environment).void }
|
14
|
-
def initialize(environment)
|
15
|
-
super
|
16
|
-
|
17
|
-
@port = T.let(@port, T.nilable(Integer))
|
18
|
-
end
|
19
|
-
|
20
|
-
sig { override.params(dockerfile: Dockerfile).void }
|
21
|
-
def apply_to(dockerfile)
|
22
|
-
dockerfile.expose(port)
|
23
|
-
end
|
24
|
-
|
25
|
-
sig { returns(Integer) }
|
26
|
-
def port
|
27
|
-
@port || DEFAULT_PORT
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class DevSpec
|
32
|
-
extend T::Sig
|
33
|
-
|
34
|
-
sig { returns(Environment) }
|
35
|
-
attr_reader :environment
|
36
|
-
|
37
|
-
sig { params(environment: Environment).void }
|
38
|
-
def initialize(environment)
|
39
|
-
@environment = environment
|
40
|
-
|
41
|
-
@setup_phase = T.let(@setup_phase, T.nilable(SetupPhase))
|
42
|
-
@package_phase = T.let(@package_phase, T.nilable(PackagePhase))
|
43
|
-
@webserver_phase = T.let(@webserver_phase, T.nilable(WebserverDevPhase))
|
44
|
-
@metadata = T.let(@metadata, T.nilable(Metadata))
|
45
|
-
@distro_spec = T.let(@distro_spec, T.nilable(Distro))
|
46
|
-
@cli = T.let(@cli, T.nilable(CLI))
|
47
|
-
@tags = T.let(@tags, T.nilable(LocalTags))
|
48
|
-
@layer_stack = T.let(@layer_stack, T.nilable(Docker::LayerStack))
|
49
|
-
end
|
50
|
-
|
51
|
-
sig { params(dir: String).void }
|
52
|
-
def working_dir(dir)
|
53
|
-
setup_phase.working_dir = dir
|
54
|
-
end
|
55
|
-
|
56
|
-
sig { params(env: String).void }
|
57
|
-
def rails_env(env)
|
58
|
-
setup_phase.rails_env = env
|
59
|
-
end
|
60
|
-
|
61
|
-
sig {
|
62
|
-
params(
|
63
|
-
package_name: Symbol,
|
64
|
-
version: T.nilable(String)
|
65
|
-
)
|
66
|
-
.void
|
67
|
-
}
|
68
|
-
def package(package_name, version = nil)
|
69
|
-
package_phase.add(package_name, version)
|
70
|
-
end
|
71
|
-
|
72
|
-
sig { params(distro_name: Symbol).void }
|
73
|
-
def distro(distro_name)
|
74
|
-
metadata.distro = distro_name
|
75
|
-
@distro_spec = nil
|
76
|
-
end
|
77
|
-
|
78
|
-
sig { params(port: Integer).void }
|
79
|
-
def port(port)
|
80
|
-
webserver_phase.port = port
|
81
|
-
end
|
82
|
-
|
83
|
-
sig {
|
84
|
-
params(
|
85
|
-
name: Symbol,
|
86
|
-
layer: T.nilable(Layer),
|
87
|
-
block: T.nilable(T.proc.params(df: Dockerfile).void)
|
88
|
-
)
|
89
|
-
.void
|
90
|
-
}
|
91
|
-
def use(name, layer = nil, &block)
|
92
|
-
layer_stack.use(name, layer, &block)
|
93
|
-
end
|
94
|
-
|
95
|
-
sig {
|
96
|
-
params(
|
97
|
-
name: Symbol,
|
98
|
-
layer: T.nilable(T.any(Layer, T::Hash[Symbol, T.untyped])),
|
99
|
-
options: T::Hash[Symbol, T.untyped],
|
100
|
-
block: T.nilable(T.proc.params(df: Dockerfile).void)
|
101
|
-
)
|
102
|
-
.void
|
103
|
-
}
|
104
|
-
def insert(name, layer = nil, options = {}, &block)
|
105
|
-
layer_stack.insert(name, layer, options, &block)
|
106
|
-
end
|
107
|
-
|
108
|
-
sig { params(name: Symbol).void }
|
109
|
-
def delete(name)
|
110
|
-
layer_stack.delete(name)
|
111
|
-
end
|
112
|
-
|
113
|
-
sig { params(name: Symbol).returns(T::Boolean) }
|
114
|
-
def exists?(name)
|
115
|
-
layer_stack.includes?(name)
|
116
|
-
end
|
117
|
-
|
118
|
-
sig {
|
119
|
-
params(block: T.nilable(T.proc.void)).returns(Credentials)
|
120
|
-
}
|
121
|
-
def credentials(&block)
|
122
|
-
raise 'Docker credentials are not supported in the development environment'
|
123
|
-
end
|
124
|
-
|
125
|
-
sig { returns(Dockerfile) }
|
126
|
-
def to_dockerfile
|
127
|
-
Dockerfile.new.tap do |df|
|
128
|
-
layer_stack.each { |layer| layer.apply_to(df) }
|
129
|
-
df.cmd("#{distro_spec.shell_exe} -c 'while test 1; do sleep 5; done'")
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
sig { returns(SetupPhase) }
|
134
|
-
def setup_phase
|
135
|
-
@setup_phase ||= SetupPhase.new(environment)
|
136
|
-
end
|
137
|
-
|
138
|
-
sig { returns(PackagePhase) }
|
139
|
-
def package_phase
|
140
|
-
@package_phase ||= PackagePhase.new(environment)
|
141
|
-
end
|
142
|
-
|
143
|
-
sig { returns(WebserverDevPhase) }
|
144
|
-
def webserver_phase
|
145
|
-
@webserver_phase ||= WebserverDevPhase.new(environment)
|
146
|
-
end
|
147
|
-
|
148
|
-
sig { returns(Metadata) }
|
149
|
-
def metadata
|
150
|
-
@metadata ||= Metadata.new(environment)
|
151
|
-
end
|
152
|
-
|
153
|
-
sig { returns(Distro) }
|
154
|
-
def distro_spec
|
155
|
-
@distro_spec ||= if distro_klass = Kuby.distros[metadata.distro]
|
156
|
-
distro_klass.new(self)
|
157
|
-
else
|
158
|
-
raise MissingDistroError, "distro '#{metadata.distro}' hasn't been registered"
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
sig { returns(String) }
|
163
|
-
def tag
|
164
|
-
t = ENV.fetch('KUBY_DOCKER_TAG') do
|
165
|
-
tags.latest_timestamp_tag
|
166
|
-
end
|
167
|
-
|
168
|
-
unless t
|
169
|
-
raise MissingTagError, 'could not find latest timestamped tag'
|
170
|
-
end
|
171
|
-
|
172
|
-
t.to_s
|
173
|
-
end
|
174
|
-
|
175
|
-
sig { params(current_tag: String).returns(String) }
|
176
|
-
def previous_tag(current_tag)
|
177
|
-
raise MissingTagError, 'cannot roll back in the development environment'
|
178
|
-
end
|
179
|
-
|
180
|
-
sig { returns(CLI) }
|
181
|
-
def cli
|
182
|
-
@cli ||= Docker::CLI.new
|
183
|
-
end
|
184
|
-
|
185
|
-
private
|
186
|
-
|
187
|
-
sig { returns(LocalTags) }
|
188
|
-
def tags
|
189
|
-
@tags ||= LocalTags.new(cli, metadata)
|
190
|
-
end
|
191
|
-
|
192
|
-
sig { returns(Docker::LayerStack) }
|
193
|
-
def layer_stack
|
194
|
-
@layer_stack ||= Docker::LayerStack.new.tap do |stack|
|
195
|
-
stack.use(:setup_phase, setup_phase)
|
196
|
-
stack.use(:package_phase, package_phase)
|
197
|
-
stack.use(:webserver_phase, webserver_phase)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
data/lib/kuby/docker/metadata.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
|
-
require 'uri'
|
4
|
-
|
5
|
-
module Kuby
|
6
|
-
module Docker
|
7
|
-
class Metadata
|
8
|
-
extend T::Sig
|
9
|
-
|
10
|
-
DEFAULT_DISTRO = :debian
|
11
|
-
LATEST_TAG = T.let('latest'.freeze, String)
|
12
|
-
|
13
|
-
sig { params(image_url: String).void }
|
14
|
-
attr_writer :image_url
|
15
|
-
|
16
|
-
sig { returns(Environment) }
|
17
|
-
attr_reader :environment
|
18
|
-
|
19
|
-
sig { params(environment: Environment).void }
|
20
|
-
def initialize(environment)
|
21
|
-
@environment = environment
|
22
|
-
@tags = T.let([], T::Array[String])
|
23
|
-
|
24
|
-
@image_url = T.let(@image_url, T.nilable(String))
|
25
|
-
@image_host = T.let(@image_host, T.nilable(String))
|
26
|
-
@image_hostname = T.let(@image_hostname, T.nilable(String))
|
27
|
-
@image_repo = T.let(@image_repo, T.nilable(String))
|
28
|
-
@distro = T.let(@distro, T.nilable(Symbol))
|
29
|
-
@full_image_uri = T.let(@full_image_uri, T.nilable(DockerURI))
|
30
|
-
@default_image_url = T.let(@default_image_url, T.nilable(String))
|
31
|
-
@default_tags = T.let(@default_tags, T.nilable(T::Array[String]))
|
32
|
-
end
|
33
|
-
|
34
|
-
sig { returns(String) }
|
35
|
-
def image_url
|
36
|
-
@image_url || default_image_url
|
37
|
-
end
|
38
|
-
|
39
|
-
sig { returns(String) }
|
40
|
-
def image_host
|
41
|
-
@image_host ||= "#{full_image_uri.host}:#{full_image_uri.port}"
|
42
|
-
end
|
43
|
-
|
44
|
-
sig { returns(String) }
|
45
|
-
def image_hostname
|
46
|
-
@image_hostname ||= full_image_uri.host
|
47
|
-
end
|
48
|
-
|
49
|
-
sig { returns(String) }
|
50
|
-
def image_repo
|
51
|
-
@image_repo ||= full_image_uri.path
|
52
|
-
end
|
53
|
-
|
54
|
-
sig { returns(T::Array[String]) }
|
55
|
-
def tags
|
56
|
-
@tags.empty? ? default_tags : @tags
|
57
|
-
end
|
58
|
-
|
59
|
-
sig { returns(Symbol) }
|
60
|
-
def distro
|
61
|
-
@distro || DEFAULT_DISTRO
|
62
|
-
end
|
63
|
-
|
64
|
-
sig { params(distro_name: Symbol).void }
|
65
|
-
def distro=(distro_name)
|
66
|
-
@distro = distro_name
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
sig { returns(DockerURI) }
|
72
|
-
def full_image_uri
|
73
|
-
@full_image_uri ||= DockerURI.parse(image_url)
|
74
|
-
end
|
75
|
-
|
76
|
-
sig { returns(String) }
|
77
|
-
def default_image_url
|
78
|
-
# assuming dockerhub by not specifying full url
|
79
|
-
@default_image_url ||= environment.app_name.downcase
|
80
|
-
end
|
81
|
-
|
82
|
-
sig { returns(T::Array[String]) }
|
83
|
-
def default_tags
|
84
|
-
@default_tags ||= [
|
85
|
-
TimestampTag.new(Time.now).to_s, LATEST_TAG
|
86
|
-
]
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
data/lib/kuby/docker/tags.rb
DELETED
@@ -1,92 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
|
3
|
-
module Kuby
|
4
|
-
module Docker
|
5
|
-
class Tags
|
6
|
-
extend T::Sig
|
7
|
-
|
8
|
-
LATEST = Metadata::LATEST_TAG
|
9
|
-
|
10
|
-
sig { returns(CLI) }
|
11
|
-
attr_reader :cli
|
12
|
-
|
13
|
-
sig { returns(::Docker::Remote::Client) }
|
14
|
-
attr_reader :remote_client
|
15
|
-
|
16
|
-
sig { returns Metadata }
|
17
|
-
attr_reader :metadata
|
18
|
-
|
19
|
-
sig {
|
20
|
-
params(
|
21
|
-
cli: CLI,
|
22
|
-
remote_client: ::Docker::Remote::Client,
|
23
|
-
metadata: Metadata
|
24
|
-
)
|
25
|
-
.void
|
26
|
-
}
|
27
|
-
def initialize(cli, remote_client, metadata)
|
28
|
-
@cli = cli
|
29
|
-
@remote_client = remote_client
|
30
|
-
@metadata = metadata
|
31
|
-
|
32
|
-
@local = T.let(@local, T.nilable(LocalTags))
|
33
|
-
@remote = T.let(@remote, T.nilable(RemoteTags))
|
34
|
-
@latest_timestamp_tag = T.let(@latest_timestamp_tag, T.nilable(TimestampTag))
|
35
|
-
end
|
36
|
-
|
37
|
-
sig { returns(T::Array[String]) }
|
38
|
-
def tags
|
39
|
-
(local.tags + remote.tags).uniq
|
40
|
-
end
|
41
|
-
|
42
|
-
sig { returns(T::Array[String]) }
|
43
|
-
def latest_tags
|
44
|
-
(local.latest_tags + remote.latest_tags).uniq
|
45
|
-
end
|
46
|
-
|
47
|
-
sig {
|
48
|
-
params(current_tag: String).returns(T.nilable(TimestampTag))
|
49
|
-
}
|
50
|
-
def previous_timestamp_tag(current_tag)
|
51
|
-
current_tag = TimestampTag.try_parse(current_tag)
|
52
|
-
return nil unless current_tag
|
53
|
-
|
54
|
-
all_tags = timestamp_tags.sort
|
55
|
-
|
56
|
-
idx = all_tags.index do |tag|
|
57
|
-
tag.time == current_tag.time
|
58
|
-
end
|
59
|
-
|
60
|
-
idx ||= 0
|
61
|
-
return nil unless idx > 0
|
62
|
-
|
63
|
-
all_tags[idx - 1]
|
64
|
-
end
|
65
|
-
|
66
|
-
sig { returns(T::Array[TimestampTag]) }
|
67
|
-
def timestamp_tags
|
68
|
-
(local.timestamp_tags + remote.timestamp_tags).uniq
|
69
|
-
end
|
70
|
-
|
71
|
-
sig { returns(T.nilable(TimestampTag)) }
|
72
|
-
def latest_timestamp_tag
|
73
|
-
@latest_timestamp_tag ||= timestamp_tags.sort.last
|
74
|
-
end
|
75
|
-
|
76
|
-
sig { returns(T.self_type) }
|
77
|
-
def all
|
78
|
-
self
|
79
|
-
end
|
80
|
-
|
81
|
-
sig { returns(LocalTags) }
|
82
|
-
def local
|
83
|
-
@local ||= LocalTags.new(cli, metadata)
|
84
|
-
end
|
85
|
-
|
86
|
-
sig { returns(RemoteTags) }
|
87
|
-
def remote
|
88
|
-
@remote ||= RemoteTags.new(remote_client, metadata)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|