kuby-core 0.17.0 → 0.18.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 +44 -0
- data/Gemfile +6 -2
- data/Rakefile +5 -3
- data/bin/tapioca +29 -0
- data/kuby-core.gemspec +9 -11
- data/lib/kuby/basic_logger.rb +34 -34
- data/lib/kuby/cli_base.rb +43 -43
- data/lib/kuby/commands.rb +94 -11
- data/lib/kuby/definition.rb +12 -12
- data/lib/kuby/dependable.rb +20 -0
- data/lib/kuby/dependency.rb +14 -0
- data/lib/kuby/docker/alpine.rb +10 -10
- data/lib/kuby/docker/app_image.rb +11 -11
- data/lib/kuby/docker/app_phase.rb +36 -0
- data/lib/kuby/docker/assets_phase.rb +2 -2
- data/lib/kuby/docker/bundler_phase.rb +42 -40
- data/lib/kuby/docker/cli.rb +71 -43
- data/lib/kuby/docker/copy_phase.rb +7 -7
- data/lib/kuby/docker/credentials.rb +1 -0
- data/lib/kuby/docker/debian.rb +10 -10
- data/lib/kuby/docker/distro.rb +13 -13
- data/lib/kuby/docker/docker_uri.rb +20 -20
- data/lib/kuby/docker/dockerfile.rb +48 -39
- data/lib/kuby/docker/image.rb +66 -54
- data/lib/kuby/docker/inline_layer.rb +4 -4
- data/lib/kuby/docker/layer.rb +6 -6
- data/lib/kuby/docker/layer_stack.rb +35 -35
- data/lib/kuby/docker/local_tags.rb +16 -16
- data/lib/kuby/docker/package_list.rb +16 -16
- data/lib/kuby/docker/package_phase.rb +16 -16
- data/lib/kuby/docker/packages/managed_package.rb +13 -13
- data/lib/kuby/docker/packages/nodejs.rb +5 -5
- data/lib/kuby/docker/packages/package.rb +8 -8
- data/lib/kuby/docker/packages/simple_managed_package.rb +7 -7
- data/lib/kuby/docker/packages/yarn.rb +6 -6
- data/lib/kuby/docker/remote_tags.rb +16 -16
- data/lib/kuby/docker/setup_phase.rb +18 -20
- data/lib/kuby/docker/spec.rb +93 -72
- data/lib/kuby/docker/timestamp_tag.rb +16 -11
- data/lib/kuby/docker/timestamped_image.rb +59 -40
- data/lib/kuby/docker/webserver_phase.rb +20 -20
- data/lib/kuby/docker/yarn_phase.rb +29 -5
- data/lib/kuby/docker.rb +2 -1
- data/lib/kuby/kubernetes/bare_metal_provider.rb +9 -9
- data/lib/kuby/kubernetes/deployer.rb +22 -10
- data/lib/kuby/kubernetes/docker_config.rb +1 -0
- data/lib/kuby/kubernetes/provider.rb +1 -0
- data/lib/kuby/kubernetes/spec.rb +47 -7
- data/lib/kuby/plugin.rb +22 -1
- data/lib/kuby/plugins/nginx_ingress.rb +8 -6
- data/lib/kuby/plugins/rails_app/assets.rb +16 -4
- data/lib/kuby/plugins/rails_app/assets_image.rb +17 -8
- data/lib/kuby/plugins/rails_app/crdb/plugin.rb +473 -0
- data/lib/kuby/plugins/rails_app/crdb.rb +9 -0
- data/lib/kuby/plugins/rails_app/database.rb +12 -8
- data/lib/kuby/plugins/rails_app/generators/kuby.rb +17 -16
- data/lib/kuby/plugins/rails_app/plugin.rb +29 -18
- data/lib/kuby/plugins/rails_app/sqlite.rb +7 -3
- data/lib/kuby/plugins/rails_app/tasks.rake +25 -12
- data/lib/kuby/plugins/rails_app.rb +1 -0
- data/lib/kuby/plugins/system.rb +16 -0
- data/lib/kuby/plugins.rb +1 -0
- data/lib/kuby/railtie.rb +31 -1
- data/lib/kuby/tasks.rb +72 -5
- data/lib/kuby/trailing_hash.rb +2 -2
- data/lib/kuby/utils/sem_ver/constraint.rb +68 -0
- data/lib/kuby/utils/sem_ver/constraint_set.rb +25 -0
- data/lib/kuby/utils/sem_ver/version.rb +49 -0
- data/lib/kuby/utils/sem_ver.rb +17 -0
- data/lib/kuby/utils/which.rb +65 -0
- data/lib/kuby/utils.rb +7 -1
- data/lib/kuby/version.rb +1 -1
- data/lib/kuby.rb +37 -2
- data/rbi/kuby-core.rbi +2128 -0
- data/spec/docker/spec_spec.rb +50 -26
- data/spec/dummy/app/channels/application_cable/channel.rb +2 -1
- data/spec/dummy/app/channels/application_cable/connection.rb +2 -1
- data/spec/dummy/app/controllers/application_controller.rb +2 -1
- data/spec/dummy/app/jobs/application_job.rb +2 -1
- data/spec/dummy/app/mailers/application_mailer.rb +2 -1
- data/spec/dummy/app/models/application_record.rb +2 -1
- data/spec/dummy/config/application.rb +2 -1
- data/spec/dummy/config/initializers/wrap_parameters.rb +2 -1
- data/spec/dummy/config/routes.rb +2 -1
- data/spec/dummy/test/application_system_test_case.rb +2 -1
- data/spec/dummy/test/channels/application_cable/connection_test.rb +2 -1
- data/spec/spec_helper.rb +13 -1
- metadata +44 -39
- data/lib/kuby/plugins/rails_app/mysql.rb +0 -158
- data/lib/kuby/plugins/rails_app/postgres.rb +0 -163
data/lib/kuby/definition.rb
CHANGED
@@ -2,23 +2,23 @@
|
|
2
2
|
|
3
3
|
module Kuby
|
4
4
|
class Definition
|
5
|
-
extend T::Sig
|
5
|
+
# extend T::Sig
|
6
6
|
|
7
|
-
sig { returns(String) }
|
7
|
+
# T::Sig::WithoutRuntime.sig { returns(String) }
|
8
8
|
attr_reader :app_name
|
9
9
|
|
10
|
-
sig { params(app_name: String, block: T.nilable(T.proc.void)).void }
|
10
|
+
# T::Sig::WithoutRuntime.sig { params(app_name: String, block: T.nilable(T.proc.void)).void }
|
11
11
|
def initialize(app_name, &block)
|
12
12
|
@app_name = app_name
|
13
|
-
@environments = T.let(@environments, T.nilable(T::Hash[Symbol, Environment]))
|
13
|
+
# @environments = T.let(@environments, T.nilable(T::Hash[Symbol, Environment]))
|
14
14
|
end
|
15
15
|
|
16
|
-
sig {
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
}
|
16
|
+
# T::Sig::WithoutRuntime.sig {
|
17
|
+
# params(
|
18
|
+
# name: Symbol,
|
19
|
+
# block: T.nilable(T.proc.void)
|
20
|
+
# ).returns(Kuby::Environment)
|
21
|
+
# }
|
22
22
|
def environment(name = Kuby.env, &block)
|
23
23
|
name = name.to_s
|
24
24
|
|
@@ -28,10 +28,10 @@ module Kuby
|
|
28
28
|
environments[name].instance_eval(&block)
|
29
29
|
end
|
30
30
|
|
31
|
-
|
31
|
+
environments[name]
|
32
32
|
end
|
33
33
|
|
34
|
-
sig { returns(T::Hash[Symbol, Environment]) }
|
34
|
+
# T::Sig::WithoutRuntime.sig { returns(T::Hash[Symbol, Kuby::Environment]) }
|
35
35
|
def environments
|
36
36
|
@environments ||= {}
|
37
37
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Kuby
|
2
|
+
class Dependable
|
3
|
+
attr_reader :name, :version_or_callable
|
4
|
+
|
5
|
+
def initialize(name, version_or_callable)
|
6
|
+
@name = name
|
7
|
+
@version_or_callable = version_or_callable
|
8
|
+
end
|
9
|
+
|
10
|
+
def version
|
11
|
+
@version ||= Kuby::Utils::SemVer.parse_version(
|
12
|
+
if version_or_callable.respond_to?(:call)
|
13
|
+
version_or_callable.call
|
14
|
+
else
|
15
|
+
version_or_callable
|
16
|
+
end
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Kuby
|
2
|
+
class Dependency
|
3
|
+
attr_reader :name, :constraints
|
4
|
+
|
5
|
+
def initialize(name, *constraints)
|
6
|
+
@name = name
|
7
|
+
@constraints = Kuby::Utils::SemVer.parse_constraints(*constraints)
|
8
|
+
end
|
9
|
+
|
10
|
+
def satisfied_by?(dependable)
|
11
|
+
constraints.satisfied_by?(dependable.version)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/kuby/docker/alpine.rb
CHANGED
@@ -3,42 +3,42 @@
|
|
3
3
|
module Kuby
|
4
4
|
module Docker
|
5
5
|
class Alpine < Distro
|
6
|
-
SHELL_EXE =
|
6
|
+
SHELL_EXE = '/bin/sh'.freeze
|
7
7
|
|
8
|
-
DEFAULT_PACKAGES =
|
8
|
+
DEFAULT_PACKAGES = [
|
9
9
|
[:ca_certificates, nil],
|
10
10
|
[:nodejs, '12.14.1'],
|
11
11
|
[:yarn, '1.21.1'],
|
12
12
|
[:c_toolchain, nil],
|
13
13
|
[:tzdata, nil],
|
14
14
|
[:git, nil]
|
15
|
-
].freeze
|
15
|
+
].freeze
|
16
16
|
|
17
|
-
sig { returns(Layer) }
|
17
|
+
# T::Sig::WithoutRuntime.sig { returns(Layer) }
|
18
18
|
attr_reader :phase
|
19
19
|
|
20
|
-
sig { override.params(packages: T::Array[Distro::PackageImpl], into: Dockerfile).void }
|
20
|
+
# T::Sig::WithoutRuntime.sig { override.params(packages: T::Array[Distro::PackageImpl], into: Dockerfile).void }
|
21
21
|
def install(packages, into:)
|
22
22
|
dockerfile = into
|
23
23
|
install_managed(packages, dockerfile)
|
24
24
|
install_unmanaged(packages, dockerfile)
|
25
25
|
end
|
26
26
|
|
27
|
-
sig { override.returns(T::Array[[Symbol, T.nilable(String)]]) }
|
27
|
+
# T::Sig::WithoutRuntime.sig { override.returns(T::Array[[Symbol, T.nilable(String)]]) }
|
28
28
|
def default_packages
|
29
29
|
DEFAULT_PACKAGES
|
30
30
|
end
|
31
31
|
|
32
|
-
sig { override.returns(String) }
|
32
|
+
# T::Sig::WithoutRuntime.sig { override.returns(String) }
|
33
33
|
def shell_exe
|
34
34
|
SHELL_EXE
|
35
35
|
end
|
36
36
|
|
37
37
|
private
|
38
38
|
|
39
|
-
sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
|
39
|
+
# T::Sig::WithoutRuntime.sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
|
40
40
|
def install_managed(packages, dockerfile)
|
41
|
-
pkgs =
|
41
|
+
pkgs = packages.select(&:managed?)
|
42
42
|
|
43
43
|
unless pkgs.empty?
|
44
44
|
package_names = pkgs.map { |pkg| pkg.package_name_for(:alpine) }
|
@@ -48,7 +48,7 @@ module Kuby
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
|
51
|
+
# T::Sig::WithoutRuntime.sig { params(packages: T::Array[Distro::PackageImpl], dockerfile: Dockerfile).void }
|
52
52
|
def install_unmanaged(packages, dockerfile)
|
53
53
|
packages
|
54
54
|
.reject(&:managed?)
|
@@ -4,18 +4,18 @@
|
|
4
4
|
module Kuby
|
5
5
|
module Docker
|
6
6
|
class AppImage < ::Kuby::Docker::TimestampedImage
|
7
|
-
extend T::Sig
|
7
|
+
# extend T::Sig
|
8
8
|
|
9
|
-
sig {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
}
|
9
|
+
# T::Sig::WithoutRuntime.sig {
|
10
|
+
# params(
|
11
|
+
# dockerfile: T.any(Dockerfile, T.proc.returns(Dockerfile)),
|
12
|
+
# image_url: String,
|
13
|
+
# credentials: Credentials,
|
14
|
+
# registry_index_url: T.nilable(String),
|
15
|
+
# main_tag: T.nilable(String),
|
16
|
+
# alias_tags: T::Array[String]
|
17
|
+
# ).void
|
18
|
+
# }
|
19
19
|
def initialize(dockerfile, image_url, credentials, registry_index_url = nil, main_tag = nil, alias_tags = [])
|
20
20
|
super
|
21
21
|
@identifier = "app"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
module Kuby
|
4
|
+
module Docker
|
5
|
+
class AppPhase < Layer
|
6
|
+
# extend T::Sig
|
7
|
+
|
8
|
+
# T::Sig::WithoutRuntime.sig { params(environment: Environment).void }
|
9
|
+
def initialize(environment)
|
10
|
+
super
|
11
|
+
|
12
|
+
@env_vars = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
# T::Sig::WithoutRuntime.sig { override.params(dockerfile: Dockerfile).void }
|
16
|
+
def apply_to(dockerfile)
|
17
|
+
@env_vars.each_pair do |key, value|
|
18
|
+
dockerfile.env("#{key}='#{value}'")
|
19
|
+
end
|
20
|
+
|
21
|
+
absolute_app_root = Pathname(dockerfile.current_workdir)
|
22
|
+
.join(environment.docker.app_root_path)
|
23
|
+
.to_s
|
24
|
+
|
25
|
+
if dockerfile.current_workdir != absolute_app_root
|
26
|
+
dockerfile.workdir(absolute_app_root)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# T::Sig::WithoutRuntime.sig { params(key: String, value: String).void }
|
31
|
+
def env(key, value)
|
32
|
+
@env_vars[key] = value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -3,9 +3,9 @@
|
|
3
3
|
module Kuby
|
4
4
|
module Docker
|
5
5
|
class AssetsPhase < Layer
|
6
|
-
extend T::Sig
|
6
|
+
# extend T::Sig
|
7
7
|
|
8
|
-
sig { override.params(dockerfile: Dockerfile).void }
|
8
|
+
# T::Sig::WithoutRuntime.sig { override.params(dockerfile: Dockerfile).void }
|
9
9
|
def apply_to(dockerfile)
|
10
10
|
dockerfile.run(
|
11
11
|
'bundle', 'exec', 'rake', 'assets:precompile'
|
@@ -5,101 +5,103 @@ require 'pathname'
|
|
5
5
|
module Kuby
|
6
6
|
module Docker
|
7
7
|
class BundlerPhase < Layer
|
8
|
-
extend T::Sig
|
8
|
+
# extend T::Sig
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
DEFAULT_GEMFILE = 'Gemfile'.freeze
|
11
|
+
DEFAULT_WITHOUT =
|
12
|
+
['development', 'test', 'deploy'].freeze
|
13
|
+
|
13
14
|
|
14
|
-
sig { returns(T.nilable(String)) }
|
15
|
+
# T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
|
15
16
|
attr_reader :version
|
16
17
|
|
17
|
-
sig { params(version: String).
|
18
|
+
# T::Sig::WithoutRuntime.sig { params(version: String).returns(String) }
|
18
19
|
attr_writer :version
|
19
20
|
|
20
|
-
sig { returns(T.nilable(String)) }
|
21
|
+
# T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
|
21
22
|
attr_reader :gemfile
|
22
23
|
|
23
|
-
sig { params(gemfile: String).
|
24
|
+
# T::Sig::WithoutRuntime.sig { params(gemfile: String).returns(String) }
|
24
25
|
attr_writer :gemfile
|
25
26
|
|
26
|
-
sig { returns(T.nilable(T::Array[String])) }
|
27
|
+
# T::Sig::WithoutRuntime.sig { returns(T.nilable(T::Array[String])) }
|
27
28
|
attr_reader :without
|
28
29
|
|
29
|
-
sig { params(without: T::Array[String]).
|
30
|
+
# T::Sig::WithoutRuntime.sig { params(without: T::Array[String]).returns(T::Array[String]) }
|
30
31
|
attr_writer :without
|
31
32
|
|
32
|
-
sig { returns(T.nilable(String)) }
|
33
|
+
# T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
|
33
34
|
attr_reader :executable
|
34
35
|
|
35
|
-
sig { params(executable: String).
|
36
|
+
# T::Sig::WithoutRuntime.sig { params(executable: String).returns(String) }
|
36
37
|
attr_writer :executable
|
37
38
|
|
38
|
-
sig { params(environment: Environment).void }
|
39
|
+
# T::Sig::WithoutRuntime.sig { params(environment: Environment).void }
|
39
40
|
def initialize(environment)
|
40
41
|
super
|
41
42
|
|
42
|
-
@version = T.let(@version, T.nilable(String))
|
43
|
-
@gemfile = T.let(@gemfile, T.nilable(String))
|
44
|
-
@gemfiles =
|
45
|
-
@without = T.let(@without, T.nilable(T::Array[String]))
|
46
|
-
@executable = T.let(@executable, T.nilable(String))
|
43
|
+
# @version = T.let(@version, T.nilable(String))
|
44
|
+
# @gemfile = T.let(@gemfile, T.nilable(String))
|
45
|
+
@gemfiles = []
|
46
|
+
# @without = T.let(@without, T.nilable(T::Array[String]))
|
47
|
+
# @executable = T.let(@executable, T.nilable(String))
|
47
48
|
end
|
48
49
|
|
49
|
-
sig { override.params(dockerfile: Dockerfile).void }
|
50
|
+
# T::Sig::WithoutRuntime.sig { override.params(dockerfile: Dockerfile).void }
|
50
51
|
def apply_to(dockerfile)
|
51
|
-
gf = gemfile ||
|
52
|
+
gf = gemfile || DEFAULT_GEMFILE
|
52
53
|
lf = "#{gf}.lock"
|
53
54
|
v = version || default_version
|
54
55
|
wo = without || DEFAULT_WITHOUT
|
55
56
|
|
56
|
-
|
57
|
+
host_path = Pathname(environment.docker.app_root_path)
|
58
|
+
container_path = Pathname(dockerfile.current_workdir).join(environment.docker.app_root_path)
|
57
59
|
|
58
|
-
|
59
|
-
dockerfile.copy(gf, '.')
|
60
|
-
dockerfile.copy(lf, '.')
|
60
|
+
dockerfile.run('gem', 'install', 'bundler', '-v', v)
|
61
61
|
|
62
|
+
dockerfile.copy(host_path.join(gf), container_path.join(gf))
|
63
|
+
dockerfile.copy(host_path.join(lf), container_path.join(lf))
|
62
64
|
@gemfiles.each do |file|
|
63
|
-
dockerfile.copy(file, file)
|
65
|
+
dockerfile.copy(host_path.join(file), container_path.join(file))
|
66
|
+
extra_lf = host_path.join("#{file}.lock")
|
67
|
+
|
68
|
+
if extra_lf.exist?
|
69
|
+
dockerfile.copy(extra_lf, container_path.join("#{file}.lock"))
|
70
|
+
end
|
64
71
|
end
|
65
72
|
|
73
|
+
dockerfile.env("BUNDLE_GEMFILE=#{container_path.join(gf)}")
|
74
|
+
|
66
75
|
unless wo.empty?
|
67
76
|
dockerfile.env("BUNDLE_WITHOUT='#{wo.join(' ')}'")
|
68
77
|
end
|
69
78
|
|
79
|
+
dockerfile.run(
|
80
|
+
executable || 'bundle', 'lock', '--lockfile', container_path.join(lf)
|
81
|
+
)
|
82
|
+
|
70
83
|
dockerfile.run(
|
71
84
|
executable || 'bundle', 'install',
|
72
85
|
'--jobs', '$(nproc)',
|
73
|
-
'--retry', '3'
|
74
|
-
'--gemfile', gf
|
86
|
+
'--retry', '3'
|
75
87
|
)
|
76
88
|
|
77
89
|
# generate binstubs and add the bin directory to our path
|
78
90
|
dockerfile.run(executable || 'bundle', 'binstubs', '--all')
|
79
|
-
dockerfile.env("PATH
|
91
|
+
dockerfile.env("PATH=#{container_path.join('bin')}:$PATH")
|
80
92
|
end
|
81
93
|
|
82
|
-
sig { params(paths: String).void }
|
94
|
+
# T::Sig::WithoutRuntime.sig { params(paths: String).void }
|
83
95
|
def gemfiles(*paths)
|
84
96
|
@gemfiles.concat(paths)
|
85
97
|
end
|
86
98
|
|
87
99
|
private
|
88
100
|
|
89
|
-
sig { returns(String) }
|
101
|
+
# T::Sig::WithoutRuntime.sig { returns(String) }
|
90
102
|
def default_version
|
91
103
|
Bundler::VERSION
|
92
104
|
end
|
93
|
-
|
94
|
-
sig { returns(String) }
|
95
|
-
def default_gemfile
|
96
|
-
Bundler
|
97
|
-
.definition
|
98
|
-
.gemfiles
|
99
|
-
.first
|
100
|
-
.relative_path_from(Pathname(Dir.getwd))
|
101
|
-
.to_s
|
102
|
-
end
|
103
105
|
end
|
104
106
|
end
|
105
107
|
end
|
data/lib/kuby/docker/cli.rb
CHANGED
@@ -7,29 +7,29 @@ require 'shellwords'
|
|
7
7
|
module Kuby
|
8
8
|
module Docker
|
9
9
|
class CLI < CLIBase
|
10
|
-
extend T::Sig
|
10
|
+
# extend T::Sig
|
11
11
|
|
12
|
-
sig { returns(String) }
|
12
|
+
# T::Sig::WithoutRuntime.sig { returns(String) }
|
13
13
|
attr_reader :executable
|
14
14
|
|
15
|
-
sig { params(executable: T.nilable(String)).void }
|
15
|
+
# T::Sig::WithoutRuntime.sig { params(executable: T.nilable(String)).void }
|
16
16
|
def initialize(executable = nil)
|
17
|
-
@executable =
|
17
|
+
@executable = executable || Kuby::Utils.which('docker')
|
18
18
|
end
|
19
19
|
|
20
|
-
sig { returns(T.nilable(String)) }
|
20
|
+
# T::Sig::WithoutRuntime.sig { returns(T.nilable(String)) }
|
21
21
|
def config_file
|
22
22
|
if File.exist?(default_config_file)
|
23
23
|
default_config_file
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
sig { returns(String) }
|
27
|
+
# T::Sig::WithoutRuntime.sig { returns(String) }
|
28
28
|
def default_config_file
|
29
29
|
File.join(Dir.home, '.docker', 'config.json')
|
30
30
|
end
|
31
31
|
|
32
|
-
sig { params(url: String, username: String, password: String).void }
|
32
|
+
# T::Sig::WithoutRuntime.sig { params(url: String, username: String, password: String).void }
|
33
33
|
def login(url:, username:, password:)
|
34
34
|
cmd = [
|
35
35
|
executable, 'login', url, '--username', username, '--password-stdin'
|
@@ -39,35 +39,43 @@ module Kuby
|
|
39
39
|
stdin.puts(password)
|
40
40
|
end
|
41
41
|
|
42
|
-
unless
|
42
|
+
unless last_status.success?
|
43
43
|
raise LoginError, 'build failed: docker command exited with '\
|
44
|
-
"status code #{
|
44
|
+
"status code #{last_status.exitstatus}"
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
sig { returns(T::Array[String]) }
|
48
|
+
# T::Sig::WithoutRuntime.sig { returns(T::Array[String]) }
|
49
49
|
def auths
|
50
50
|
return [] unless config_file
|
51
51
|
|
52
|
-
config = JSON.parse(File.read(
|
52
|
+
config = JSON.parse(File.read(config_file))
|
53
53
|
config.fetch('auths', {}).keys
|
54
54
|
end
|
55
55
|
|
56
|
-
sig {
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
56
|
+
# T::Sig::WithoutRuntime.sig {
|
57
|
+
# params(
|
58
|
+
# image: Image,
|
59
|
+
# build_args: T::Hash[T.any(Symbol, String), String],
|
60
|
+
# docker_args: T::Array[String],
|
61
|
+
# context: T.nilable(String),
|
62
|
+
# cache_from: T.nilable(String)
|
63
|
+
# ).void
|
64
|
+
# }
|
65
|
+
def build(image, build_args: {}, docker_args: [], context: nil, cache_from: nil)
|
65
66
|
cmd = [
|
66
67
|
executable, 'build',
|
67
68
|
*image.tags.flat_map { |tag| ['-t', "#{image.image_url}:#{tag}"] },
|
68
69
|
*build_args.flat_map do |arg, val|
|
69
70
|
['--build-arg', Shellwords.shellescape("#{arg}=#{val}")]
|
70
|
-
end
|
71
|
+
end
|
72
|
+
]
|
73
|
+
|
74
|
+
if cache_from
|
75
|
+
cmd += ['--cache-from', cache_from]
|
76
|
+
end
|
77
|
+
|
78
|
+
cmd += [
|
71
79
|
'-f-',
|
72
80
|
*docker_args,
|
73
81
|
context || '.'
|
@@ -77,21 +85,21 @@ module Kuby
|
|
77
85
|
stdin.puts(image.dockerfile.to_s)
|
78
86
|
end
|
79
87
|
|
80
|
-
unless
|
88
|
+
unless last_status.success?
|
81
89
|
raise BuildError, 'build failed: docker command exited with '\
|
82
|
-
"status code #{
|
90
|
+
"status code #{last_status.exitstatus}"
|
83
91
|
end
|
84
92
|
end
|
85
93
|
|
86
|
-
sig {
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
}
|
94
|
+
# T::Sig::WithoutRuntime.sig {
|
95
|
+
# params(
|
96
|
+
# image_url: String,
|
97
|
+
# tag: String,
|
98
|
+
# env: T::Hash[T.any(Symbol, String), String],
|
99
|
+
# ports: T::Array[T.any(String, Integer)]
|
100
|
+
# )
|
101
|
+
# .void
|
102
|
+
# }
|
95
103
|
def run(image_url:, tag: 'latest', env: {}, ports: [])
|
96
104
|
cmd = [
|
97
105
|
executable, 'run',
|
@@ -105,13 +113,33 @@ module Kuby
|
|
105
113
|
execc(cmd)
|
106
114
|
end
|
107
115
|
|
108
|
-
sig { params(
|
109
|
-
def
|
116
|
+
# T::Sig::WithoutRuntime.sig { params(container: String, command: String, tty: T::Boolean).returns(String) }
|
117
|
+
def exec_capture(container:, command:, tty: true)
|
118
|
+
cmd = [executable, 'exec']
|
119
|
+
cmd << '-it' if tty
|
120
|
+
cmd += [container, command]
|
121
|
+
|
122
|
+
backticks(cmd)
|
123
|
+
end
|
124
|
+
|
125
|
+
# T::Sig::WithoutRuntime.sig { params(image_url: String, tag: String, format: T.nilable(String)).returns(String) }
|
126
|
+
def inspect(image_url:, tag: 'latest', format: nil)
|
127
|
+
cmd = [executable, 'inspect']
|
128
|
+
cmd += ['--format', "'#{format}'"]
|
129
|
+
cmd << "#{image_url}:#{tag}"
|
130
|
+
|
131
|
+
backticks(cmd)
|
132
|
+
end
|
133
|
+
|
134
|
+
# T::Sig::WithoutRuntime.sig { params(image_url: String, digests: T::Boolean).returns(T::Array[T::Hash[Symbol, String]]) }
|
135
|
+
def images(image_url, digests: true)
|
110
136
|
cmd = [
|
111
137
|
executable, 'images', image_url,
|
112
138
|
'--format', '"{{json . }}"'
|
113
139
|
]
|
114
140
|
|
141
|
+
cmd << '--digests' if digests
|
142
|
+
|
115
143
|
backticks(cmd).split("\n").map do |image_data|
|
116
144
|
JSON.parse(image_data).each_with_object({}) do |(k, v), ret|
|
117
145
|
ret[k.underscore.to_sym] = v
|
@@ -119,41 +147,41 @@ module Kuby
|
|
119
147
|
end
|
120
148
|
end
|
121
149
|
|
122
|
-
sig { params(image_url: String, tag: String).void }
|
150
|
+
# T::Sig::WithoutRuntime.sig { params(image_url: String, tag: String).void }
|
123
151
|
def push(image_url, tag)
|
124
152
|
systemm([
|
125
153
|
executable, 'push', "#{image_url}:#{tag}"
|
126
154
|
])
|
127
155
|
|
128
|
-
unless
|
156
|
+
unless last_status.success?
|
129
157
|
raise PushError, 'push failed: docker command exited with '\
|
130
|
-
"status code #{
|
158
|
+
"status code #{last_status.exitstatus}"
|
131
159
|
end
|
132
160
|
end
|
133
161
|
|
134
|
-
sig { params(image_url: String, tag: String).void }
|
162
|
+
# T::Sig::WithoutRuntime.sig { params(image_url: String, tag: String).void }
|
135
163
|
def pull(image_url, tag)
|
136
164
|
systemm([
|
137
165
|
executable, 'pull', "#{image_url}:#{tag}"
|
138
166
|
])
|
139
167
|
|
140
|
-
unless
|
168
|
+
unless last_status.success?
|
141
169
|
raise PullError, 'pull failed: docker command exited with '\
|
142
|
-
"status code #{
|
170
|
+
"status code #{last_status.exitstatus}"
|
143
171
|
end
|
144
172
|
end
|
145
173
|
|
146
|
-
sig { returns(Symbol) }
|
174
|
+
# T::Sig::WithoutRuntime.sig { returns(Symbol) }
|
147
175
|
def status_key
|
148
176
|
:kuby_docker_cli_last_status
|
149
177
|
end
|
150
178
|
|
151
|
-
sig { returns(Symbol) }
|
179
|
+
# T::Sig::WithoutRuntime.sig { returns(Symbol) }
|
152
180
|
def stdout_key
|
153
181
|
:kuby_docker_stdout
|
154
182
|
end
|
155
183
|
|
156
|
-
sig { returns(Symbol) }
|
184
|
+
# T::Sig::WithoutRuntime.sig { returns(Symbol) }
|
157
185
|
def stderr_key
|
158
186
|
:kuby_docker_stderr
|
159
187
|
end
|
@@ -3,25 +3,25 @@
|
|
3
3
|
module Kuby
|
4
4
|
module Docker
|
5
5
|
class CopyPhase < Layer
|
6
|
-
extend T::Sig
|
6
|
+
# extend T::Sig
|
7
7
|
|
8
|
-
DEFAULT_PATHS =
|
8
|
+
DEFAULT_PATHS = ['./'].freeze
|
9
9
|
|
10
|
-
sig { returns(T::Array[String]) }
|
10
|
+
# T::Sig::WithoutRuntime.sig { returns(T::Array[String]) }
|
11
11
|
attr_reader :paths
|
12
12
|
|
13
|
-
sig { params(environment: Environment).void }
|
13
|
+
# T::Sig::WithoutRuntime.sig { params(environment: Environment).void }
|
14
14
|
def initialize(environment)
|
15
15
|
super
|
16
|
-
@paths =
|
16
|
+
@paths = []
|
17
17
|
end
|
18
18
|
|
19
|
-
sig { params(path: String).void }
|
19
|
+
# T::Sig::WithoutRuntime.sig { params(path: String).void }
|
20
20
|
def <<(path)
|
21
21
|
paths << path
|
22
22
|
end
|
23
23
|
|
24
|
-
sig { params(dockerfile: Dockerfile).void }
|
24
|
+
# T::Sig::WithoutRuntime.sig { params(dockerfile: Dockerfile).void }
|
25
25
|
def apply_to(dockerfile)
|
26
26
|
to_copy = paths.empty? ? DEFAULT_PATHS : paths
|
27
27
|
to_copy.each { |path| dockerfile.copy(path, '.') }
|