kuby-core 0.7.2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -0
  3. data/Gemfile +1 -0
  4. data/README.md +11 -1
  5. data/bin/kuby +4 -0
  6. data/kuby-core.gemspec +9 -4
  7. data/lib/kuby.rb +58 -19
  8. data/lib/kuby/basic_logger.rb +13 -0
  9. data/lib/kuby/cli_base.rb +81 -8
  10. data/lib/kuby/commands.rb +244 -0
  11. data/lib/kuby/definition.rb +1 -11
  12. data/lib/kuby/dev_setup.rb +255 -0
  13. data/lib/kuby/docker.rb +1 -0
  14. data/lib/kuby/docker/bundler_phase.rb +3 -3
  15. data/lib/kuby/docker/cli.rb +13 -1
  16. data/lib/kuby/docker/dev_spec.rb +131 -0
  17. data/lib/kuby/docker/dockerfile.rb +16 -1
  18. data/lib/kuby/docker/layer.rb +4 -4
  19. data/lib/kuby/docker/layer_stack.rb +4 -0
  20. data/lib/kuby/docker/local_tags.rb +4 -0
  21. data/lib/kuby/docker/metadata.rb +18 -38
  22. data/lib/kuby/docker/package_phase.rb +2 -2
  23. data/lib/kuby/docker/setup_phase.rb +3 -2
  24. data/lib/kuby/docker/spec.rb +42 -16
  25. data/lib/kuby/docker/timestamp_tag.rb +6 -0
  26. data/lib/kuby/environment.rb +15 -2
  27. data/lib/kuby/kubernetes.rb +9 -11
  28. data/lib/kuby/kubernetes/deploy_task.rb +4 -1
  29. data/lib/kuby/kubernetes/deployer.rb +70 -15
  30. data/lib/kuby/kubernetes/{minikube_provider.rb → docker_desktop_provider.rb} +8 -4
  31. data/lib/kuby/kubernetes/provider.rb +12 -8
  32. data/lib/kuby/kubernetes/spec.rb +30 -29
  33. data/lib/kuby/plugin.rb +59 -0
  34. data/lib/kuby/plugin_registry.rb +27 -0
  35. data/lib/kuby/plugins.rb +6 -0
  36. data/lib/kuby/plugins/nginx_ingress.rb +71 -0
  37. data/lib/kuby/plugins/rails_app.rb +18 -0
  38. data/lib/kuby/plugins/rails_app/asset_copy_task.rb +117 -0
  39. data/lib/kuby/plugins/rails_app/assets.rb +347 -0
  40. data/lib/kuby/plugins/rails_app/database.rb +74 -0
  41. data/lib/kuby/{kubernetes/plugins → plugins}/rails_app/generators/kuby.rb +14 -16
  42. data/lib/kuby/plugins/rails_app/mysql.rb +152 -0
  43. data/lib/kuby/plugins/rails_app/plugin.rb +593 -0
  44. data/lib/kuby/plugins/rails_app/postgres.rb +143 -0
  45. data/lib/kuby/plugins/rails_app/rewrite_db_config.rb +11 -0
  46. data/lib/kuby/plugins/rails_app/sqlite.rb +32 -0
  47. data/lib/kuby/plugins/rails_app/tasks.rake +36 -0
  48. data/lib/kuby/rails_commands.rb +89 -0
  49. data/lib/kuby/railtie.rb +0 -4
  50. data/lib/kuby/tasks.rb +85 -31
  51. data/lib/kuby/version.rb +1 -1
  52. data/spec/docker/metadata_spec.rb +84 -0
  53. data/spec/docker/spec_spec.rb +266 -0
  54. data/spec/docker/timestamp_tag_spec.rb +54 -4
  55. data/spec/dummy/Gemfile +54 -0
  56. data/spec/dummy/Gemfile.lock +223 -0
  57. data/spec/dummy/README.md +24 -0
  58. data/spec/dummy/Rakefile +6 -0
  59. data/spec/dummy/app/assets/config/manifest.js +2 -0
  60. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  61. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  62. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  63. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  64. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  65. data/spec/dummy/app/javascript/channels/consumer.js +6 -0
  66. data/spec/dummy/app/javascript/channels/index.js +5 -0
  67. data/spec/dummy/app/javascript/packs/application.js +17 -0
  68. data/spec/dummy/app/jobs/application_job.rb +7 -0
  69. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  70. data/spec/dummy/app/models/application_record.rb +3 -0
  71. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  72. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  73. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  74. data/spec/dummy/bin/bundle +114 -0
  75. data/spec/dummy/bin/rails +9 -0
  76. data/spec/dummy/bin/rake +9 -0
  77. data/spec/dummy/bin/setup +36 -0
  78. data/spec/dummy/bin/spring +17 -0
  79. data/spec/dummy/bin/yarn +11 -0
  80. data/spec/dummy/config.ru +5 -0
  81. data/spec/dummy/config/application.rb +19 -0
  82. data/spec/dummy/config/boot.rb +4 -0
  83. data/spec/dummy/config/cable.yml +10 -0
  84. data/spec/dummy/config/credentials.yml.enc +1 -0
  85. data/spec/dummy/config/database.yml +25 -0
  86. data/spec/dummy/config/environment.rb +5 -0
  87. data/spec/dummy/config/environments/development.rb +62 -0
  88. data/spec/dummy/config/environments/production.rb +112 -0
  89. data/spec/dummy/config/environments/test.rb +49 -0
  90. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  91. data/spec/dummy/config/initializers/assets.rb +14 -0
  92. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  93. data/spec/dummy/config/initializers/content_security_policy.rb +30 -0
  94. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  95. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  96. data/spec/dummy/config/initializers/inflections.rb +16 -0
  97. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  98. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  99. data/spec/dummy/config/locales/en.yml +33 -0
  100. data/spec/dummy/config/master.key +1 -0
  101. data/spec/dummy/config/puma.rb +38 -0
  102. data/spec/dummy/config/routes.rb +3 -0
  103. data/spec/dummy/config/spring.rb +6 -0
  104. data/spec/dummy/config/storage.yml +34 -0
  105. data/spec/dummy/db/seeds.rb +7 -0
  106. data/spec/dummy/package.json +11 -0
  107. data/spec/dummy/public/404.html +67 -0
  108. data/spec/dummy/public/422.html +67 -0
  109. data/spec/dummy/public/500.html +66 -0
  110. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  111. data/spec/dummy/public/apple-touch-icon.png +0 -0
  112. data/spec/dummy/public/favicon.ico +0 -0
  113. data/spec/dummy/public/robots.txt +1 -0
  114. data/spec/dummy/test/application_system_test_case.rb +5 -0
  115. data/spec/dummy/test/channels/application_cable/connection_test.rb +11 -0
  116. data/spec/dummy/test/test_helper.rb +13 -0
  117. data/spec/dummy/tmp/cache/bootsnap-load-path-cache +0 -0
  118. data/spec/spec_helper.rb +77 -2
  119. data/spec/support/docker/fake_cli.rb +54 -0
  120. data/spec/support/docker/remote/fake_client.rb +16 -0
  121. data/spec/trailing_hash_spec.rb +23 -0
  122. metadata +139 -30
  123. data/lib/ext/krane/kubernetes_resource.rb +0 -16
  124. data/lib/kuby/kubernetes/plugin.rb +0 -55
  125. data/lib/kuby/kubernetes/plugins.rb +0 -8
  126. data/lib/kuby/kubernetes/plugins/nginx_ingress.rb +0 -73
  127. data/lib/kuby/kubernetes/plugins/rails_app.rb +0 -16
  128. data/lib/kuby/kubernetes/plugins/rails_app/database.rb +0 -79
  129. data/lib/kuby/kubernetes/plugins/rails_app/mysql.rb +0 -154
  130. data/lib/kuby/kubernetes/plugins/rails_app/plugin.rb +0 -379
  131. data/lib/kuby/kubernetes/plugins/rails_app/postgres.rb +0 -142
  132. data/lib/kuby/kubernetes/plugins/rails_app/rewrite_db_config.rb +0 -13
  133. data/lib/kuby/kubernetes/plugins/rails_app/sqlite.rb +0 -30
  134. data/lib/kuby/kubernetes/plugins/rails_app/tasks.rake +0 -28
  135. data/lib/kuby/tasks/kuby.rake +0 -70
@@ -1,3 +1,5 @@
1
+ require 'digest'
2
+
1
3
  module Kuby
2
4
  module Docker
3
5
  class Dockerfile
@@ -65,6 +67,10 @@ module Kuby
65
67
  def to_s; "CMD #{super}"; end
66
68
  end
67
69
 
70
+ class Arg < Command
71
+ def to_s; "ARG #{super}"; end
72
+ end
73
+
68
74
  attr_reader :commands, :cursor
69
75
 
70
76
  def initialize
@@ -84,6 +90,10 @@ module Kuby
84
90
  add Env.new(*args)
85
91
  end
86
92
 
93
+ def arg(*args)
94
+ add Arg.new(*args)
95
+ end
96
+
87
97
  def run(*args)
88
98
  add Run.new(*args)
89
99
  end
@@ -101,7 +111,12 @@ module Kuby
101
111
  end
102
112
 
103
113
  def to_s
104
- commands.map(&:to_s).join("\n")
114
+ # ensure trailing newline
115
+ "#{commands.map(&:to_s).join("\n")}\n"
116
+ end
117
+
118
+ def checksum
119
+ Digest::SHA256.hexdigest(to_s)
105
120
  end
106
121
 
107
122
  def exposed_ports
@@ -1,10 +1,10 @@
1
1
  module Kuby
2
2
  module Docker
3
3
  class Layer
4
- attr_reader :definition
4
+ attr_reader :environment
5
5
 
6
- def initialize(definition)
7
- @definition = definition
6
+ def initialize(environment)
7
+ @environment = environment
8
8
  end
9
9
 
10
10
  def apply_to(dockerfile)
@@ -15,7 +15,7 @@ module Kuby
15
15
  private
16
16
 
17
17
  def metadata
18
- definition.docker.metadata
18
+ environment.docker.metadata
19
19
  end
20
20
  end
21
21
  end
@@ -63,6 +63,10 @@ module Kuby
63
63
  stack.delete(name)
64
64
  layers.delete(name)
65
65
  end
66
+
67
+ def includes?(name)
68
+ layers.include?(name)
69
+ end
66
70
  end
67
71
  end
68
72
  end
@@ -33,6 +33,10 @@ module Kuby
33
33
  def timestamp_tags
34
34
  tags.map { |t| TimestampTag.try_parse(t) }.compact
35
35
  end
36
+
37
+ def latest_timestamp_tag
38
+ @latest_timestamp_tag ||= timestamp_tags.sort.last
39
+ end
36
40
  end
37
41
  end
38
42
  end
@@ -5,13 +5,14 @@ module Kuby
5
5
  class Metadata
6
6
  DEFAULT_DISTRO = :debian
7
7
  DEFAULT_REGISTRY_HOST = 'https://www.docker.com'.freeze
8
+ DEFAULT_REGISTRY_SCHEME = 'https'
8
9
  LATEST_TAG = 'latest'
9
10
 
10
11
  attr_accessor :image_url
11
- attr_reader :definition
12
+ attr_reader :environment
12
13
 
13
- def initialize(definition)
14
- @definition = definition
14
+ def initialize(environment)
15
+ @environment = environment
15
16
  @tags = []
16
17
  end
17
18
 
@@ -20,12 +21,7 @@ module Kuby
20
21
  end
21
22
 
22
23
  def image_host
23
- @image_host ||= if image_url.include?('/')
24
- uri = parse_url(image_url)
25
- "#{uri.scheme}://#{uri.host}"
26
- else
27
- DEFAULT_REGISTRY_HOST
28
- end
24
+ @image_host ||= "#{full_image_uri.scheme}://#{full_image_uri.host}"
29
25
  end
30
26
 
31
27
  def image_hostname
@@ -33,39 +29,13 @@ module Kuby
33
29
  end
34
30
 
35
31
  def image_repo
36
- @image_repo ||= if image_url.include?('/')
37
- parse_url(image_url).path.sub(/\A\//, '')
38
- else
39
- image_url
40
- end
32
+ @image_repo ||= full_image_uri.path.sub(/\A[\/]+/, '')
41
33
  end
42
34
 
43
35
  def tags
44
36
  @tags.empty? ? default_tags : @tags
45
37
  end
46
38
 
47
- def tag
48
- t = ENV.fetch('KUBY_DOCKER_TAG') do
49
- definition.docker.tags.latest_timestamp_tag
50
- end
51
-
52
- unless t
53
- raise MissingTagError, 'could not find latest timestamped tag'
54
- end
55
-
56
- t.to_s
57
- end
58
-
59
- def previous_tag(current_tag)
60
- t = definition.docker.tags.previous_timestamp_tag(current_tag)
61
-
62
- unless t
63
- raise MissingTagError, 'could not find previous timestamped tag'
64
- end
65
-
66
- t.to_s
67
- end
68
-
69
39
  def distro
70
40
  @distro || DEFAULT_DISTRO
71
41
  end
@@ -76,9 +46,19 @@ module Kuby
76
46
 
77
47
  private
78
48
 
49
+ def full_image_uri
50
+ @full_image_uri ||= if image_url.include?('://')
51
+ URI.parse(image_url)
52
+ elsif image_url =~ /\A[^.]+\.[^\/]+\//
53
+ URI.parse("#{DEFAULT_REGISTRY_SCHEME}://#{image_url}")
54
+ else
55
+ URI.parse("#{DEFAULT_REGISTRY_HOST}/#{image_url.sub(/\A[\/]+/, '')}")
56
+ end
57
+ end
58
+
79
59
  def default_image_url
80
60
  # assuming dockerhub by not specifying full url
81
- @default_image_url ||= definition.app_name.downcase
61
+ @default_image_url ||= environment.app_name.downcase
82
62
  end
83
63
 
84
64
  def default_tags
@@ -92,7 +72,7 @@ module Kuby
92
72
  return uri if uri.scheme
93
73
 
94
74
  # force a scheme because URI.parse won't work properly without one
95
- URI.parse("https://#{url}")
75
+ URI.parse("#{DEFAULT_REGISTRY_SCHEME}://#{url}")
96
76
  end
97
77
  end
98
78
  end
@@ -40,7 +40,7 @@ module Kuby
40
40
  private
41
41
 
42
42
  def distro_spec
43
- definition.docker.distro_spec
43
+ environment.docker.distro_spec
44
44
  end
45
45
 
46
46
  def get_package(package_name, version)
@@ -52,7 +52,7 @@ module Kuby
52
52
  end
53
53
 
54
54
  def metadata
55
- definition.docker.metadata
55
+ environment.docker.metadata
56
56
  end
57
57
  end
58
58
  end
@@ -3,13 +3,14 @@ module Kuby
3
3
  class SetupPhase < Layer
4
4
  DEFAULT_WORKING_DIR = '/usr/src/app'.freeze
5
5
 
6
- attr_accessor :base_image, :working_dir
6
+ attr_accessor :base_image, :working_dir, :rails_env
7
7
 
8
8
  def apply_to(dockerfile)
9
9
  dockerfile.from(base_image || default_base_image)
10
10
  dockerfile.workdir(working_dir || DEFAULT_WORKING_DIR)
11
- dockerfile.env("RAILS_ENV=#{Kuby.env}")
11
+ dockerfile.env("RAILS_ENV=#{rails_env || Kuby.env}")
12
12
  dockerfile.env("KUBY_ENV=#{Kuby.env}")
13
+ dockerfile.arg('RAILS_MASTER_KEY')
13
14
  end
14
15
 
15
16
  private
@@ -3,10 +3,10 @@ require 'docker/remote'
3
3
  module Kuby
4
4
  module Docker
5
5
  class Spec
6
- attr_reader :definition
6
+ attr_reader :environment
7
7
 
8
- def initialize(definition)
9
- @definition = definition
8
+ def initialize(environment)
9
+ @environment = environment
10
10
  end
11
11
 
12
12
  def base_image(image_url)
@@ -22,15 +22,15 @@ module Kuby
22
22
  end
23
23
 
24
24
  def bundler_version(version)
25
- bundler_phase.bundler_version = version
25
+ bundler_phase.version = version
26
26
  end
27
27
 
28
28
  def gemfile(path)
29
29
  bundler_phase.gemfile = path
30
30
  end
31
31
 
32
- def package(pkg)
33
- package_phase << pkg
32
+ def package(*args)
33
+ package_phase.add(*args)
34
34
  end
35
35
 
36
36
  def distro(distro_name)
@@ -62,6 +62,10 @@ module Kuby
62
62
  layer_stack.delete(*args)
63
63
  end
64
64
 
65
+ def exists?(*args)
66
+ layer_stack.includes?(*args)
67
+ end
68
+
65
69
  def credentials(&block)
66
70
  @credentials ||= Credentials.new
67
71
  @credentials.instance_eval(&block) if block
@@ -75,39 +79,57 @@ module Kuby
75
79
  end
76
80
 
77
81
  def setup_phase
78
- @setup_phase ||= SetupPhase.new(definition)
82
+ @setup_phase ||= SetupPhase.new(environment)
79
83
  end
80
84
 
81
85
  def package_phase
82
- @package_phase ||= PackagePhase.new(definition)
86
+ @package_phase ||= PackagePhase.new(environment)
83
87
  end
84
88
 
85
89
  def bundler_phase
86
- @bundler_phase ||= BundlerPhase.new(definition)
90
+ @bundler_phase ||= BundlerPhase.new(environment)
87
91
  end
88
92
 
89
93
  def yarn_phase
90
- @yarn_phase ||= YarnPhase.new(definition)
94
+ @yarn_phase ||= YarnPhase.new(environment)
91
95
  end
92
96
 
93
97
  def copy_phase
94
- @copy_phase ||= CopyPhase.new(definition)
98
+ @copy_phase ||= CopyPhase.new(environment)
95
99
  end
96
100
 
97
101
  def assets_phase
98
- @assets_phase ||= AssetsPhase.new(definition)
102
+ @assets_phase ||= AssetsPhase.new(environment)
99
103
  end
100
104
 
101
105
  def webserver_phase
102
- @webserver_phase ||= WebserverPhase.new(definition)
106
+ @webserver_phase ||= WebserverPhase.new(environment)
103
107
  end
104
108
 
105
109
  def metadata
106
- @metadata ||= Metadata.new(definition)
110
+ @metadata ||= Metadata.new(environment)
107
111
  end
108
112
 
109
- def tags
110
- @tags ||= Tags.new(cli, remote_client, metadata)
113
+ def tag
114
+ t = ENV.fetch('KUBY_DOCKER_TAG') do
115
+ tags.latest_timestamp_tag
116
+ end
117
+
118
+ unless t
119
+ raise MissingTagError, 'could not find latest timestamped tag'
120
+ end
121
+
122
+ t.to_s
123
+ end
124
+
125
+ def previous_tag(current_tag)
126
+ t = tags.previous_timestamp_tag(current_tag)
127
+
128
+ unless t
129
+ raise MissingTagError, 'could not find previous timestamped tag'
130
+ end
131
+
132
+ t.to_s
111
133
  end
112
134
 
113
135
  def cli
@@ -129,6 +151,10 @@ module Kuby
129
151
  end
130
152
  end
131
153
 
154
+ def tags
155
+ @tags ||= Tags.new(cli, remote_client, metadata)
156
+ end
157
+
132
158
  private
133
159
 
134
160
  def layer_stack
@@ -1,3 +1,5 @@
1
+ require 'time'
2
+
1
3
  module Kuby
2
4
  module Docker
3
5
  class TimestampTag
@@ -27,6 +29,10 @@ module Kuby
27
29
  time <=> other.time
28
30
  end
29
31
 
32
+ def ==(other)
33
+ time == other.time
34
+ end
35
+
30
36
  def hash
31
37
  time.hash
32
38
  end
@@ -8,15 +8,28 @@ module Kuby
8
8
  end
9
9
 
10
10
  def docker(&block)
11
- @docker ||= Docker::Spec.new(definition)
11
+ @docker ||= if development?
12
+ Docker::DevSpec.new(self)
13
+ else
14
+ Docker::Spec.new(self)
15
+ end
16
+
12
17
  @docker.instance_eval(&block) if block
13
18
  @docker
14
19
  end
15
20
 
16
21
  def kubernetes(&block)
17
- @kubernetes ||= Kubernetes::Spec.new(definition)
22
+ @kubernetes ||= Kubernetes::Spec.new(self)
18
23
  @kubernetes.instance_eval(&block) if block
19
24
  @kubernetes
20
25
  end
26
+
27
+ def app_name
28
+ definition.app_name
29
+ end
30
+
31
+ def development?
32
+ name == 'development'
33
+ end
21
34
  end
22
35
  end
@@ -2,16 +2,14 @@ require 'kuby/kubernetes/errors'
2
2
 
3
3
  module Kuby
4
4
  module Kubernetes
5
- autoload :MinikubeProvider, 'kuby/kubernetes/minikube_provider'
6
- autoload :Deployer, 'kuby/kubernetes/deployer'
7
- autoload :DeployTask, 'kuby/kubernetes/deploy_task'
8
- autoload :DockerConfig, 'kuby/kubernetes/docker_config'
9
- autoload :Manifest, 'kuby/kubernetes/manifest'
10
- autoload :Monitors, 'kuby/kubernetes/monitors'
11
- autoload :Plugin, 'kuby/kubernetes/plugin'
12
- autoload :Plugins, 'kuby/kubernetes/plugins'
13
- autoload :Provider, 'kuby/kubernetes/provider'
14
- autoload :RegistrySecret, 'kuby/kubernetes/registry_secret'
15
- autoload :Spec, 'kuby/kubernetes/spec'
5
+ autoload :Deployer, 'kuby/kubernetes/deployer'
6
+ autoload :DeployTask, 'kuby/kubernetes/deploy_task'
7
+ autoload :DockerConfig, 'kuby/kubernetes/docker_config'
8
+ autoload :DockerDesktopProvider, 'kuby/kubernetes/docker_desktop_provider'
9
+ autoload :Manifest, 'kuby/kubernetes/manifest'
10
+ autoload :Plugins, 'kuby/kubernetes/plugins'
11
+ autoload :Provider, 'kuby/kubernetes/provider'
12
+ autoload :RegistrySecret, 'kuby/kubernetes/registry_secret'
13
+ autoload :Spec, 'kuby/kubernetes/spec'
16
14
  end
17
15
  end
@@ -1,5 +1,4 @@
1
1
  require 'krane'
2
- require 'ext/krane/kubernetes_resource'
3
2
  require 'kubectl-rb'
4
3
 
5
4
  module Kuby
@@ -19,6 +18,10 @@ module Kuby
19
18
  end
20
19
  end
21
20
 
21
+ def logger
22
+ deploy_task.instance_variable_get(:@logger)
23
+ end
24
+
22
25
  private
23
26
 
24
27
  def with_env(new_env)
@@ -5,23 +5,43 @@ require 'yaml'
5
5
  module Kuby
6
6
  module Kubernetes
7
7
  class Deployer
8
- attr_reader :definition
8
+ attr_reader :environment
9
+ attr_accessor :logdev
9
10
 
10
- def initialize(definition)
11
- @definition = definition
11
+ def initialize(environment)
12
+ @environment = environment
12
13
  end
13
14
 
14
15
  def deploy
15
- namespaced, global = all_resources.partition do |resource|
16
- # Unfortunately we can't use respond_to here because all KubeDSL
17
- # objects use ObjectMeta, which has a namespace field. Not sure
18
- # why, since it makes no sense for a namespace to have a namespace.
19
- # Instead we just check for nil here.
20
- resource.metadata.namespace
16
+ restart_rails_deployment_if_necessary do
17
+ namespaced, global = all_resources.partition do |resource|
18
+ # Unfortunately we can't use respond_to here because all KubeDSL
19
+ # objects use ObjectMeta, which has a namespace field. Not sure
20
+ # why, since it makes no sense for a namespace to have a namespace.
21
+ # Instead we just check for nil here.
22
+ resource.metadata.namespace
23
+ end
24
+
25
+ deploy_global_resources(global)
26
+ deploy_namespaced_resources(namespaced)
21
27
  end
28
+ end
29
+
30
+ # adhere to the "CLI" interface
31
+ def with_pipes(out = STDOUT, err = STDERR)
32
+ previous_logdev = logdev
33
+ @logdev = err
34
+ yield
35
+ ensure
36
+ @logdev = previous_logdev
37
+ end
38
+
39
+ def logdev
40
+ @logdev || STDERR
41
+ end
22
42
 
23
- deploy_global_resources(global)
24
- deploy_namespaced_resources(namespaced)
43
+ def last_status
44
+ nil
25
45
  end
26
46
 
27
47
  private
@@ -42,7 +62,7 @@ module Kuby
42
62
 
43
63
  cli.apply(res)
44
64
  end
45
- rescue InvalidResourceError => e
65
+ rescue KubernetesCLI::InvalidResourceError => e
46
66
  Kuby.logger.fatal(e.message)
47
67
  Kuby.logger.fatal(e.resource.to_resource.to_yaml)
48
68
  end
@@ -67,22 +87,57 @@ module Kuby
67
87
  filenames: [tmpdir]
68
88
  )
69
89
 
90
+ task.logger.reopen(logdev)
91
+
70
92
  task.run!(verify_result: true, prune: false)
71
93
  ensure
72
94
  ENV['KUBECONFIG'] = old_kubeconfig
73
95
  FileUtils.rm_rf(tmpdir)
74
96
  end
75
97
 
98
+ def restart_rails_deployment_if_necessary
99
+ deployed_image = nil
100
+ current_image = "#{docker.metadata.image_url}:#{docker.tag}"
101
+
102
+ if rails_app = kubernetes.plugin(:rails_app)
103
+ deployment_name = rails_app.deployment.metadata.name
104
+
105
+ begin
106
+ deployment = cli.get_object(
107
+ 'deployment', namespace.metadata.name, deployment_name
108
+ )
109
+
110
+ deployed_image = deployment.dig(*%w(spec template spec containers), 0, 'image')
111
+ rescue ::KubernetesCLI::GetResourceError
112
+ end
113
+ end
114
+
115
+ yield
116
+
117
+ if deployed_image == current_image
118
+ Kuby.logger.info('Docker image URL did not change, restarting Rails deployment manually')
119
+ cli.restart_deployment(namespace.metadata.name, deployment_name)
120
+ end
121
+ end
122
+
76
123
  def provider
77
- definition.kubernetes.provider
124
+ kubernetes.provider
78
125
  end
79
126
 
80
127
  def namespace
81
- definition.kubernetes.namespace
128
+ kubernetes.namespace
82
129
  end
83
130
 
84
131
  def all_resources
85
- definition.kubernetes.resources
132
+ kubernetes.resources
133
+ end
134
+
135
+ def docker
136
+ environment.docker
137
+ end
138
+
139
+ def kubernetes
140
+ environment.kubernetes
86
141
  end
87
142
 
88
143
  def cli