kuby-core 0.11.14 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,5 +1,7 @@
|
|
1
1
|
# typed: strict
|
2
2
|
|
3
|
+
require 'docker/remote'
|
4
|
+
|
3
5
|
module Kuby
|
4
6
|
module Docker
|
5
7
|
class RemoteTags
|
@@ -8,24 +10,27 @@ module Kuby
|
|
8
10
|
sig { returns(::Docker::Remote::Client) }
|
9
11
|
attr_reader :remote_client
|
10
12
|
|
11
|
-
sig { returns(
|
12
|
-
attr_reader :
|
13
|
+
sig { returns(String) }
|
14
|
+
attr_reader :image_url
|
13
15
|
|
14
16
|
sig {
|
15
17
|
params(
|
16
18
|
remote_client: ::Docker::Remote::Client,
|
17
|
-
|
19
|
+
image_url: String
|
18
20
|
)
|
19
21
|
.void
|
20
22
|
}
|
21
|
-
def initialize(remote_client,
|
23
|
+
def initialize(remote_client, image_url)
|
22
24
|
@remote_client = remote_client
|
23
|
-
@
|
25
|
+
@image_url = image_url
|
24
26
|
end
|
25
27
|
|
26
28
|
sig { returns(T::Array[String]) }
|
27
29
|
def tags
|
28
30
|
remote_client.tags
|
31
|
+
rescue ::Docker::Remote::UnknownRepoError
|
32
|
+
# this can happen if we've never pushed to the repo before
|
33
|
+
[]
|
29
34
|
end
|
30
35
|
|
31
36
|
sig { returns(T::Array[String]) }
|
@@ -7,9 +7,6 @@ module Kuby
|
|
7
7
|
|
8
8
|
DEFAULT_WORKING_DIR = T.let('/usr/src/app'.freeze, String)
|
9
9
|
|
10
|
-
sig { returns(T.nilable(String)) }
|
11
|
-
attr_reader :base_image
|
12
|
-
|
13
10
|
sig { params(base_image: String).void }
|
14
11
|
attr_writer :base_image
|
15
12
|
|
@@ -25,35 +22,46 @@ module Kuby
|
|
25
22
|
sig { params(rails_env: String).void }
|
26
23
|
attr_writer :rails_env
|
27
24
|
|
28
|
-
sig {
|
29
|
-
|
30
|
-
|
25
|
+
sig { returns(T.nilable(Docker::Spec)) }
|
26
|
+
attr_reader :docker_spec
|
27
|
+
|
28
|
+
sig { params(environment: Environment, docker_spec: Docker::Spec).void }
|
29
|
+
def initialize(environment, docker_spec)
|
30
|
+
super(environment)
|
31
31
|
|
32
32
|
@base_image = T.let(@base_image, T.nilable(String))
|
33
33
|
@working_dir = T.let(@working_dir, T.nilable(String))
|
34
34
|
@rails_env = T.let(@rails_env, T.nilable(String))
|
35
|
+
@docker_spec = T.let(docker_spec, T.nilable(Docker::Spec))
|
35
36
|
end
|
36
37
|
|
37
38
|
sig { override.params(dockerfile: Dockerfile).void }
|
38
39
|
def apply_to(dockerfile)
|
39
|
-
dockerfile.from(base_image
|
40
|
+
dockerfile.from(base_image)
|
40
41
|
dockerfile.workdir(working_dir || DEFAULT_WORKING_DIR)
|
41
42
|
dockerfile.env("RAILS_ENV=#{rails_env || Kuby.env}")
|
42
43
|
dockerfile.env("KUBY_ENV=#{Kuby.env}")
|
43
44
|
dockerfile.arg('RAILS_MASTER_KEY')
|
44
45
|
end
|
45
46
|
|
47
|
+
sig { returns(String) }
|
48
|
+
def base_image
|
49
|
+
@base_image || default_base_image
|
50
|
+
end
|
51
|
+
|
46
52
|
private
|
47
53
|
|
48
54
|
sig { returns(String) }
|
49
55
|
def default_base_image
|
50
|
-
|
56
|
+
spec = T.must(docker_spec)
|
57
|
+
|
58
|
+
case spec.distro_name
|
51
59
|
when :debian
|
52
60
|
"ruby:#{RUBY_VERSION}"
|
53
61
|
when :alpine
|
54
62
|
"ruby:#{RUBY_VERSION}-alpine"
|
55
63
|
else
|
56
|
-
raise MissingDistroError, "distro '#{
|
64
|
+
raise MissingDistroError, "distro '#{spec.distro_name}' hasn't been registered"
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
data/lib/kuby/docker/spec.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
# typed: strict
|
2
2
|
|
3
|
-
require 'docker/remote'
|
4
|
-
|
5
3
|
module Kuby
|
6
4
|
module Docker
|
7
5
|
class Spec
|
8
6
|
extend T::Sig
|
9
7
|
|
8
|
+
DEFAULT_DISTRO = :debian
|
9
|
+
|
10
10
|
sig { returns(Environment) }
|
11
11
|
attr_reader :environment
|
12
12
|
|
13
|
+
sig { returns(T.nilable(String)) }
|
14
|
+
attr_reader :image_url_str
|
15
|
+
|
13
16
|
sig { params(environment: Environment).void }
|
14
17
|
def initialize(environment)
|
15
18
|
@environment = environment
|
@@ -22,13 +25,18 @@ module Kuby
|
|
22
25
|
@copy_phase = T.let(@copy_phase, T.nilable(CopyPhase))
|
23
26
|
@assets_phase = T.let(@assets_phase, T.nilable(AssetsPhase))
|
24
27
|
@webserver_phase = T.let(@webserver_phase, T.nilable(WebserverPhase))
|
25
|
-
@metadata = T.let(@metadata, T.nilable(Metadata))
|
26
28
|
|
29
|
+
@distro_name = T.let(@distro_name, T.nilable(Symbol))
|
27
30
|
@distro_spec = T.let(@distro_spec, T.nilable(Distro))
|
28
|
-
@cli = T.let(@cli, T.nilable(CLI))
|
29
|
-
@remote_client = T.let(@remote_client, T.nilable(::Docker::Remote::Client))
|
30
|
-
@tags = T.let(@tags, T.nilable(Tags))
|
31
31
|
@layer_stack = T.let(@layer_stack, T.nilable(Kuby::Docker::LayerStack))
|
32
|
+
|
33
|
+
@image_url_str = T.let(@image_url_str, T.nilable(String))
|
34
|
+
@image = T.let(@image, T.nilable(Docker::AppImage))
|
35
|
+
end
|
36
|
+
|
37
|
+
sig { returns(Symbol) }
|
38
|
+
def distro_name
|
39
|
+
@distro_name || DEFAULT_DISTRO
|
32
40
|
end
|
33
41
|
|
34
42
|
sig { params(image_url: String).void }
|
@@ -69,7 +77,7 @@ module Kuby
|
|
69
77
|
|
70
78
|
sig { params(distro_name: Symbol).void }
|
71
79
|
def distro(distro_name)
|
72
|
-
|
80
|
+
@distro_name = distro_name
|
73
81
|
@distro_spec = nil
|
74
82
|
end
|
75
83
|
|
@@ -85,7 +93,7 @@ module Kuby
|
|
85
93
|
|
86
94
|
sig { params(url: String).void }
|
87
95
|
def image_url(url)
|
88
|
-
|
96
|
+
@image_url_str = url
|
89
97
|
end
|
90
98
|
|
91
99
|
sig {
|
@@ -132,16 +140,22 @@ module Kuby
|
|
132
140
|
@credentials
|
133
141
|
end
|
134
142
|
|
135
|
-
sig { returns(
|
136
|
-
def
|
137
|
-
|
138
|
-
|
143
|
+
sig { returns(Docker::AppImage) }
|
144
|
+
def image
|
145
|
+
@image ||= begin
|
146
|
+
dockerfile = Dockerfile.new.tap do |df|
|
147
|
+
layer_stack.each { |layer| layer.apply_to(df) }
|
148
|
+
end
|
149
|
+
|
150
|
+
Docker::AppImage.new(
|
151
|
+
dockerfile, T.must(image_url_str), credentials
|
152
|
+
)
|
139
153
|
end
|
140
154
|
end
|
141
155
|
|
142
156
|
sig { returns(SetupPhase) }
|
143
157
|
def setup_phase
|
144
|
-
@setup_phase ||= SetupPhase.new(environment)
|
158
|
+
@setup_phase ||= SetupPhase.new(environment, self)
|
145
159
|
end
|
146
160
|
|
147
161
|
sig { returns(PackagePhase) }
|
@@ -174,62 +188,15 @@ module Kuby
|
|
174
188
|
@webserver_phase ||= WebserverPhase.new(environment)
|
175
189
|
end
|
176
190
|
|
177
|
-
sig { returns(Metadata) }
|
178
|
-
def metadata
|
179
|
-
@metadata ||= Metadata.new(environment)
|
180
|
-
end
|
181
|
-
|
182
|
-
sig { returns(String) }
|
183
|
-
def tag
|
184
|
-
t = ENV.fetch('KUBY_DOCKER_TAG') do
|
185
|
-
tags.latest_timestamp_tag
|
186
|
-
end
|
187
|
-
|
188
|
-
unless t
|
189
|
-
raise MissingTagError, 'could not find latest timestamped tag'
|
190
|
-
end
|
191
|
-
|
192
|
-
t.to_s
|
193
|
-
end
|
194
|
-
|
195
|
-
sig { params(current_tag: String).returns(String) }
|
196
|
-
def previous_tag(current_tag)
|
197
|
-
t = tags.previous_timestamp_tag(current_tag)
|
198
|
-
|
199
|
-
unless t
|
200
|
-
raise MissingTagError, 'could not find previous timestamped tag'
|
201
|
-
end
|
202
|
-
|
203
|
-
t.to_s
|
204
|
-
end
|
205
|
-
|
206
|
-
sig { returns(CLI) }
|
207
|
-
def cli
|
208
|
-
@cli ||= Docker::CLI.new
|
209
|
-
end
|
210
|
-
|
211
|
-
sig { returns(::Docker::Remote::Client) }
|
212
|
-
def remote_client
|
213
|
-
@remote_client ||= ::Docker::Remote::Client.new(
|
214
|
-
metadata.image_host, metadata.image_repo,
|
215
|
-
credentials.username, credentials.password,
|
216
|
-
)
|
217
|
-
end
|
218
|
-
|
219
191
|
sig { returns(Distro) }
|
220
192
|
def distro_spec
|
221
|
-
@distro_spec ||= if distro_klass = Kuby.distros[
|
193
|
+
@distro_spec ||= if distro_klass = Kuby.distros[distro_name]
|
222
194
|
distro_klass.new(self)
|
223
195
|
else
|
224
|
-
raise MissingDistroError, "distro '#{
|
196
|
+
raise MissingDistroError, "distro '#{distro_name}' hasn't been registered"
|
225
197
|
end
|
226
198
|
end
|
227
199
|
|
228
|
-
sig { returns(Tags) }
|
229
|
-
def tags
|
230
|
-
@tags ||= Tags.new(cli, remote_client, metadata)
|
231
|
-
end
|
232
|
-
|
233
200
|
private
|
234
201
|
|
235
202
|
sig { returns(Kuby::Docker::LayerStack) }
|
@@ -9,8 +9,15 @@ module Kuby
|
|
9
9
|
|
10
10
|
FORMAT = T.let('%Y%m%d%H%M%S'.freeze, String)
|
11
11
|
|
12
|
-
sig { params(str: String).returns(T.nilable(TimestampTag)) }
|
12
|
+
sig { params(str: T.nilable(String)).returns(T.nilable(TimestampTag)) }
|
13
13
|
def self.try_parse(str)
|
14
|
+
return nil unless str
|
15
|
+
|
16
|
+
# The strptime function stops scanning after the pattern has been matched, so
|
17
|
+
# we check for all numbers here to prevent things like 20210424165405-assets
|
18
|
+
# from being treated as a timestamp tag.
|
19
|
+
return nil unless str =~ /\A\d+\z/
|
20
|
+
|
14
21
|
time = begin
|
15
22
|
Time.strptime(str, FORMAT)
|
16
23
|
rescue ArgumentError
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
require 'docker/remote'
|
4
|
+
|
5
|
+
module Kuby
|
6
|
+
module Docker
|
7
|
+
class TimestampedImage < Image
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
sig {
|
11
|
+
params(
|
12
|
+
dockerfile: T.any(Dockerfile, T.proc.returns(Dockerfile)),
|
13
|
+
image_url: String,
|
14
|
+
credentials: Credentials,
|
15
|
+
main_tag: T.nilable(String),
|
16
|
+
alias_tags: T::Array[String]
|
17
|
+
).void
|
18
|
+
}
|
19
|
+
def initialize(dockerfile, image_url, credentials, main_tag = nil, alias_tags = [])
|
20
|
+
@new_version = T.let(@new_version, T.nilable(Image))
|
21
|
+
@current_version = T.let(@current_version, T.nilable(Image))
|
22
|
+
@previous_version = T.let(@previous_version, T.nilable(Image))
|
23
|
+
|
24
|
+
@remote_client = T.let(@remote_client, T.nilable(::Docker::Remote::Client))
|
25
|
+
@local = T.let(@local, T.nilable(LocalTags))
|
26
|
+
@remote = T.let(@remote, T.nilable(RemoteTags))
|
27
|
+
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
sig { returns(Image) }
|
32
|
+
def new_version
|
33
|
+
@new_version ||= duplicate_with_tags(
|
34
|
+
TimestampTag.new(Time.now).to_s, [Kuby::Docker::LATEST_TAG]
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
sig { returns(Image) }
|
39
|
+
def current_version
|
40
|
+
@current_version ||= duplicate_with_tags(
|
41
|
+
latest_timestamp_tag.to_s, [Kuby::Docker::LATEST_TAG]
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
sig { params(current_tag: T.nilable(String)).returns(Image) }
|
46
|
+
def previous_version(current_tag = nil)
|
47
|
+
@previous_version ||= duplicate_with_tags(
|
48
|
+
previous_timestamp_tag(current_tag).to_s, []
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
sig { params(current_tag: T.nilable(String)).returns(TimestampTag) }
|
53
|
+
def previous_timestamp_tag(current_tag = nil)
|
54
|
+
current_tag = TimestampTag.try_parse(current_tag || latest_timestamp_tag.to_s)
|
55
|
+
raise MissingTagError, 'could not find current timestamp tag' unless current_tag
|
56
|
+
|
57
|
+
all_tags = timestamp_tags.sort
|
58
|
+
|
59
|
+
idx = all_tags.index do |tag|
|
60
|
+
tag.time == current_tag.time
|
61
|
+
end
|
62
|
+
|
63
|
+
idx ||= 0
|
64
|
+
raise MissingTagError, 'could not find previous timestamp tag' unless idx > 0
|
65
|
+
|
66
|
+
T.must(all_tags[idx - 1])
|
67
|
+
end
|
68
|
+
|
69
|
+
sig { returns(TimestampTag) }
|
70
|
+
def latest_timestamp_tag
|
71
|
+
tag = timestamp_tags.sort.last
|
72
|
+
raise MissingTagError, 'could not find latest timestamp tag' unless tag
|
73
|
+
tag
|
74
|
+
end
|
75
|
+
|
76
|
+
sig { params(build_args: T::Hash[String, String]).void }
|
77
|
+
def build(build_args = {})
|
78
|
+
docker_cli.build(new_version, build_args: build_args)
|
79
|
+
@current_version = new_version
|
80
|
+
@new_version = nil
|
81
|
+
end
|
82
|
+
|
83
|
+
sig { params(tag: String).void }
|
84
|
+
def push(tag)
|
85
|
+
docker_cli.push(image_url, tag)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
sig { returns(::Docker::Remote::Client) }
|
91
|
+
def remote_client
|
92
|
+
@remote_client ||= ::Docker::Remote::Client.new(
|
93
|
+
image_host, image_repo, credentials.username, credentials.password,
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
sig { returns(T::Array[TimestampTag]) }
|
98
|
+
def timestamp_tags
|
99
|
+
(local.timestamp_tags + remote.timestamp_tags).uniq
|
100
|
+
end
|
101
|
+
|
102
|
+
sig { returns(LocalTags) }
|
103
|
+
def local
|
104
|
+
@local ||= LocalTags.new(docker_cli, image_url)
|
105
|
+
end
|
106
|
+
|
107
|
+
sig { returns(RemoteTags) }
|
108
|
+
def remote
|
109
|
+
@remote ||= RemoteTags.new(remote_client, image_url)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -7,8 +7,8 @@ module Kuby
|
|
7
7
|
|
8
8
|
sig { params(dockerfile: Dockerfile).void }
|
9
9
|
def apply_to(dockerfile)
|
10
|
-
|
11
|
-
dockerfile.copy('yarn.
|
10
|
+
# use character classes as a hack to only copy the files if they exist
|
11
|
+
dockerfile.copy('package.json yarn.loc[k] .npmr[c] .yarnr[c]', './')
|
12
12
|
dockerfile.run('yarn', 'install')
|
13
13
|
end
|
14
14
|
end
|
data/lib/kuby/docker.rb
CHANGED
@@ -4,30 +4,32 @@ require 'kuby/docker/errors'
|
|
4
4
|
|
5
5
|
module Kuby
|
6
6
|
module Docker
|
7
|
-
|
8
|
-
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
14
|
-
autoload :
|
15
|
-
autoload :
|
16
|
-
autoload :
|
17
|
-
autoload :
|
18
|
-
autoload :
|
19
|
-
autoload :
|
20
|
-
autoload :
|
21
|
-
autoload :
|
22
|
-
autoload :
|
23
|
-
autoload :
|
24
|
-
autoload :
|
25
|
-
autoload :
|
26
|
-
autoload :
|
27
|
-
autoload :
|
28
|
-
autoload :
|
29
|
-
autoload :
|
30
|
-
autoload :
|
31
|
-
autoload :
|
7
|
+
LATEST_TAG = T.let('latest'.freeze, String)
|
8
|
+
|
9
|
+
autoload :Alpine, 'kuby/docker/alpine'
|
10
|
+
autoload :AppImage, 'kuby/docker/app_image'
|
11
|
+
autoload :AssetsPhase, 'kuby/docker/assets_phase'
|
12
|
+
autoload :BundlerPhase, 'kuby/docker/bundler_phase'
|
13
|
+
autoload :CLI, 'kuby/docker/cli'
|
14
|
+
autoload :CopyPhase, 'kuby/docker/copy_phase'
|
15
|
+
autoload :Credentials, 'kuby/docker/credentials'
|
16
|
+
autoload :Debian, 'kuby/docker/debian'
|
17
|
+
autoload :Distro, 'kuby/docker/distro'
|
18
|
+
autoload :Dockerfile, 'kuby/docker/dockerfile'
|
19
|
+
autoload :DockerURI, 'kuby/docker/docker_uri'
|
20
|
+
autoload :Image, 'kuby/docker/image'
|
21
|
+
autoload :InlineLayer, 'kuby/docker/inline_layer'
|
22
|
+
autoload :Layer, 'kuby/docker/layer'
|
23
|
+
autoload :LayerStack, 'kuby/docker/layer_stack'
|
24
|
+
autoload :LocalTags, 'kuby/docker/local_tags'
|
25
|
+
autoload :Packages, 'kuby/docker/packages'
|
26
|
+
autoload :PackagePhase, 'kuby/docker/package_phase'
|
27
|
+
autoload :RemoteTags, 'kuby/docker/remote_tags'
|
28
|
+
autoload :SetupPhase, 'kuby/docker/setup_phase'
|
29
|
+
autoload :Spec, 'kuby/docker/spec'
|
30
|
+
autoload :TimestampedImage, 'kuby/docker/timestamped_image'
|
31
|
+
autoload :TimestampTag, 'kuby/docker/timestamp_tag'
|
32
|
+
autoload :WebserverPhase, 'kuby/docker/webserver_phase'
|
33
|
+
autoload :YarnPhase, 'kuby/docker/yarn_phase'
|
32
34
|
end
|
33
35
|
end
|
data/lib/kuby/environment.rb
CHANGED
@@ -12,12 +12,7 @@ module Kuby
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def docker(&block)
|
15
|
-
@docker ||=
|
16
|
-
Docker::DevSpec.new(self)
|
17
|
-
else
|
18
|
-
Docker::Spec.new(self)
|
19
|
-
end
|
20
|
-
|
15
|
+
@docker ||= Docker::Spec.new(self)
|
21
16
|
@docker.instance_eval(&block) if block
|
22
17
|
@docker
|
23
18
|
end
|
@@ -31,9 +26,5 @@ module Kuby
|
|
31
26
|
def app_name
|
32
27
|
definition.app_name
|
33
28
|
end
|
34
|
-
|
35
|
-
def development?
|
36
|
-
name == 'development'
|
37
|
-
end
|
38
29
|
end
|
39
30
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
require 'kube-dsl'
|
4
|
+
|
5
|
+
module Kuby
|
6
|
+
module Kubernetes
|
7
|
+
class BareMetalProvider < Provider
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
STORAGE_CLASS_NAME = T.let('hostpath'.freeze, String)
|
11
|
+
|
12
|
+
class Config
|
13
|
+
extend ::KubeDSL::ValueFields
|
14
|
+
|
15
|
+
value_fields :kubeconfig
|
16
|
+
end
|
17
|
+
|
18
|
+
sig { returns(Config) }
|
19
|
+
attr_reader :config
|
20
|
+
|
21
|
+
sig { params(environment: Environment).void }
|
22
|
+
def initialize(environment)
|
23
|
+
@config = T.let(Config.new, Config)
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
sig { params(block: T.proc.void).void }
|
28
|
+
def configure(&block)
|
29
|
+
config.instance_eval(&block) if block
|
30
|
+
end
|
31
|
+
|
32
|
+
sig { returns(String) }
|
33
|
+
def kubeconfig_path
|
34
|
+
config.kubeconfig
|
35
|
+
end
|
36
|
+
|
37
|
+
sig { returns(String) }
|
38
|
+
def storage_class_name
|
39
|
+
STORAGE_CLASS_NAME
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
sig { void }
|
45
|
+
def after_initialize
|
46
|
+
configure do
|
47
|
+
# default kubeconfig path
|
48
|
+
kubeconfig File.join(ENV['HOME'], '.kube', 'config')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
4
|
require 'securerandom'
|
5
|
+
require 'tmpdir'
|
5
6
|
require 'yaml'
|
6
7
|
|
7
8
|
module Kuby
|
@@ -101,7 +102,7 @@ module Kuby
|
|
101
102
|
|
102
103
|
def restart_rails_deployment_if_necessary
|
103
104
|
deployed_image = nil
|
104
|
-
current_image = "#{docker.
|
105
|
+
current_image = "#{docker.image.image_url}:#{kubernetes.tag}"
|
105
106
|
|
106
107
|
if rails_app = kubernetes.plugin(:rails_app)
|
107
108
|
deployment_name = rails_app.deployment.metadata.name
|
@@ -18,21 +18,6 @@ module Kuby
|
|
18
18
|
config.instance_eval(&block) if block
|
19
19
|
end
|
20
20
|
|
21
|
-
def after_configuration
|
22
|
-
if rails_app = spec.plugin(:rails_app)
|
23
|
-
# Remove ingress and change service type from ClusterIP to
|
24
|
-
# LoadBalancer. No need to set up ingress for Docker Desktop
|
25
|
-
# since it handles all the localhost mapping, etc if you set
|
26
|
-
# up a service LB.
|
27
|
-
rails_app.resources.delete(rails_app.ingress)
|
28
|
-
rails_app.service.spec { type 'LoadBalancer' }
|
29
|
-
end
|
30
|
-
|
31
|
-
if assets = spec.plugin(:rails_assets)
|
32
|
-
assets.service.spec { type 'LoadBalancer' }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
21
|
def kubeconfig_path
|
37
22
|
config.kubeconfig
|
38
23
|
end
|
data/lib/kuby/kubernetes/spec.rb
CHANGED
@@ -72,7 +72,7 @@ module Kuby
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def before_deploy
|
75
|
-
@tag ||= docker.
|
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.
|
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
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
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
|
-
|
163
|
-
|
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/kubernetes.rb
CHANGED
@@ -3,6 +3,7 @@ require 'kuby/kubernetes/errors'
|
|
3
3
|
|
4
4
|
module Kuby
|
5
5
|
module Kubernetes
|
6
|
+
autoload :BareMetalProvider, 'kuby/kubernetes/bare_metal_provider'
|
6
7
|
autoload :Deployer, 'kuby/kubernetes/deployer'
|
7
8
|
autoload :DeployTask, 'kuby/kubernetes/deploy_task'
|
8
9
|
autoload :DockerConfig, 'kuby/kubernetes/docker_config'
|