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
@@ -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'
|