kuby-core 0.11.16 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/Gemfile +1 -2
  4. data/README.md +2 -1
  5. data/kuby-core.gemspec +1 -1
  6. data/lib/kuby/commands.rb +25 -73
  7. data/lib/kuby/docker/alpine.rb +2 -1
  8. data/lib/kuby/docker/app_image.rb +34 -0
  9. data/lib/kuby/docker/bundler_phase.rb +10 -0
  10. data/lib/kuby/docker/cli.rb +7 -13
  11. data/lib/kuby/docker/docker_uri.rb +50 -9
  12. data/lib/kuby/docker/errors.rb +1 -19
  13. data/lib/kuby/docker/image.rb +142 -0
  14. data/lib/kuby/docker/layer.rb +0 -7
  15. data/lib/kuby/docker/local_tags.rb +9 -10
  16. data/lib/kuby/docker/package_phase.rb +0 -5
  17. data/lib/kuby/docker/packages.rb +1 -0
  18. data/lib/kuby/docker/remote_tags.rb +10 -5
  19. data/lib/kuby/docker/setup_phase.rb +17 -9
  20. data/lib/kuby/docker/spec.rb +38 -62
  21. data/lib/kuby/docker/timestamp_tag.rb +8 -1
  22. data/lib/kuby/docker/timestamped_image.rb +114 -0
  23. data/lib/kuby/docker.rb +27 -25
  24. data/lib/kuby/environment.rb +1 -10
  25. data/lib/kuby/kubernetes/bare_metal_provider.rb +16 -4
  26. data/lib/kuby/kubernetes/deployer.rb +1 -1
  27. data/lib/kuby/kubernetes/docker_desktop_provider.rb +0 -15
  28. data/lib/kuby/kubernetes/spec.rb +21 -17
  29. data/lib/kuby/plugin.rb +2 -2
  30. data/lib/kuby/plugins/rails_app/assets.rb +62 -70
  31. data/lib/kuby/plugins/rails_app/assets_image.rb +57 -0
  32. data/lib/kuby/plugins/rails_app/generators/kuby.rb +31 -9
  33. data/lib/kuby/plugins/rails_app/plugin.rb +53 -236
  34. data/lib/kuby/plugins/rails_app.rb +1 -0
  35. data/lib/kuby/tasks.rb +98 -69
  36. data/lib/kuby/version.rb +1 -1
  37. data/lib/kuby.rb +2 -20
  38. data/spec/docker/spec_spec.rb +21 -118
  39. data/spec/docker/timestamped_image_spec.rb +123 -0
  40. data/spec/spec_helper.rb +10 -11
  41. metadata +10 -14
  42. data/lib/kuby/dev_setup.rb +0 -346
  43. data/lib/kuby/docker/dev_spec.rb +0 -202
  44. data/lib/kuby/docker/metadata.rb +0 -90
  45. data/lib/kuby/docker/tags.rb +0 -92
  46. data/lib/kuby/rails_commands.rb +0 -84
  47. data/spec/docker/metadata_spec.rb +0 -73
  48. data/spec/dummy/Gemfile.lock +0 -223
  49. data/spec/dummy/config/master.key +0 -1
  50. data/spec/dummy/tmp/cache/bootsnap-load-path-cache +0 -0
@@ -72,7 +72,7 @@ module Kuby
72
72
  end
73
73
 
74
74
  def before_deploy
75
- @tag ||= docker.tag
75
+ @tag ||= docker.image.current_version.main_tag
76
76
 
77
77
  provider.before_deploy(resources)
78
78
  @plugins.each { |_, plg| plg.before_deploy(resources) }
@@ -81,7 +81,7 @@ module Kuby
81
81
  end
82
82
 
83
83
  def after_deploy
84
- @tag ||= docker.tag
84
+ @tag ||= docker.image.current_version.main_tag
85
85
 
86
86
  @plugins.each { |_, plg| plg.after_deploy(resources) }
87
87
  provider.after_deploy(resources)
@@ -144,24 +144,22 @@ module Kuby
144
144
  def registry_secret(&block)
145
145
  spec = self
146
146
 
147
- unless environment.development?
148
- @registry_secret ||= RegistrySecret.new do
149
- metadata do
150
- name "#{spec.selector_app}-registry-secret"
151
- namespace spec.namespace.metadata.name
152
- end
153
-
154
- docker_config do
155
- registry_host spec.docker.metadata.image_hostname
156
- username spec.docker.credentials.username
157
- password spec.docker.credentials.password
158
- email spec.docker.credentials.email
159
- end
147
+ @registry_secret ||= RegistrySecret.new do
148
+ metadata do
149
+ name "#{spec.selector_app}-registry-secret"
150
+ namespace spec.namespace.metadata.name
160
151
  end
161
152
 
162
- @registry_secret.instance_eval(&block) if block
163
- @registry_secret
153
+ docker_config do
154
+ registry_host spec.docker.image.image_hostname
155
+ username spec.docker.image.credentials.username
156
+ password spec.docker.image.credentials.password
157
+ email spec.docker.image.credentials.email
158
+ end
164
159
  end
160
+
161
+ @registry_secret.instance_eval(&block) if block
162
+ @registry_secret
165
163
  end
166
164
 
167
165
  def resources
@@ -172,6 +170,12 @@ module Kuby
172
170
  ].compact)
173
171
  end
174
172
 
173
+ def docker_images
174
+ @docker_images ||= [
175
+ docker.image, *@plugins.flat_map { |_, plugin| plugin.docker_images }
176
+ ]
177
+ end
178
+
175
179
  def selector_app
176
180
  @selector_app ||= environment.app_name.downcase
177
181
  end
data/lib/kuby/plugin.rb CHANGED
@@ -21,8 +21,8 @@ module Kuby
21
21
  []
22
22
  end
23
23
 
24
- # additional dockerfiles that should be built and pushed
25
- def dockerfiles
24
+ # additional docker images that should be built and pushed
25
+ def docker_images
26
26
  []
27
27
  end
28
28
 
@@ -47,38 +47,6 @@ module Kuby
47
47
  end
48
48
  end
49
49
 
50
- def configure_deployment(deployment, docker_image)
51
- spec = self
52
-
53
- deployment.spec.template.spec do
54
- init_container(:copy_assets) do
55
- name "#{spec.selector_app}-copy-assets"
56
- command %w(bundle exec rake kuby:rails_app:assets:copy)
57
- image docker_image
58
-
59
- volume_mount do
60
- name 'assets'
61
- mount_path RAILS_MOUNT_PATH
62
- end
63
- end
64
-
65
- container(:web) do
66
- volume_mount do
67
- name 'assets'
68
- mount_path NGINX_MOUNT_PATH
69
- end
70
- end
71
-
72
- volume do
73
- name 'assets'
74
-
75
- persistent_volume_claim do
76
- claim_name spec.volume_claim.metadata.name
77
- end
78
- end
79
- end
80
- end
81
-
82
50
  def copy_task
83
51
  @copy_task ||= AssetCopyTask.new(
84
52
  from: asset_path, to: RAILS_MOUNT_PATH
@@ -238,7 +206,7 @@ module Kuby
238
206
  container(:nginx) do
239
207
  name "#{kube_spec.selector_app}-#{kube_spec.role}"
240
208
  image_pull_policy 'IfNotPresent'
241
- image NGINX_IMAGE
209
+ image "#{kube_spec.image.image_url}:#{kube_spec.kubernetes.tag || Kuby::Docker::LATEST_TAG}-assets"
242
210
 
243
211
  port do
244
212
  container_port NGINX_PORT
@@ -252,11 +220,6 @@ module Kuby
252
220
  sub_path 'nginx.conf'
253
221
  end
254
222
 
255
- volume_mount do
256
- name 'assets'
257
- mount_path NGINX_MOUNT_PATH
258
- end
259
-
260
223
  readiness_probe do
261
224
  success_threshold 1
262
225
  failure_threshold 2
@@ -272,6 +235,10 @@ module Kuby
272
235
  end
273
236
  end
274
237
 
238
+ image_pull_secret do
239
+ name kube_spec.environment.kubernetes.registry_secret.metadata.name
240
+ end
241
+
275
242
  volume do
276
243
  name 'nginx-config'
277
244
 
@@ -280,14 +247,6 @@ module Kuby
280
247
  end
281
248
  end
282
249
 
283
- volume do
284
- name 'assets'
285
-
286
- persistent_volume_claim do
287
- claim_name kube_spec.volume_claim.metadata.name
288
- end
289
- end
290
-
291
250
  restart_policy 'Always'
292
251
  service_account_name kube_spec.service_account.metadata.name
293
252
  end
@@ -299,38 +258,19 @@ module Kuby
299
258
  @deployment
300
259
  end
301
260
 
302
- def volume_claim
303
- spec = self
304
-
305
- @volume_claim ||= KubeDSL.persistent_volume_claim do
306
- metadata do
307
- name "#{spec.selector_app}-#{spec.role}"
308
- namespace spec.namespace.metadata.name
309
- end
310
-
311
- spec do
312
- access_modes ['ReadWriteOnce']
313
- storage_class_name spec.environment.kubernetes.provider.storage_class_name
314
-
315
- resources do
316
- requests do
317
- add :storage, '10Gi'
318
- end
319
- end
320
- end
321
- end
322
- end
323
-
324
261
  def resources
325
262
  @resources ||= [
326
263
  service,
327
264
  service_account,
328
265
  nginx_config,
329
- deployment,
330
- volume_claim
266
+ deployment
331
267
  ]
332
268
  end
333
269
 
270
+ def docker_images
271
+ @docker_images ||= [docker_spec]
272
+ end
273
+
334
274
  def namespace
335
275
  environment.kubernetes.namespace
336
276
  end
@@ -342,6 +282,58 @@ module Kuby
342
282
  def role
343
283
  ROLE
344
284
  end
285
+
286
+ def docker
287
+ environment.docker
288
+ end
289
+
290
+ def kubernetes
291
+ environment.kubernetes
292
+ end
293
+
294
+ def docker_images
295
+ @docker_images ||= [image]
296
+ end
297
+
298
+ def image
299
+ @image ||= RailsApp::AssetsImage.new(docker.image, -> { dockerfile }, docker.image.registry_index_url)
300
+ end
301
+
302
+ private
303
+
304
+ def dockerfile
305
+ Docker::Dockerfile.new.tap do |df|
306
+ base_image = docker.image.current_version
307
+ cur_tag = base_image.main_tag
308
+ app_name = environment.app_name.downcase
309
+
310
+ tags = begin
311
+ [base_image.previous_timestamp_tag(cur_tag).to_s, cur_tag]
312
+ rescue Kuby::Docker::MissingTagError
313
+ [cur_tag, nil]
314
+ end
315
+
316
+ # this can handle more than 2 tags by virtue of using each_cons :)
317
+ tags.each_cons(2) do |prev_tag, tag|
318
+ prev_image_name = "#{app_name}-#{prev_tag}"
319
+ df.from("#{base_image.image_url}:#{prev_tag}", as: prev_image_name)
320
+ df.arg('RAILS_MASTER_KEY')
321
+ df.run("mkdir -p #{RAILS_MOUNT_PATH}")
322
+ df.run("env RAILS_MASTER_KEY=$RAILS_MASTER_KEY bundle exec rake kuby:rails_app:assets:copy")
323
+
324
+ if tag
325
+ image_name = "#{app_name}-#{tag}"
326
+ df.from("#{base_image.image_url}:#{tag}", as: image_name)
327
+ df.arg('RAILS_MASTER_KEY')
328
+ df.copy("--from=#{prev_image_name} #{RAILS_MOUNT_PATH}", RAILS_MOUNT_PATH)
329
+ df.run("env RAILS_MASTER_KEY=$RAILS_MASTER_KEY bundle exec rake kuby:rails_app:assets:copy")
330
+ end
331
+ end
332
+
333
+ df.from(NGINX_IMAGE)
334
+ df.copy("--from=#{"#{app_name}-#{tags.compact.last}"} #{RAILS_MOUNT_PATH}", NGINX_MOUNT_PATH)
335
+ end
336
+ end
345
337
  end
346
338
  end
347
339
  end
@@ -0,0 +1,57 @@
1
+ module Kuby
2
+ module Plugins
3
+ module RailsApp
4
+ class AssetsImage < ::Kuby::Docker::Image
5
+ attr_reader :base_image
6
+
7
+ def initialize(base_image, dockerfile, registry_index_url = nil, main_tag = nil, alias_tags = [])
8
+ super(dockerfile, base_image.image_url, base_image.credentials, registry_index_url, main_tag, alias_tags)
9
+ @base_image = base_image
10
+ @identifier = "assets"
11
+ end
12
+
13
+ def new_version
14
+ # Asset images track the base image, so return the current version
15
+ # here. There can be no asset image without a base image.
16
+ current_version
17
+ end
18
+
19
+ def current_version
20
+ @current_version ||= duplicate_with_annotated_tags(
21
+ base_image.current_version
22
+ )
23
+ end
24
+
25
+ def previous_version
26
+ @previous_version ||= duplicate_with_annotated_tags(
27
+ base_image.previous_version
28
+ )
29
+ end
30
+
31
+ def build(build_args = {}, docker_args = [])
32
+ docker_cli.build(current_version, build_args: build_args, docker_args: docker_args)
33
+ end
34
+
35
+ def push(tag)
36
+ docker_cli.push(image_url, tag)
37
+ end
38
+
39
+ private
40
+
41
+ def duplicate_with_annotated_tags(image)
42
+ self.class.new(
43
+ base_image,
44
+ dockerfile,
45
+ registry_index_url,
46
+ annotate_tag(image.main_tag),
47
+ image.alias_tags.map { |at| annotate_tag(at) }
48
+ )
49
+ end
50
+
51
+ def annotate_tag(tag)
52
+ "#{tag}-assets"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -86,16 +86,38 @@ class KubyGenerator < Rails::Generators::Base
86
86
  create_file(
87
87
  '.dockerignore',
88
88
  <<~END
89
- .bundle/
90
- vendor/bundle
91
- node_modules/
92
- .node_modules/
93
- **/.git*
94
- tmp/
95
- log/
96
- engines/**/log/
97
- engines/**/tmp/
89
+ .git/
90
+
91
+ # Ignore bundler config.
92
+ .bundle
93
+
94
+ # Ignore all logfiles and tempfiles.
95
+ log/*
96
+ tmp/*
97
+ !log/.keep
98
+ !tmp/.keep
99
+
100
+ # Ignore pidfiles, but keep the directory.
101
+ tmp/pids/*
102
+ !tmp/pids/
103
+ !tmp/pids/.keep
104
+
105
+ # Ignore uploaded files in development.
106
+ storage/*
107
+ !storage/.keep
108
+
98
109
  public/assets
110
+ **/.byebug_history
111
+
112
+ # Ignore master key for decrypting credentials and more.
113
+ config/master.key
114
+
115
+ public/packs
116
+ public/packs-test
117
+ node_modules
118
+ yarn-error.log
119
+ **/yarn-debug.log*
120
+ **/.yarn-integrity
99
121
  END
100
122
  )
101
123
  end