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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c537d5778b44ceab6bbd75ae91b2c8569bdba7356c25112c172ce10533a5b073
|
4
|
+
data.tar.gz: c8fda1880975e51a5e398ccb5e42474ead68e7a179ea403ded3b15ee615dc4f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea78f96fa54b86a8917e252af444e92465b43e9017c52e25e9e643df50095a31a15462ba48f8db1f94063aff414ce9d2eb2a9e3617e2c9581823d339c810a0af
|
7
|
+
data.tar.gz: b791c2e2190e8c16a52b1039f565f9e6f04d55bc47395d0133581503beb882019139199da14efecf2d488a26e6229e7beaf649375c5067df69db6c0c7787fcf2
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,47 @@
|
|
1
|
+
## 0.18.0
|
2
|
+
* Add the ability to specify your app's root directory.
|
3
|
+
- Call `app_root <path>` inside the `docker` section of your Kuby config file.
|
4
|
+
- Necessary for use-cases like apps living inside gem repos, etc.
|
5
|
+
* Add `:app_phase` to set of Docker build phases.
|
6
|
+
- Allows easily setting environment variables.
|
7
|
+
- Sets the working directory to the app root if the app's root directory has been set via the `app_root` feature described above.
|
8
|
+
* Upgrade to Nginx ingress controller v1.1.1.
|
9
|
+
- Necessary to support Kind, the local Kubernetes cluster tool (see the kuby-kind gem).
|
10
|
+
* Run `bundle lock` before installing gem dependencies.
|
11
|
+
* Fix bug causing errors when certain container registries return a 401 if the repo doesn't exist yet.
|
12
|
+
- I'm looking at you, Azure.
|
13
|
+
* Don't fail to deploy if the app doesn't use Active Record.
|
14
|
+
* Fix git merge issue causing no output when running `kuby dockerfiles`.
|
15
|
+
* Upgrade integration tests to Kubernetes 1.23.
|
16
|
+
- This upgrade is incompatible with the version of KubeDB we're currently using.
|
17
|
+
- KubeDB has been replaced with the CockroachDB operator. Kuby will no longer support KubeDB after this release.
|
18
|
+
* Add ability to deploy resources into more than one namespace.
|
19
|
+
* Remove support for MySQL and Postgres in favor of CockroachDB.
|
20
|
+
- KubeDB has moved to an incompatible licensing model and Kuby can no longer use it.
|
21
|
+
- CockroachDB is now the only managed database offering (aside from SQLite) for the following reasons:
|
22
|
+
- CRDB is cloud-native, i.e. is designed to be run on cloud platforms like Kubernetes.
|
23
|
+
- CRDB can be easily upgraded in-place while both MySQL and Postgres demand a much more manual, error-prone upgrade process that proved very difficult to automate.
|
24
|
+
- CRDB is Postgres wire-compatible, meaning those who use Postgres (and I believe that accounts for the majority of Rails devs) will hardly be impacted by this change at all. While CRDB is not feature-by-feature compatible with Postgres, the differences are unlikely to be important to the average Rails app.
|
25
|
+
* Use SSL certificates instead of usernames and passwords for database authentication.
|
26
|
+
- This is the preferred way to communicate with instances of CockroachDB (also supported by Postgres).
|
27
|
+
- Kuby uses cert-manager to establish a custom PKI for database interactions.
|
28
|
+
- The Rails generator now entirely omits the database configuration section, making config simpler.
|
29
|
+
* Avoid failing on first deploy.
|
30
|
+
- Previous versions of Kuby did not wait for the database to spin up before attempting to start the Rails app, which resulted in what appeared to be a failed deploy. Kubernetes would eventually sort everything out, but it made for a less than ideal developer experience.
|
31
|
+
- The `create_unless_exists` rake task has been superceded by the `bootstrap` rake task, which is run in an init container whenever the app boots. It is responsible for ensuring the database server is reachable and creating any users defined in the Kuby config.
|
32
|
+
* Add the ability for plugins to define their own set of rake tasks.
|
33
|
+
- These are runnable via the CLI.
|
34
|
+
* Add the ability for plugins to define a `#remove` routine, which is meant to do the opposite of whatever `#setup` does.
|
35
|
+
- It is now also possible to run a plugin's remove routine from the CLI.
|
36
|
+
* Add the ability for plugins to depend on things like Kubernetes and Helm.
|
37
|
+
- Uses semantic versioning and compares required versions to current versions.
|
38
|
+
* Avoid using the `which` command to find executables on the current PATH.
|
39
|
+
- `which` has been deprecated in at least one Linux distro (Debian), perhaps others.
|
40
|
+
- Use `Kuby::Utils.which` instead.
|
41
|
+
* Support Rails 7.
|
42
|
+
- Don't run `yarn install` if there's no package.json.
|
43
|
+
* Automatically cache Docker builds from the latest image, should it exist.
|
44
|
+
|
1
45
|
## 0.17.1
|
2
46
|
* Allow storage class to be customized when using the built-in bare metal provider.
|
3
47
|
* Fix a bug where the assets image would be built using the previous app image instead of the current one.
|
data/Gemfile
CHANGED
@@ -5,8 +5,12 @@ gemspec
|
|
5
5
|
group :development, :test do
|
6
6
|
gem 'pry-byebug'
|
7
7
|
gem 'rake'
|
8
|
-
|
9
|
-
gem '
|
8
|
+
|
9
|
+
gem 'curdle', '~> 1.2'
|
10
|
+
gem 'parlour', github: 'camertron/parlour', branch: 'initialize_void' # '~> 7.0'
|
11
|
+
gem 'tapioca', '~> 0.7'
|
12
|
+
gem 'sorbet-runtime', '= 0.5.9897'
|
13
|
+
gem 'sorbet-static', '= 0.5.9897'
|
10
14
|
end
|
11
15
|
|
12
16
|
group :test do
|
data/Rakefile
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
require 'rspec/core/rake_task'
|
3
|
-
require '
|
3
|
+
require 'curdle'
|
4
4
|
|
5
|
-
|
5
|
+
Curdle::Tasks.install
|
6
6
|
|
7
|
-
|
7
|
+
require 'pry-byebug'
|
8
|
+
require 'sorbet-runtime'
|
9
|
+
require 'kuby'
|
8
10
|
|
9
11
|
task default: :spec
|
10
12
|
|
data/bin/tapioca
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'tapioca' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("tapioca", "tapioca")
|
data/kuby-core.gemspec
CHANGED
@@ -13,24 +13,22 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.platform = Gem::Platform::RUBY
|
14
14
|
|
15
15
|
s.add_dependency 'colorize', '~> 0.8'
|
16
|
-
s.add_dependency 'docker-remote', '~> 0.
|
17
|
-
s.add_dependency 'gli', '~> 2.
|
16
|
+
s.add_dependency 'docker-remote', '~> 0.8'
|
17
|
+
s.add_dependency 'gli', '~> 2.21'
|
18
18
|
s.add_dependency 'helm-cli', '~> 0.3'
|
19
|
-
|
20
|
-
|
21
|
-
s.add_dependency '
|
22
|
-
s.add_dependency '
|
23
|
-
s.add_dependency '
|
24
|
-
s.add_dependency 'kuby-kube-db', '>= 0.6'
|
25
|
-
s.add_dependency 'kubernetes-cli', '~> 0.3'
|
19
|
+
s.add_dependency 'krane', '~> 2.0'
|
20
|
+
s.add_dependency 'kuby-cert-manager', '~> 0.4'
|
21
|
+
s.add_dependency 'kuby-crdb', '~> 0.2'
|
22
|
+
s.add_dependency 'kube-dsl', '~> 0.7'
|
23
|
+
s.add_dependency 'kubernetes-cli', '~> 0.4'
|
26
24
|
s.add_dependency 'railties', '>= 5.1'
|
27
25
|
s.add_dependency 'rouge', '~> 3.0'
|
28
|
-
s.add_dependency '
|
26
|
+
s.add_dependency 'rake'
|
29
27
|
|
30
28
|
s.add_development_dependency 'rspec'
|
31
29
|
|
32
30
|
s.require_path = 'lib'
|
33
31
|
s.executables << 'kuby'
|
34
32
|
|
35
|
-
s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'LICENSE', 'CHANGELOG.md', 'README.md', 'Rakefile', 'kuby-core.gemspec']
|
33
|
+
s.files = Dir['{bin,lib,rbi,spec}/**/*', 'Gemfile', 'LICENSE', 'CHANGELOG.md', 'README.md', 'Rakefile', 'kuby-core.gemspec']
|
36
34
|
end
|
data/lib/kuby/basic_logger.rb
CHANGED
@@ -5,25 +5,25 @@ require 'colorized_string'
|
|
5
5
|
|
6
6
|
module Kuby
|
7
7
|
class BasicLogger < Logger
|
8
|
-
extend T::Sig
|
8
|
+
# extend T::Sig
|
9
9
|
|
10
|
-
sig {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
}
|
10
|
+
# T::Sig::WithoutRuntime.sig {
|
11
|
+
# override.params(
|
12
|
+
# logdev: T.any(String, IO, StringIO, NilClass),
|
13
|
+
# shift_age: Integer,
|
14
|
+
# shift_size: Integer,
|
15
|
+
# level: Integer,
|
16
|
+
# progname: T.nilable(String),
|
17
|
+
# formatter: T.nilable(FormatterProcType),
|
18
|
+
# datetime_format: T.nilable(String),
|
19
|
+
# shift_period_suffix: T.nilable(String)
|
20
|
+
# ).void
|
21
|
+
# }
|
22
22
|
def initialize(
|
23
23
|
logdev, shift_age = 0, shift_size = 1048576, level: DEBUG,
|
24
24
|
progname: nil, formatter: nil, datetime_format: nil,
|
25
25
|
shift_period_suffix: '%Y%m%d')
|
26
|
-
@logdev = T.let(@logdev, T.nilable(Logger::LogDevice))
|
26
|
+
# @logdev = T.let(@logdev, T.nilable(Logger::LogDevice))
|
27
27
|
|
28
28
|
super
|
29
29
|
|
@@ -32,12 +32,12 @@ module Kuby
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
sig {
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
}
|
35
|
+
# T::Sig::WithoutRuntime.sig {
|
36
|
+
# override.params(
|
37
|
+
# progname_or_msg: T.untyped,
|
38
|
+
# block: T.nilable(T.proc.returns(T.untyped))
|
39
|
+
# ).void
|
40
|
+
# }
|
41
41
|
def info(progname_or_msg = nil, &block)
|
42
42
|
if block
|
43
43
|
super(progname_or_msg) { ColorizedString[block.call].yellow }
|
@@ -46,12 +46,12 @@ module Kuby
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
sig {
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
}
|
49
|
+
# T::Sig::WithoutRuntime.sig {
|
50
|
+
# override.params(
|
51
|
+
# progname_or_msg: T.untyped,
|
52
|
+
# block: T.nilable(T.proc.returns(T.untyped))
|
53
|
+
# ).void
|
54
|
+
# }
|
55
55
|
def fatal(progname_or_msg = nil, &block)
|
56
56
|
if block
|
57
57
|
super(progname_or_msg) { ColorizedString[block.call].red }
|
@@ -61,13 +61,13 @@ module Kuby
|
|
61
61
|
end
|
62
62
|
|
63
63
|
# adhere to the "CLI" interface
|
64
|
-
sig {
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
}
|
64
|
+
# T::Sig::WithoutRuntime.sig {
|
65
|
+
# params(
|
66
|
+
# out: T.any(IO, StringIO),
|
67
|
+
# err: T.any(IO, StringIO),
|
68
|
+
# block: T.proc.void
|
69
|
+
# ).void
|
70
|
+
# }
|
71
71
|
def with_pipes(out = STDOUT, err = STDERR, &block)
|
72
72
|
previous_logdev = @logdev&.dev || STDERR
|
73
73
|
reopen(err)
|
@@ -76,7 +76,7 @@ module Kuby
|
|
76
76
|
reopen(previous_logdev)
|
77
77
|
end
|
78
78
|
|
79
|
-
sig { returns(T.nilable(Process::Status)) }
|
79
|
+
# T::Sig::WithoutRuntime.sig { returns(T.nilable(Process::Status)) }
|
80
80
|
def last_status
|
81
81
|
nil
|
82
82
|
end
|
data/lib/kuby/cli_base.rb
CHANGED
@@ -5,39 +5,39 @@ require 'thread'
|
|
5
5
|
|
6
6
|
module Kuby
|
7
7
|
class CLIBase
|
8
|
-
extend T::Sig
|
8
|
+
# extend T::Sig
|
9
9
|
|
10
|
-
BeforeCallback = T.type_alias { T.proc.params(cmd: T::Array[String]).void }
|
11
|
-
AfterCallback = T.type_alias do
|
12
|
-
|
13
|
-
end
|
10
|
+
# BeforeCallback = T.type_alias { T.proc.params(cmd: T::Array[String]).void }
|
11
|
+
# AfterCallback = T.type_alias do
|
12
|
+
# T.proc.params(cmd: T::Array[String], last_status: T.nilable(Process::Status)).void
|
13
|
+
# end
|
14
14
|
|
15
|
-
sig { returns(T.nilable(Process::Status)) }
|
15
|
+
# T::Sig::WithoutRuntime.sig { returns(T.nilable(Process::Status)) }
|
16
16
|
def last_status
|
17
17
|
Thread.current[status_key]
|
18
18
|
end
|
19
19
|
|
20
|
-
sig { params(block: BeforeCallback).void }
|
20
|
+
# T::Sig::WithoutRuntime.sig { params(block: BeforeCallback).void }
|
21
21
|
def before_execute(&block)
|
22
|
-
@before_execute = T.let(@before_execute, T.nilable(T::Array[BeforeCallback]))
|
22
|
+
# @before_execute = T.let(@before_execute, T.nilable(T::Array[BeforeCallback]))
|
23
23
|
@before_execute ||= []
|
24
24
|
@before_execute << block
|
25
25
|
end
|
26
26
|
|
27
|
-
sig { params(block: AfterCallback).void }
|
27
|
+
# T::Sig::WithoutRuntime.sig { params(block: AfterCallback).void }
|
28
28
|
def after_execute(&block)
|
29
|
-
@after_execute = T.let(@after_execute, T.nilable(T::Array[AfterCallback]))
|
29
|
+
# @after_execute = T.let(@after_execute, T.nilable(T::Array[AfterCallback]))
|
30
30
|
@after_execute ||= []
|
31
31
|
@after_execute << block
|
32
32
|
end
|
33
33
|
|
34
|
-
sig {
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
}
|
34
|
+
# T::Sig::WithoutRuntime.sig {
|
35
|
+
# params(
|
36
|
+
# out: T.any(IO, StringIO),
|
37
|
+
# err: T.any(IO, StringIO),
|
38
|
+
# block: T.proc.void
|
39
|
+
# ).void
|
40
|
+
# }
|
41
41
|
def with_pipes(out = STDOUT, err = STDERR, &block)
|
42
42
|
previous_stdout = self.stdout
|
43
43
|
previous_stderr = self.stderr
|
@@ -49,34 +49,34 @@ module Kuby
|
|
49
49
|
self.stderr = previous_stderr
|
50
50
|
end
|
51
51
|
|
52
|
-
sig { returns(T.nilable(T.any(IO, StringIO))) }
|
52
|
+
# T::Sig::WithoutRuntime.sig { returns(T.nilable(T.any(IO, StringIO))) }
|
53
53
|
def stdout
|
54
54
|
Thread.current[stdout_key] || STDOUT
|
55
55
|
end
|
56
56
|
|
57
|
-
sig { params(new_stdout: T.nilable(T.any(IO, StringIO))).void }
|
57
|
+
# T::Sig::WithoutRuntime.sig { params(new_stdout: T.nilable(T.any(IO, StringIO))).void }
|
58
58
|
def stdout=(new_stdout)
|
59
59
|
Thread.current[stdout_key] = new_stdout
|
60
60
|
end
|
61
61
|
|
62
|
-
sig { returns(T.nilable(T.any(IO, StringIO))) }
|
62
|
+
# T::Sig::WithoutRuntime.sig { returns(T.nilable(T.any(IO, StringIO))) }
|
63
63
|
def stderr
|
64
64
|
Thread.current[stderr_key] || STDERR
|
65
65
|
end
|
66
66
|
|
67
|
-
sig { params(new_stderr: T.nilable(T.any(IO, StringIO))).void }
|
67
|
+
# T::Sig::WithoutRuntime.sig { params(new_stderr: T.nilable(T.any(IO, StringIO))).void }
|
68
68
|
def stderr=(new_stderr)
|
69
69
|
Thread.current[stderr_key] = new_stderr
|
70
70
|
end
|
71
71
|
|
72
72
|
private
|
73
73
|
|
74
|
-
sig {
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
}
|
74
|
+
# T::Sig::WithoutRuntime.sig {
|
75
|
+
# params(
|
76
|
+
# cmd: T::Array[String],
|
77
|
+
# block: T.proc.params(stdin: IO).void
|
78
|
+
# ).void
|
79
|
+
# }
|
80
80
|
def open3_w(cmd, &block)
|
81
81
|
run_before_callbacks(cmd)
|
82
82
|
cmd_s = cmd.join(' ')
|
@@ -99,20 +99,20 @@ module Kuby
|
|
99
99
|
yield(p_stdin)
|
100
100
|
|
101
101
|
p_stdin.close
|
102
|
-
self.last_status =
|
102
|
+
self.last_status = wait_thread.value
|
103
103
|
run_after_callbacks(cmd)
|
104
104
|
wait_thread.join
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
sig { params(cmd: T::Array[String]).void }
|
108
|
+
# T::Sig::WithoutRuntime.sig { params(cmd: T::Array[String]).void }
|
109
109
|
def execc(cmd)
|
110
110
|
run_before_callbacks(cmd)
|
111
111
|
cmd_s = cmd.join(' ')
|
112
112
|
exec(cmd_s)
|
113
113
|
end
|
114
114
|
|
115
|
-
sig { params(cmd: T::Array[String]).void }
|
115
|
+
# T::Sig::WithoutRuntime.sig { params(cmd: T::Array[String]).void }
|
116
116
|
def systemm(cmd)
|
117
117
|
if stdout == STDOUT && stderr == STDERR
|
118
118
|
systemm_default(cmd)
|
@@ -121,7 +121,7 @@ module Kuby
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
-
sig { params(cmd: T::Array[String]).void }
|
124
|
+
# T::Sig::WithoutRuntime.sig { params(cmd: T::Array[String]).void }
|
125
125
|
def systemm_default(cmd)
|
126
126
|
run_before_callbacks(cmd)
|
127
127
|
cmd_s = cmd.join(' ')
|
@@ -131,7 +131,7 @@ module Kuby
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
sig { params(cmd: T::Array[String]).void }
|
134
|
+
# T::Sig::WithoutRuntime.sig { params(cmd: T::Array[String]).void }
|
135
135
|
def systemm_open3(cmd)
|
136
136
|
run_before_callbacks(cmd)
|
137
137
|
cmd_s = cmd.join(' ')
|
@@ -152,14 +152,14 @@ module Kuby
|
|
152
152
|
end
|
153
153
|
|
154
154
|
p_stdin.close
|
155
|
-
self.last_status =
|
155
|
+
self.last_status = wait_thread.value
|
156
156
|
run_after_callbacks(cmd)
|
157
157
|
wait_thread.join
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
161
|
|
162
|
-
sig { params(cmd: T::Array[String]).returns(String) }
|
162
|
+
# T::Sig::WithoutRuntime.sig { params(cmd: T::Array[String]).returns(String) }
|
163
163
|
def backticks(cmd)
|
164
164
|
if stdout == STDOUT && stderr == STDERR
|
165
165
|
backticks_default(cmd)
|
@@ -168,7 +168,7 @@ module Kuby
|
|
168
168
|
end
|
169
169
|
end
|
170
170
|
|
171
|
-
sig { params(cmd: T::Array[String]).returns(String) }
|
171
|
+
# T::Sig::WithoutRuntime.sig { params(cmd: T::Array[String]).returns(String) }
|
172
172
|
def backticks_default(cmd)
|
173
173
|
run_before_callbacks(cmd)
|
174
174
|
cmd_s = cmd.join(' ')
|
@@ -178,7 +178,7 @@ module Kuby
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
181
|
-
sig { params(cmd: T::Array[String]).returns(String) }
|
181
|
+
# T::Sig::WithoutRuntime.sig { params(cmd: T::Array[String]).returns(String) }
|
182
182
|
def backticks_open3(cmd)
|
183
183
|
run_before_callbacks(cmd)
|
184
184
|
cmd_s = cmd.join(' ')
|
@@ -200,7 +200,7 @@ module Kuby
|
|
200
200
|
end
|
201
201
|
|
202
202
|
p_stdin.close
|
203
|
-
self.last_status =
|
203
|
+
self.last_status = wait_thread.value
|
204
204
|
run_after_callbacks(cmd)
|
205
205
|
wait_thread.join
|
206
206
|
end
|
@@ -208,32 +208,32 @@ module Kuby
|
|
208
208
|
result.string
|
209
209
|
end
|
210
210
|
|
211
|
-
sig { params(cmd: T::Array[String]).void }
|
211
|
+
# T::Sig::WithoutRuntime.sig { params(cmd: T::Array[String]).void }
|
212
212
|
def run_before_callbacks(cmd)
|
213
213
|
(@before_execute || []).each { |cb| cb.call(cmd) }
|
214
214
|
end
|
215
215
|
|
216
|
-
sig { params(cmd: T::Array[String]).void }
|
216
|
+
# T::Sig::WithoutRuntime.sig { params(cmd: T::Array[String]).void }
|
217
217
|
def run_after_callbacks(cmd)
|
218
218
|
(@after_execute || []).each { |cb| cb.call(cmd, last_status) }
|
219
219
|
end
|
220
220
|
|
221
|
-
sig { params(status: Process::Status).void }
|
221
|
+
# T::Sig::WithoutRuntime.sig { params(status: Process::Status).void }
|
222
222
|
def last_status=(status)
|
223
223
|
Thread.current[status_key] = status
|
224
224
|
end
|
225
225
|
|
226
|
-
sig { returns(Symbol) }
|
226
|
+
# T::Sig::WithoutRuntime.sig { returns(Symbol) }
|
227
227
|
def status_key
|
228
228
|
raise NotImplementedError, "#{__method__} must be defined in derived classes"
|
229
229
|
end
|
230
230
|
|
231
|
-
sig { returns(Symbol) }
|
231
|
+
# T::Sig::WithoutRuntime.sig { returns(Symbol) }
|
232
232
|
def stdout_key
|
233
233
|
raise NotImplementedError, "#{__method__} must be defined in derived classes"
|
234
234
|
end
|
235
235
|
|
236
|
-
sig { returns(Symbol) }
|
236
|
+
# T::Sig::WithoutRuntime.sig { returns(Symbol) }
|
237
237
|
def stderr_key
|
238
238
|
raise NotImplementedError, "#{__method__} must be defined in derived classes"
|
239
239
|
end
|
data/lib/kuby/commands.rb
CHANGED
@@ -3,9 +3,12 @@
|
|
3
3
|
require 'kuby/version'
|
4
4
|
require 'gli'
|
5
5
|
|
6
|
+
# run the pre hook for the help command
|
7
|
+
GLI::Commands::Help.skips_pre = false
|
8
|
+
|
6
9
|
module Kuby
|
7
10
|
class Commands
|
8
|
-
extend T::Sig
|
11
|
+
# extend T::Sig
|
9
12
|
extend GLI::App
|
10
13
|
|
11
14
|
# GLI doesn't have a wildcard option, so it's impossible to tell it to
|
@@ -19,12 +22,12 @@ module Kuby
|
|
19
22
|
# avoid the usual series of cryptic alias_method calls (note that there
|
20
23
|
# is no singleton class version of #prepend in the Ruby language).
|
21
24
|
singleton_class.send(:prepend, Module.new do
|
22
|
-
extend T::Sig
|
25
|
+
# extend T::Sig
|
23
26
|
|
24
|
-
sig { params(args: T::Array[String]).void }
|
27
|
+
# T::Sig::WithoutRuntime.sig { params(args: T::Array[String]).void }
|
25
28
|
def run(args)
|
26
29
|
if idx = args.index('rails') || idx = args.index('rake')
|
27
|
-
@rails_options = T.let(@rails_options, T.nilable(T::Array[String]))
|
30
|
+
# @rails_options = T.let(@rails_options, T.nilable(T::Array[String]))
|
28
31
|
@rails_options = args[(idx + 1)..-1]
|
29
32
|
super(args[0..idx])
|
30
33
|
else
|
@@ -34,11 +37,24 @@ module Kuby
|
|
34
37
|
end
|
35
38
|
end)
|
36
39
|
|
37
|
-
sig { returns(Kuby::Tasks) }
|
40
|
+
# T::Sig::WithoutRuntime.sig { returns(Kuby::Tasks) }
|
38
41
|
def self.tasks
|
39
42
|
Kuby::Tasks.new(Kuby.environment)
|
40
43
|
end
|
41
44
|
|
45
|
+
# T::Sig::WithoutRuntime.sig {
|
46
|
+
# params(
|
47
|
+
# global_options: T::Hash[T.any(String, Symbol), T.any(String, Integer)]
|
48
|
+
# ).void
|
49
|
+
# }
|
50
|
+
def self.load_kuby_config!(global_options)
|
51
|
+
return if @kuby_config_loaded
|
52
|
+
|
53
|
+
Kuby.env = global_options[:environment] if global_options[:environment]
|
54
|
+
Kuby.load!(global_options[:config])
|
55
|
+
@kuby_config_loaded = true
|
56
|
+
end
|
57
|
+
|
42
58
|
program_desc 'Kuby command-line interface. Kuby is a convention '\
|
43
59
|
'over configuration approach for running Rails apps in Kubernetes.'
|
44
60
|
|
@@ -54,9 +70,35 @@ module Kuby
|
|
54
70
|
default_value './kuby.rb'
|
55
71
|
flag [:c, :config]
|
56
72
|
|
73
|
+
command_missing do |command_name, global_options|
|
74
|
+
load_kuby_config!(global_options)
|
75
|
+
cmd = nil
|
76
|
+
|
77
|
+
# command_name is also the name of the plugin
|
78
|
+
if plugin_klass = Kuby.plugins.find(command_name)
|
79
|
+
if plugin_klass.respond_to?(:install_commands)
|
80
|
+
desc "Run commands for the #{command_name} plugin."
|
81
|
+
cmd = command(command_name) do |c|
|
82
|
+
# the plugin now defines its own commands on c
|
83
|
+
plugin_klass.install_commands(c)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
cmd
|
89
|
+
end
|
90
|
+
|
57
91
|
pre do |global_options, options, args|
|
58
|
-
|
59
|
-
|
92
|
+
load_kuby_config!(global_options)
|
93
|
+
|
94
|
+
Kuby.plugins.each do |plugin_name, plugin_klass|
|
95
|
+
if plugin_klass.respond_to?(:commands) && !@commands[plugin_name]
|
96
|
+
desc "Run commands for the #{plugin_name} plugin."
|
97
|
+
command plugin_name.to_sym do |c|
|
98
|
+
plugin_klass.commands(c)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
60
102
|
|
61
103
|
# GLI will abort unless this block returns a truthy value
|
62
104
|
true
|
@@ -68,7 +110,7 @@ module Kuby
|
|
68
110
|
c.flag [:a, :arg], required: false, multiple: true
|
69
111
|
|
70
112
|
c.desc 'When enabled, ignores missing build arguments.'
|
71
|
-
c.switch [:'ignore-missing-args'], required: false,
|
113
|
+
c.switch [:'ignore-missing-args'], required: false, default_value: false
|
72
114
|
|
73
115
|
c.desc 'Build only the images associated with the specified identifier(s). '\
|
74
116
|
'Run `kuby images` for a list of all valid identifiers (note that '\
|
@@ -78,6 +120,9 @@ module Kuby
|
|
78
120
|
c.desc 'The directory to use as the Docker build context.'
|
79
121
|
c.flag [:c, :context], required: false
|
80
122
|
|
123
|
+
c.desc 'Pull the latest images from the registry and reuse any previously built layers.'
|
124
|
+
c.switch [:l, :'cache-from-latest'], required: false, default_value: true
|
125
|
+
|
81
126
|
c.action do |global_options, options, docker_args|
|
82
127
|
build_args = {}.tap do |build_args|
|
83
128
|
(options[:arg] || []).each do |a|
|
@@ -91,7 +136,8 @@ module Kuby
|
|
91
136
|
build_args, docker_args,
|
92
137
|
only: options[:only],
|
93
138
|
ignore_missing_args: options[:'ignore-missing-args'],
|
94
|
-
context: options[:context]
|
139
|
+
context: options[:context],
|
140
|
+
cache_from_latest: options[:'cache-from-latest']
|
95
141
|
)
|
96
142
|
end
|
97
143
|
end
|
@@ -175,7 +221,7 @@ module Kuby
|
|
175
221
|
c.desc 'Prefixes the kubectl command with the namespace associated with '\
|
176
222
|
'the current environment. For example, if the Kuby env is "production", '\
|
177
223
|
'this option will prefix the kubectl command with "-n myapp-production".'
|
178
|
-
c.switch [:N, :namespaced],
|
224
|
+
c.switch [:N, :namespaced], default_value: false
|
179
225
|
c.action do |global_options, options, args|
|
180
226
|
if options[:namespaced]
|
181
227
|
# sorry Demeter
|
@@ -187,6 +233,43 @@ module Kuby
|
|
187
233
|
end
|
188
234
|
end
|
189
235
|
|
236
|
+
desc 'Provides information about plugins.'
|
237
|
+
command :plugin do |rc|
|
238
|
+
rc.desc "Run a plugin's remove routine, i.e. uninstall it's resources from your cluster."
|
239
|
+
rc.command :remove do |c|
|
240
|
+
c.desc 'The plugin to remove. Run `kuby plugin list` for a list of valid plugin '\
|
241
|
+
'identifiers.'
|
242
|
+
c.flag [:p, :plugin], required: true
|
243
|
+
c.action do |global_options, options, args|
|
244
|
+
tasks.remove_plugin(options[:plugin])
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
rc.desc 'List plugins.'
|
249
|
+
rc.command :list do |c|
|
250
|
+
c.desc 'Show all available plugins, not just the ones in use.'
|
251
|
+
c.switch [:a, :all], default_value: false
|
252
|
+
c.action do |global_options, options, args|
|
253
|
+
tasks.list_plugins(all: options[:all])
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
rc.desc "Run one of a plugin's rake tasks. Omit task names to print all tasks."
|
258
|
+
rc.arg_name 'task_name', [:multiple, :optional]
|
259
|
+
rc.command :rake do |c|
|
260
|
+
c.action do |global_options, options, args|
|
261
|
+
# Args come through as @rails_options here because of the monkeypatch
|
262
|
+
# at the top of this file. Should revisit the patch at some point because
|
263
|
+
# I think GLI's arg concept can replace it.
|
264
|
+
if @rails_options.empty?
|
265
|
+
tasks.list_rake_tasks
|
266
|
+
else
|
267
|
+
tasks.run_rake_tasks(@rails_options)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
190
273
|
desc 'Runs commands, etc against the Kubernetes cluster.'
|
191
274
|
command :remote do |rc|
|
192
275
|
rc.desc 'Tails (i.e. continuously streams) the Rails log from your running application.'
|
@@ -206,7 +289,7 @@ module Kuby
|
|
206
289
|
rc.desc 'Runs an arbitrary command inside a running Rails pod.'
|
207
290
|
rc.command :exec do |c|
|
208
291
|
c.action do |global_options, options, args|
|
209
|
-
tasks.remote_exec([*args,
|
292
|
+
tasks.remote_exec([*args, *@rails_options])
|
210
293
|
end
|
211
294
|
end
|
212
295
|
|