kuby-core 0.8.1 → 0.11.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 +41 -1
- data/Gemfile +1 -0
- data/README.md +15 -3
- data/bin/kuby +4 -0
- data/kuby-core.gemspec +7 -3
- data/lib/kuby-core.rb +1 -0
- data/lib/kuby.rb +60 -18
- data/lib/kuby/basic_logger.rb +14 -0
- data/lib/kuby/cli_base.rb +126 -4
- data/lib/kuby/commands.rb +245 -0
- data/lib/kuby/definition.rb +2 -3
- data/lib/kuby/dev_setup.rb +256 -0
- data/lib/kuby/docker.rb +4 -0
- data/lib/kuby/docker/alpine.rb +16 -12
- data/lib/kuby/docker/assets_phase.rb +5 -0
- data/lib/kuby/docker/bundler_phase.rb +39 -5
- data/lib/kuby/docker/cli.rb +60 -3
- data/lib/kuby/docker/copy_phase.rb +11 -3
- data/lib/kuby/docker/credentials.rb +1 -0
- data/lib/kuby/docker/debian.rb +14 -10
- data/lib/kuby/docker/dev_spec.rb +195 -0
- data/lib/kuby/docker/distro.rb +43 -0
- data/lib/kuby/docker/dockerfile.rb +81 -18
- data/lib/kuby/docker/errors.rb +9 -0
- data/lib/kuby/docker/inline_layer.rb +7 -0
- data/lib/kuby/docker/layer.rb +11 -0
- data/lib/kuby/docker/layer_stack.rb +47 -6
- data/lib/kuby/docker/local_tags.rb +27 -2
- data/lib/kuby/docker/metadata.rb +35 -29
- data/lib/kuby/docker/package_list.rb +22 -3
- data/lib/kuby/docker/package_phase.rb +25 -5
- data/lib/kuby/docker/packages.rb +1 -0
- data/lib/kuby/docker/packages/managed_package.rb +20 -2
- data/lib/kuby/docker/packages/nodejs.rb +8 -0
- data/lib/kuby/docker/packages/package.rb +15 -1
- data/lib/kuby/docker/packages/simple_managed_package.rb +10 -1
- data/lib/kuby/docker/packages/yarn.rb +14 -0
- data/lib/kuby/docker/remote_tags.rb +21 -2
- data/lib/kuby/docker/setup_phase.rb +37 -5
- data/lib/kuby/docker/spec.rb +114 -12
- data/lib/kuby/docker/tags.rb +37 -2
- data/lib/kuby/docker/timestamp_tag.rb +14 -2
- data/lib/kuby/docker/webserver_phase.rb +40 -5
- data/lib/kuby/docker/yarn_phase.rb +5 -0
- data/lib/kuby/environment.rb +14 -1
- data/lib/kuby/kubernetes.rb +10 -9
- data/lib/kuby/kubernetes/deploy_task.rb +5 -0
- data/lib/kuby/kubernetes/deployer.rb +67 -11
- data/lib/kuby/kubernetes/docker_config.rb +1 -0
- data/lib/kuby/kubernetes/{minikube_provider.rb → docker_desktop_provider.rb} +5 -4
- data/lib/kuby/kubernetes/errors.rb +1 -0
- data/lib/kuby/kubernetes/manifest.rb +1 -0
- data/lib/kuby/kubernetes/provider.rb +9 -4
- data/lib/kuby/kubernetes/registry_secret.rb +1 -0
- data/lib/kuby/kubernetes/spec.rb +24 -22
- data/lib/kuby/middleware.rb +1 -0
- data/lib/kuby/middleware/health_check.rb +1 -0
- data/lib/kuby/plugin.rb +1 -0
- data/lib/kuby/plugin_registry.rb +28 -0
- data/lib/kuby/plugins.rb +1 -0
- data/lib/kuby/plugins/nginx_ingress.rb +1 -0
- data/lib/kuby/plugins/rails_app.rb +1 -0
- data/lib/kuby/plugins/rails_app/asset_copy_task.rb +1 -0
- data/lib/kuby/plugins/rails_app/assets.rb +1 -0
- data/lib/kuby/plugins/rails_app/database.rb +10 -9
- data/lib/kuby/plugins/rails_app/generators/kuby.rb +45 -44
- data/lib/kuby/plugins/rails_app/mysql.rb +1 -3
- data/lib/kuby/plugins/rails_app/plugin.rb +244 -44
- data/lib/kuby/plugins/rails_app/postgres.rb +1 -0
- data/lib/kuby/plugins/rails_app/rewrite_db_config.rb +1 -0
- data/lib/kuby/plugins/rails_app/sqlite.rb +1 -0
- data/lib/kuby/rails_commands.rb +84 -0
- data/lib/kuby/railtie.rb +1 -4
- data/lib/kuby/tasks.rb +78 -23
- data/lib/kuby/trailing_hash.rb +5 -3
- data/lib/kuby/version.rb +3 -1
- data/spec/docker/metadata_spec.rb +1 -108
- data/spec/docker/spec_spec.rb +303 -0
- data/spec/docker/timestamp_tag_spec.rb +1 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +1 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +1 -0
- data/spec/dummy/app/controllers/application_controller.rb +1 -0
- data/spec/dummy/app/helpers/application_helper.rb +1 -0
- data/spec/dummy/app/jobs/application_job.rb +1 -0
- data/spec/dummy/app/mailers/application_mailer.rb +1 -0
- data/spec/dummy/app/models/application_record.rb +1 -0
- data/spec/dummy/config/application.rb +1 -0
- data/spec/dummy/config/boot.rb +1 -0
- data/spec/dummy/config/environment.rb +1 -0
- data/spec/dummy/config/environments/development.rb +1 -0
- data/spec/dummy/config/environments/production.rb +1 -0
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +1 -0
- data/spec/dummy/config/initializers/assets.rb +1 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +1 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +1 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +1 -0
- data/spec/dummy/config/initializers/inflections.rb +1 -0
- data/spec/dummy/config/initializers/mime_types.rb +1 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +1 -0
- data/spec/dummy/config/puma.rb +1 -0
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/dummy/config/spring.rb +1 -0
- data/spec/dummy/db/seeds.rb +1 -0
- data/spec/dummy/test/application_system_test_case.rb +1 -0
- data/spec/dummy/test/channels/application_cable/connection_test.rb +1 -0
- data/spec/dummy/test/test_helper.rb +1 -0
- data/spec/spec_helper.rb +18 -1
- data/spec/support/docker/fake_cli.rb +1 -0
- data/spec/support/docker/remote/fake_client.rb +1 -0
- data/spec/trailing_hash_spec.rb +2 -0
- metadata +62 -11
- data/lib/kuby/tasks/kuby.rake +0 -70
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
require 'kuby/version'
|
|
3
|
+
require 'gli'
|
|
4
|
+
|
|
5
|
+
module Kuby
|
|
6
|
+
class Commands
|
|
7
|
+
extend GLI::App
|
|
8
|
+
|
|
9
|
+
# GLI doesn't have a wildcard option, so it's impossible to tell it to
|
|
10
|
+
# slurp up all args after a certain point. In our case, we want to be
|
|
11
|
+
# able to invoke `rails` commands and pass through all the original
|
|
12
|
+
# flags, switches, etc. To get around GLI's limitations, we identify
|
|
13
|
+
# `rails` commands in this hijacked `run` method and only use GLI to
|
|
14
|
+
# parse global options (like -e). The rest of the Rails options are
|
|
15
|
+
# captured in an instance variable and thereby made available to the
|
|
16
|
+
# Rails command handlers defined below. We use Module#prepend here to
|
|
17
|
+
# avoid the usual series of cryptic alias_method calls (note that there
|
|
18
|
+
# is no singleton class version of #prepend in the Ruby language).
|
|
19
|
+
singleton_class.send(:prepend, Module.new do
|
|
20
|
+
def run(args)
|
|
21
|
+
if idx = args.index('rails') || idx = args.index('rake')
|
|
22
|
+
@rails_options = args[idx..-1]
|
|
23
|
+
super(args[0..idx])
|
|
24
|
+
else
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end)
|
|
29
|
+
|
|
30
|
+
def self.tasks
|
|
31
|
+
Kuby::Tasks.new(Kuby.environment)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.must_be_dev_env!
|
|
35
|
+
unless Kuby.environment.development?
|
|
36
|
+
fail "Command not supported in the '#{Kuby.environment.name}' environment"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
program_desc 'Kuby command-line interface. Kuby is a convention '\
|
|
41
|
+
'over configuration approach for running Rails apps in Kubernetes.'
|
|
42
|
+
|
|
43
|
+
version Kuby::VERSION
|
|
44
|
+
|
|
45
|
+
subcommand_option_handling :normal
|
|
46
|
+
arguments :loose
|
|
47
|
+
|
|
48
|
+
desc 'The Kuby environment to use. Overrides KUBY_ENV.'
|
|
49
|
+
flag [:e, :environment], type: String, required: false
|
|
50
|
+
|
|
51
|
+
desc 'Path to your Kuby config file. Overrides KUBY_CONFIG.'
|
|
52
|
+
default_value './kuby.rb'
|
|
53
|
+
flag [:c, :config]
|
|
54
|
+
|
|
55
|
+
pre do |global_options, options, args|
|
|
56
|
+
Kuby.env = global_options[:environment] if global_options[:environment]
|
|
57
|
+
Kuby.load!(global_options[:config])
|
|
58
|
+
|
|
59
|
+
# GLI will abort unless this block returns a truthy value
|
|
60
|
+
true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# These are only stubs included to fill out the help screens. Rails
|
|
64
|
+
# commands are handled by the RailsCommands class.
|
|
65
|
+
desc 'Runs a Rails command.'
|
|
66
|
+
command :rails do |rc|
|
|
67
|
+
rc.action do |global_options, options, args|
|
|
68
|
+
must_be_dev_env!
|
|
69
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
70
|
+
Kuby::RailsCommands.run(@rails_options)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
rc.desc 'Runs the rails server (run `rails server --help` for options)'
|
|
74
|
+
rc.command [:server, :s] do |c|
|
|
75
|
+
c.action do |global_options, options, args|
|
|
76
|
+
must_be_dev_env!
|
|
77
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
78
|
+
Kuby::RailsCommands.run(@rails_options)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
rc.desc 'Runs a script in the Rails environment (run `rails runner --help` for options)'
|
|
83
|
+
rc.command [:runner, :r] do |c|
|
|
84
|
+
c.action do |global_options, options, args|
|
|
85
|
+
must_be_dev_env!
|
|
86
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
87
|
+
Kuby::RailsCommands.run(@rails_options)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
rc.desc 'Starts an interactive Ruby console with the Rails environment loaded '\
|
|
92
|
+
'(run `rails console --help` for options)'
|
|
93
|
+
rc.command [:console, :c] do |c|
|
|
94
|
+
c.action do |global_options, options, args|
|
|
95
|
+
must_be_dev_env!
|
|
96
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
97
|
+
Kuby::RailsCommands.run(@rails_options)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
desc 'Runs a rake task.'
|
|
103
|
+
command :rake do |rc|
|
|
104
|
+
rc.action do |global_options, options, args|
|
|
105
|
+
must_be_dev_env!
|
|
106
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
107
|
+
Kuby::RailsCommands.run(@rails_options)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
desc 'Builds the Docker image.'
|
|
112
|
+
command :build do |c|
|
|
113
|
+
c.action do |global_options, options, args|
|
|
114
|
+
tasks.build
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
desc 'Pushes the Docker image to the configured registry.'
|
|
119
|
+
command :push do |c|
|
|
120
|
+
c.action do |global_options, options, args|
|
|
121
|
+
tasks.push
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
desc 'Gets your Kubernetes cluster ready to run your Rails app.'
|
|
126
|
+
command :setup do |c|
|
|
127
|
+
c.action do |global_options, options, args|
|
|
128
|
+
tasks.setup
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
desc 'Prints the effective Dockerfile used to build the Docker image.'
|
|
133
|
+
command :dockerfile do |c|
|
|
134
|
+
c.action do |global_options, options, args|
|
|
135
|
+
tasks.print_dockerfile
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
desc 'Deploys the application.'
|
|
140
|
+
command :deploy do |c|
|
|
141
|
+
c.desc 'The Docker tag to deploy. Defaults to the most recent tag.'
|
|
142
|
+
c.flag [:t, :tag], required: false
|
|
143
|
+
c.action do |global_options, options, args|
|
|
144
|
+
tasks.deploy(options[:tag])
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
desc 'Rolls back to the previous Docker tag.'
|
|
149
|
+
command :rollback do |c|
|
|
150
|
+
c.action do |global_options, options, args|
|
|
151
|
+
tasks.rollback
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
desc 'Prints the effective Kubernetes resources that will be applied on deploy.'
|
|
156
|
+
command :resources do |c|
|
|
157
|
+
c.action do |global_options, options, args|
|
|
158
|
+
tasks.print_resources
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
desc 'Prints out the contents of the kubeconfig Kuby is using to communicate with your cluster.'
|
|
163
|
+
command :kubeconfig do |c|
|
|
164
|
+
c.action do |global_options, options, args|
|
|
165
|
+
tasks.print_kubeconfig
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
desc 'Runs an arbitrary kubectl command.'
|
|
170
|
+
command :kubectl do |c|
|
|
171
|
+
c.desc 'Prefixes the kubectl command with the namespace associated with '\
|
|
172
|
+
'the current environment. For example, if the Kuby env is "production", '\
|
|
173
|
+
'this option will prefix the kubectl command with "-n myapp-production".'
|
|
174
|
+
c.switch [:N, :namespaced], default: false
|
|
175
|
+
c.action do |global_options, options, args|
|
|
176
|
+
if options[:namespaced]
|
|
177
|
+
# sorry Demeter
|
|
178
|
+
namespace = Kuby.definition.environment.kubernetes.namespace.metadata.name
|
|
179
|
+
args = ['-n', namespace, *args]
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
tasks.kubectl(*args)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
desc 'Runs commands, etc against the Kubernetes cluster.'
|
|
187
|
+
command :remote do |rc|
|
|
188
|
+
rc.desc 'Tails (i.e. continuously streams) the Rails log from your running application.'
|
|
189
|
+
rc.command :logs do |c|
|
|
190
|
+
c.action do |global_options, options, args|
|
|
191
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
192
|
+
tasks.remote_logs
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
rc.desc 'Lists running Kubernetes pods.'
|
|
197
|
+
rc.command :status do |c|
|
|
198
|
+
c.action do |global_options, options, args|
|
|
199
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
200
|
+
tasks.remote_status
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
rc.desc 'Runs an arbitrary command inside a running Rails pod.'
|
|
205
|
+
rc.command :exec do |c|
|
|
206
|
+
c.action do |global_options, options, args|
|
|
207
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
208
|
+
tasks.remote_exec(args)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
rc.desc 'Establishes a shell inside a running Rails pod.'
|
|
213
|
+
rc.command :shell do |c|
|
|
214
|
+
c.action do |global_options, options, args|
|
|
215
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
216
|
+
tasks.remote_shell
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
rc.desc 'Establishes a Rails console inside a running Rails pod.'
|
|
221
|
+
rc.command :console do |c|
|
|
222
|
+
c.action do |global_options, options, args|
|
|
223
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
224
|
+
tasks.remote_console
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
rc.desc 'Establishes a database console inside a running Rails pod.'
|
|
229
|
+
rc.command :dbconsole do |c|
|
|
230
|
+
c.action do |global_options, options, args|
|
|
231
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
232
|
+
tasks.remote_dbconsole
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
rc.desc "Restarts the Rails app's web pods."
|
|
237
|
+
rc.command :restart do |c|
|
|
238
|
+
c.action do |global_options, options, args|
|
|
239
|
+
exit 1 unless tasks.dev_deployment_ok
|
|
240
|
+
tasks.remote_restart
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
data/lib/kuby/definition.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# typed: true
|
|
1
2
|
module Kuby
|
|
2
3
|
class Definition
|
|
3
4
|
attr_reader :app_name
|
|
@@ -9,9 +10,7 @@ module Kuby
|
|
|
9
10
|
def environment(name = Kuby.env, &block)
|
|
10
11
|
name = name.to_s
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
environments[name] ||= Environment.new(name, self)
|
|
14
|
-
end
|
|
13
|
+
environments[name] ||= Environment.new(name, self)
|
|
15
14
|
|
|
16
15
|
if block_given?
|
|
17
16
|
environments[name].instance_eval(&block)
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
module Kuby
|
|
3
|
+
class Spinner
|
|
4
|
+
PIECES = %w(- \\ | /).freeze
|
|
5
|
+
INTERVAL = 0.2 # seconds
|
|
6
|
+
|
|
7
|
+
def self.spin(message)
|
|
8
|
+
yield new(message)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :message, :status
|
|
12
|
+
|
|
13
|
+
def initialize(message)
|
|
14
|
+
@message = message
|
|
15
|
+
@status = :running
|
|
16
|
+
@thread = Thread.new do
|
|
17
|
+
counter = 0
|
|
18
|
+
|
|
19
|
+
while true
|
|
20
|
+
case status
|
|
21
|
+
when :running
|
|
22
|
+
piece = PIECES[counter % PIECES.size]
|
|
23
|
+
STDOUT.write "\r[#{piece}] #{message}"
|
|
24
|
+
sleep INTERVAL
|
|
25
|
+
counter += 1
|
|
26
|
+
when :success
|
|
27
|
+
STDOUT.write("\r[+] #{message}")
|
|
28
|
+
break
|
|
29
|
+
when :failure
|
|
30
|
+
STDOUT.write("\r[×] #{message}")
|
|
31
|
+
break
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
puts
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def success
|
|
40
|
+
@status = :success
|
|
41
|
+
@thread.join
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def failure
|
|
45
|
+
@status = :failure
|
|
46
|
+
@thread.join
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class SetupTask
|
|
51
|
+
attr_reader :message, :callable
|
|
52
|
+
|
|
53
|
+
def initialize(message, callable)
|
|
54
|
+
@message = message
|
|
55
|
+
@callable = callable
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def run
|
|
59
|
+
callable.call
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class Pipe
|
|
64
|
+
attr_reader :name, :cli, :out, :err
|
|
65
|
+
|
|
66
|
+
def initialize(name, cli)
|
|
67
|
+
@name = name
|
|
68
|
+
@cli = cli
|
|
69
|
+
@out = StringIO.new
|
|
70
|
+
@err = StringIO.new
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def wrap(&block)
|
|
74
|
+
cli.with_pipes(out, err) do
|
|
75
|
+
block.call
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def success?
|
|
80
|
+
cli.last_status.nil? || cli.last_status.success?
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
class Pipes
|
|
85
|
+
include Enumerable
|
|
86
|
+
|
|
87
|
+
attr_reader :pipes, :ex
|
|
88
|
+
|
|
89
|
+
def self.build(clis)
|
|
90
|
+
new(clis.map { |name, cli| Pipe.new(name, cli) })
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def initialize(pipes)
|
|
94
|
+
@pipes = pipes
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def each(&block)
|
|
98
|
+
pipes.each(&block)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def wrap(&block)
|
|
102
|
+
do_wrap(pipes, &block)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def success?
|
|
106
|
+
pipes.all?(&:success?) && !ex
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
|
|
111
|
+
def do_wrap(remaining_pipes, &block)
|
|
112
|
+
if remaining_pipes.empty?
|
|
113
|
+
begin
|
|
114
|
+
yield
|
|
115
|
+
rescue => e
|
|
116
|
+
@ex = e
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
return
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
remaining_pipes[0].wrap do
|
|
123
|
+
do_wrap(remaining_pipes[1..-1], &block)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
class SetupTaskList
|
|
129
|
+
attr_reader :tasks, :clis
|
|
130
|
+
|
|
131
|
+
def initialize(tasks, clis)
|
|
132
|
+
@tasks = tasks
|
|
133
|
+
@clis = clis
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def run
|
|
137
|
+
tasks.each do |task|
|
|
138
|
+
pipes = Pipes.build(clis)
|
|
139
|
+
|
|
140
|
+
Spinner.spin(task.message) do |spinner|
|
|
141
|
+
pipes.wrap { task.run }
|
|
142
|
+
|
|
143
|
+
if pipes.success?
|
|
144
|
+
spinner.success
|
|
145
|
+
else
|
|
146
|
+
spinner.failure
|
|
147
|
+
print_error(pipes.ex)
|
|
148
|
+
|
|
149
|
+
pipes.each do |pipe|
|
|
150
|
+
print_streams(pipe)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
return false
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
true
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
private
|
|
162
|
+
|
|
163
|
+
def print_streams(pipe)
|
|
164
|
+
unless pipe.out.string.strip.empty?
|
|
165
|
+
puts("========= #{pipe.name.upcase} STDOUT ========")
|
|
166
|
+
puts pipe.out.string
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
unless pipe.err.string.strip.empty?
|
|
170
|
+
puts("========= #{pipe.name.upcase} STDERR ========")
|
|
171
|
+
puts pipe.err.string
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def print_error(ex)
|
|
176
|
+
return unless ex
|
|
177
|
+
puts("========= RUBY ERROR ========")
|
|
178
|
+
puts(ex.message)
|
|
179
|
+
puts(ex.backtrace.join("\n"))
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
class DevSetup
|
|
184
|
+
attr_reader :environment
|
|
185
|
+
|
|
186
|
+
def initialize(environment)
|
|
187
|
+
@environment = environment
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def run
|
|
191
|
+
SetupTaskList.new(setup_tasks, clis).run
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
private
|
|
195
|
+
|
|
196
|
+
def setup_tasks
|
|
197
|
+
@setup_tasks ||= [
|
|
198
|
+
SetupTask.new(
|
|
199
|
+
'Building dev Docker image', -> { tasks.build }
|
|
200
|
+
),
|
|
201
|
+
|
|
202
|
+
SetupTask.new(
|
|
203
|
+
'Setting up local Kubernetes cluster', -> { tasks.setup }
|
|
204
|
+
),
|
|
205
|
+
|
|
206
|
+
SetupTask.new(
|
|
207
|
+
'Deploying dev environment', -> { tasks.deploy }
|
|
208
|
+
),
|
|
209
|
+
|
|
210
|
+
SetupTask.new(
|
|
211
|
+
'Installing bundler', -> {
|
|
212
|
+
tasks.remote_system("gem install bundler -v #{Bundler::VERSION}")
|
|
213
|
+
}
|
|
214
|
+
),
|
|
215
|
+
|
|
216
|
+
SetupTask.new(
|
|
217
|
+
'Installing bundled gems', -> { tasks.remote_system('bundle install') }
|
|
218
|
+
),
|
|
219
|
+
|
|
220
|
+
SetupTask.new(
|
|
221
|
+
'Installing Javascript packages', -> { tasks.remote_system('yarn install') }
|
|
222
|
+
),
|
|
223
|
+
|
|
224
|
+
SetupTask.new(
|
|
225
|
+
'Creating database', -> { tasks.remote_system('bundle exec rake db:create') }
|
|
226
|
+
),
|
|
227
|
+
|
|
228
|
+
SetupTask.new(
|
|
229
|
+
'Migrating database', -> { tasks.remote_system('bundle exec rake db:migrate') }
|
|
230
|
+
)
|
|
231
|
+
]
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def kubernetes
|
|
235
|
+
environment.kubernetes
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def docker
|
|
239
|
+
environment.docker
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def clis
|
|
243
|
+
@clis ||= {
|
|
244
|
+
kubectl: kubernetes.provider.kubernetes_cli,
|
|
245
|
+
helm: kubernetes.provider.helm_cli,
|
|
246
|
+
krane: kubernetes.provider.deployer,
|
|
247
|
+
docker: docker.cli,
|
|
248
|
+
kuby: Kuby.logger
|
|
249
|
+
}
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def tasks
|
|
253
|
+
@tasks ||= Kuby::Tasks.new(environment)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|