kuby-core 0.5.0 → 0.6.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 +34 -0
- data/kuby-core.gemspec +2 -1
- data/lib/kuby.rb +20 -14
- data/lib/kuby/definition.rb +22 -16
- data/lib/kuby/docker.rb +2 -1
- data/lib/kuby/docker/alpine.rb +0 -1
- data/lib/kuby/docker/assets_phase.rb +1 -1
- data/lib/kuby/docker/bundler_phase.rb +4 -2
- data/lib/kuby/docker/copy_phase.rb +1 -1
- data/lib/kuby/docker/inline_layer.rb +15 -0
- data/lib/kuby/docker/{phase.rb → layer.rb} +6 -5
- data/lib/kuby/docker/layer_stack.rb +30 -4
- data/lib/kuby/docker/metadata.rb +5 -1
- data/lib/kuby/docker/package_phase.rb +1 -1
- data/lib/kuby/docker/setup_phase.rb +1 -1
- data/lib/kuby/docker/spec.rb +4 -4
- data/lib/kuby/docker/webserver_phase.rb +1 -1
- data/lib/kuby/docker/yarn_phase.rb +1 -1
- data/lib/kuby/environment.rb +22 -0
- data/lib/kuby/kubernetes/minikube_provider.rb +5 -5
- data/lib/kuby/kubernetes/plugins/nginx_ingress.rb +12 -0
- data/lib/kuby/kubernetes/plugins/rails_app/database.rb +30 -9
- data/lib/kuby/kubernetes/plugins/rails_app/generators/kuby.rb +43 -4
- data/lib/kuby/kubernetes/plugins/rails_app/mysql.rb +14 -4
- data/lib/kuby/kubernetes/plugins/rails_app/plugin.rb +15 -14
- data/lib/kuby/kubernetes/plugins/rails_app/postgres.rb +132 -0
- data/lib/kuby/kubernetes/plugins/rails_app/sqlite.rb +20 -0
- data/lib/kuby/kubernetes/plugins/rails_app/tasks.rake +9 -4
- data/lib/kuby/kubernetes/spec.rb +1 -1
- data/lib/kuby/railtie.rb +0 -4
- data/lib/kuby/tasks.rb +12 -0
- data/lib/kuby/tasks/kuby.rake +19 -18
- data/lib/kuby/version.rb +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfe201dc901e8ae1b43121cb2652343f8db33893a6da69d783715cc7f320e2d2
|
4
|
+
data.tar.gz: 452b7119e76ee461f93729aa70999d51a5b1f77bc7b3af5c4935ebd863f2e526
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2944a9ea28ee31b4763d2cbbe2db04cc9009526919ef8a25b8513fbf2fdfbf72e5356ee94969b4623fc208e3b7bc527d1423e68d39447e500c0a2bd8b93867ca
|
7
|
+
data.tar.gz: 6259dd452e62337c01d1d301a0adc0fedb394c6a667e7f51a5cece1cf5464654708ba9ca56783aed610067e6b6a86131f8d7cb9371de51202e0f867610d66f15
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,37 @@
|
|
1
|
+
## 0.6.0
|
2
|
+
* Don't load the Rails environment when running Kuby's rake tasks.
|
3
|
+
- Kuby's gems are still part of the bundle, but config has been moved out of the initializer and into kuby.rb in the Rails root directory.
|
4
|
+
- Internal classes no longer retain a reference to `Rails.application`.
|
5
|
+
- Kuby config now requires `environment` blocks:
|
6
|
+
```ruby
|
7
|
+
Kuby.define('my-app') do
|
8
|
+
environment(:production) do
|
9
|
+
...
|
10
|
+
end
|
11
|
+
|
12
|
+
environment(:staging) do
|
13
|
+
...
|
14
|
+
end
|
15
|
+
end
|
16
|
+
```
|
17
|
+
* Fix `MissingDistroError` caused by not setting a default distro.
|
18
|
+
* Create a .dockerignore file when running the Rails generator.
|
19
|
+
* Add ability to insert inline Docker layers without having to create a separate class, eg:
|
20
|
+
```ruby
|
21
|
+
insert :hello, before: :bundler_phase do |dockerfile|
|
22
|
+
dockerfile.run('echo "hello, world"')
|
23
|
+
end
|
24
|
+
```
|
25
|
+
* Add Postgres database support.
|
26
|
+
* Don't install sqlite libs by default.
|
27
|
+
* Modify Rails generator
|
28
|
+
- Require kuby and load config safely.
|
29
|
+
- Provide manual access to credentials via `ActiveSupport::EncryptedConfiguration`, which is necessary now that our rake tasks don't load the Rails environment.
|
30
|
+
* Add a convenience method for requesting the amount of block storage for the database.
|
31
|
+
* Add the ability to entirely disable database management via `manage_database false`.
|
32
|
+
* Avoid deploying nginx-ingress if it's already deployed.
|
33
|
+
* Add rake task for running arbitrary `kubectl` commands.
|
34
|
+
|
1
35
|
## 0.5.0
|
2
36
|
* Fix Rails generators issue causing crash at startup.
|
3
37
|
* Add rake task to run arbitrary kubectl commands.
|
data/kuby-core.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.add_dependency 'colorize', '~> 0.8'
|
16
16
|
s.add_dependency 'docker-remote', '~> 0.1'
|
17
17
|
s.add_dependency 'krane', '~> 1.0'
|
18
|
-
s.add_dependency 'kuby-cert-manager', '~> 0.
|
18
|
+
s.add_dependency 'kuby-cert-manager', '~> 0.2'
|
19
19
|
s.add_dependency 'kube-dsl', '~> 0.3'
|
20
20
|
s.add_dependency 'kuby-kube-db', '~> 0.4'
|
21
21
|
s.add_dependency 'kubernetes-cli', '~> 0.2'
|
@@ -23,5 +23,6 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_dependency 'rouge', '~> 3.0'
|
24
24
|
|
25
25
|
s.require_path = 'lib'
|
26
|
+
|
26
27
|
s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'LICENSE', 'CHANGELOG.md', 'README.md', 'Rakefile', 'kuby-core.gemspec']
|
27
28
|
end
|
data/lib/kuby.rb
CHANGED
@@ -10,6 +10,7 @@ module Kuby
|
|
10
10
|
autoload :CLIBase, 'kuby/cli_base'
|
11
11
|
autoload :Definition, 'kuby/definition'
|
12
12
|
autoload :Docker, 'kuby/docker'
|
13
|
+
autoload :Environment, 'kuby/environment'
|
13
14
|
autoload :Kubernetes, 'kuby/kubernetes'
|
14
15
|
autoload :Middleware, 'kuby/middleware'
|
15
16
|
autoload :Tasks, 'kuby/tasks'
|
@@ -19,19 +20,25 @@ module Kuby
|
|
19
20
|
|
20
21
|
class << self
|
21
22
|
attr_reader :definition
|
22
|
-
|
23
|
+
attr_writer :logger
|
23
24
|
|
24
|
-
def
|
25
|
-
|
26
|
-
definitions[environment] ||= Definition.new(environment, app, &block)
|
25
|
+
def load!
|
26
|
+
require ENV['KUBY_CONFIG'] || File.join('.', 'kuby.rb')
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
29
|
+
def define(name, &block)
|
30
|
+
raise 'Kuby is already configured' if @definition
|
31
|
+
|
32
|
+
@definition = Definition.new(name.to_s)
|
33
|
+
@definition.instance_eval(&block)
|
34
|
+
|
35
|
+
@definition.environments.each do |_, env|
|
36
|
+
env.kubernetes.after_configuration
|
37
|
+
end
|
31
38
|
end
|
32
39
|
|
33
|
-
def
|
34
|
-
|
40
|
+
def environment(name = env)
|
41
|
+
definition.environment(name.to_s) do
|
35
42
|
raise UndefinedEnvironmentError, "couldn't find a Kuby environment named "\
|
36
43
|
"'#{environment}'"
|
37
44
|
end
|
@@ -61,6 +68,10 @@ module Kuby
|
|
61
68
|
@plugins ||= {}
|
62
69
|
end
|
63
70
|
|
71
|
+
def logger
|
72
|
+
@logger ||= BasicLogger.new(STDERR)
|
73
|
+
end
|
74
|
+
|
64
75
|
def register_package(package_name, package_def = nil)
|
65
76
|
packages[package_name] = case package_def
|
66
77
|
when NilClass
|
@@ -86,7 +97,7 @@ module Kuby
|
|
86
97
|
|
87
98
|
def env
|
88
99
|
ENV.fetch('KUBY_ENV') do
|
89
|
-
(
|
100
|
+
(definition.environments.keys.first || Rails.env).to_s
|
90
101
|
end
|
91
102
|
end
|
92
103
|
end
|
@@ -114,8 +125,3 @@ Kuby.register_package(:c_toolchain,
|
|
114
125
|
debian: 'build-essential',
|
115
126
|
alpine: 'build-base'
|
116
127
|
)
|
117
|
-
|
118
|
-
Kuby.register_package(:sqlite_dev,
|
119
|
-
debian: 'libsqlite3-dev',
|
120
|
-
alpine: 'sqlite-dev'
|
121
|
-
)
|
data/lib/kuby/definition.rb
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
module Kuby
|
2
2
|
class Definition
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :app_name
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
7
|
-
|
5
|
+
def initialize(app_name, &block)
|
6
|
+
@app_name = app_name
|
7
|
+
end
|
8
|
+
|
9
|
+
def environment(name = Kuby.env, &block)
|
10
|
+
name = name.to_s
|
11
|
+
|
12
|
+
if name
|
13
|
+
environments[name] ||= Environment.new(name, self)
|
14
|
+
end
|
15
|
+
|
16
|
+
if block_given?
|
17
|
+
environments[name].instance_eval(&block)
|
18
|
+
end
|
8
19
|
|
9
|
-
|
10
|
-
kubernetes.after_configuration
|
20
|
+
environments[name]
|
11
21
|
end
|
12
22
|
|
13
|
-
def docker
|
14
|
-
|
15
|
-
@docker.instance_eval(&block) if block
|
16
|
-
@docker
|
23
|
+
def docker
|
24
|
+
environment.docker
|
17
25
|
end
|
18
26
|
|
19
|
-
def kubernetes
|
20
|
-
|
21
|
-
@kubernetes.instance_eval(&block) if block
|
22
|
-
@kubernetes
|
27
|
+
def kubernetes
|
28
|
+
environment.kubernetes
|
23
29
|
end
|
24
30
|
|
25
|
-
def
|
26
|
-
@
|
31
|
+
def environments
|
32
|
+
@environments ||= {}
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
data/lib/kuby/docker.rb
CHANGED
@@ -10,12 +10,13 @@ module Kuby
|
|
10
10
|
autoload :Credentials, 'kuby/docker/credentials'
|
11
11
|
autoload :Debian, 'kuby/docker/debian'
|
12
12
|
autoload :Dockerfile, 'kuby/docker/dockerfile'
|
13
|
+
autoload :InlineLayer, 'kuby/docker/inline_layer'
|
14
|
+
autoload :Layer, 'kuby/docker/layer'
|
13
15
|
autoload :LayerStack, 'kuby/docker/layer_stack'
|
14
16
|
autoload :LocalTags, 'kuby/docker/local_tags'
|
15
17
|
autoload :Metadata, 'kuby/docker/metadata'
|
16
18
|
autoload :Packages, 'kuby/docker/packages'
|
17
19
|
autoload :PackagePhase, 'kuby/docker/package_phase'
|
18
|
-
autoload :Phase, 'kuby/docker/phase'
|
19
20
|
autoload :RemoteTags, 'kuby/docker/remote_tags'
|
20
21
|
autoload :SetupPhase, 'kuby/docker/setup_phase'
|
21
22
|
autoload :Spec, 'kuby/docker/spec'
|
data/lib/kuby/docker/alpine.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
1
3
|
module Kuby
|
2
4
|
module Docker
|
3
|
-
class BundlerPhase <
|
5
|
+
class BundlerPhase < Layer
|
4
6
|
DEFAULT_WITHOUT = ['development', 'test', 'deploy'].freeze
|
5
7
|
|
6
8
|
attr_accessor :version, :gemfile, :without
|
@@ -48,7 +50,7 @@ module Kuby
|
|
48
50
|
.definition
|
49
51
|
.gemfiles
|
50
52
|
.first
|
51
|
-
.relative_path_from(
|
53
|
+
.relative_path_from(Pathname(Dir.getwd))
|
52
54
|
.to_s
|
53
55
|
end
|
54
56
|
end
|
@@ -1,18 +1,19 @@
|
|
1
1
|
module Kuby
|
2
2
|
module Docker
|
3
|
-
class
|
3
|
+
class Layer
|
4
4
|
attr_reader :definition
|
5
5
|
|
6
6
|
def initialize(definition)
|
7
7
|
@definition = definition
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
definition.app
|
10
|
+
def apply_to(dockerfile)
|
11
|
+
raise NotImplementedError,
|
12
|
+
"#{__method__} must be defined in derived classes"
|
14
13
|
end
|
15
14
|
|
15
|
+
private
|
16
|
+
|
16
17
|
def metadata
|
17
18
|
definition.docker.metadata
|
18
19
|
end
|
@@ -15,12 +15,31 @@ module Kuby
|
|
15
15
|
@stack.each { |name| yield layers[name] }
|
16
16
|
end
|
17
17
|
|
18
|
-
def use(name, layer)
|
18
|
+
def use(name, layer = nil, &block)
|
19
19
|
stack << name
|
20
|
-
|
20
|
+
|
21
|
+
if layer
|
22
|
+
layers[name] = layer
|
23
|
+
elsif block_given?
|
24
|
+
layers[name] = InlineLayer.new(block)
|
25
|
+
else
|
26
|
+
raise "Must either pass a layer object or a block to `#{__method__}'"
|
27
|
+
end
|
21
28
|
end
|
22
29
|
|
23
|
-
def insert(name, layer, options = {})
|
30
|
+
def insert(name, layer = nil, options = {}, &block)
|
31
|
+
# this is truly gross but it's the only way I can think of to be able
|
32
|
+
# to call insert these two ways:
|
33
|
+
#
|
34
|
+
# insert :foo, FooLayer.new, before: :bundler_phase
|
35
|
+
# insert :foo, before: :bundler_phase do
|
36
|
+
# ...
|
37
|
+
# end
|
38
|
+
if layer.is_a?(Hash)
|
39
|
+
insert(name, nil, options.merge(layer), &block)
|
40
|
+
return
|
41
|
+
end
|
42
|
+
|
24
43
|
existing_name = options[:before] || options[:after]
|
25
44
|
idx = stack.index(existing_name)
|
26
45
|
|
@@ -30,7 +49,14 @@ module Kuby
|
|
30
49
|
|
31
50
|
idx += 1 if options[:after]
|
32
51
|
stack.insert(idx, name)
|
33
|
-
|
52
|
+
|
53
|
+
if layer
|
54
|
+
layers[name] = layer
|
55
|
+
elsif block_given?
|
56
|
+
layers[name] = InlineLayer.new(block)
|
57
|
+
else
|
58
|
+
raise "Must either pass a layer object or a block to `#{__method__}'"
|
59
|
+
end
|
34
60
|
end
|
35
61
|
|
36
62
|
def delete(name)
|
data/lib/kuby/docker/metadata.rb
CHANGED
@@ -8,7 +8,7 @@ module Kuby
|
|
8
8
|
LATEST_TAG = 'latest'
|
9
9
|
|
10
10
|
attr_accessor :image_url
|
11
|
-
attr_reader :definition
|
11
|
+
attr_reader :definition
|
12
12
|
|
13
13
|
def initialize(definition)
|
14
14
|
@definition = definition
|
@@ -62,6 +62,10 @@ module Kuby
|
|
62
62
|
t.to_s
|
63
63
|
end
|
64
64
|
|
65
|
+
def distro
|
66
|
+
@distro || DEFAULT_DISTRO
|
67
|
+
end
|
68
|
+
|
65
69
|
def distro=(distro_name)
|
66
70
|
@distro = distro_name
|
67
71
|
end
|
data/lib/kuby/docker/spec.rb
CHANGED
@@ -50,12 +50,12 @@ module Kuby
|
|
50
50
|
metadata.image_url = url
|
51
51
|
end
|
52
52
|
|
53
|
-
def use(*args)
|
54
|
-
layer_stack.use(*args)
|
53
|
+
def use(*args, &block)
|
54
|
+
layer_stack.use(*args, &block)
|
55
55
|
end
|
56
56
|
|
57
|
-
def insert(*args)
|
58
|
-
layer_stack.insert(*args)
|
57
|
+
def insert(*args, &block)
|
58
|
+
layer_stack.insert(*args, &block)
|
59
59
|
end
|
60
60
|
|
61
61
|
def delete(*args)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Kuby
|
2
|
+
class Environment
|
3
|
+
attr_reader :name, :definition
|
4
|
+
|
5
|
+
def initialize(name, definition, &block)
|
6
|
+
@name = name
|
7
|
+
@definition = definition
|
8
|
+
end
|
9
|
+
|
10
|
+
def docker(&block)
|
11
|
+
@docker ||= Docker::Spec.new(definition)
|
12
|
+
@docker.instance_eval(&block) if block
|
13
|
+
@docker
|
14
|
+
end
|
15
|
+
|
16
|
+
def kubernetes(&block)
|
17
|
+
@kubernetes ||= Kubernetes::Spec.new(definition)
|
18
|
+
@kubernetes.instance_eval(&block) if block
|
19
|
+
@kubernetes
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -26,11 +26,6 @@ module Kuby
|
|
26
26
|
rails_app.resources.delete(rails_app.ingress)
|
27
27
|
rails_app.service.spec { type 'LoadBalancer' }
|
28
28
|
end
|
29
|
-
|
30
|
-
configure do
|
31
|
-
# default kubeconfig path
|
32
|
-
kubeconfig File.join(ENV['HOME'], '.kube', 'config')
|
33
|
-
end
|
34
29
|
end
|
35
30
|
|
36
31
|
def kubeconfig_path
|
@@ -45,6 +40,11 @@ module Kuby
|
|
45
40
|
|
46
41
|
def after_initialize
|
47
42
|
@config = Config.new
|
43
|
+
|
44
|
+
configure do
|
45
|
+
# default kubeconfig path
|
46
|
+
kubeconfig File.join(ENV['HOME'], '.kube', 'config')
|
47
|
+
end
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -27,6 +27,11 @@ module Kuby
|
|
27
27
|
def setup
|
28
28
|
Kuby.logger.info('Deploying nginx ingress resources')
|
29
29
|
|
30
|
+
if already_deployed?
|
31
|
+
Kuby.logger.info('Nginx ingress already deployed, skipping')
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
30
35
|
SETUP_RESOURCES.each do |uri|
|
31
36
|
uri = uri % { provider: @config.provider || DEFAULT_PROVIDER }
|
32
37
|
kubernetes_cli.apply_uri(uri)
|
@@ -48,6 +53,13 @@ module Kuby
|
|
48
53
|
|
49
54
|
private
|
50
55
|
|
56
|
+
def already_deployed?
|
57
|
+
kubernetes_cli.get_object('Service', 'ingress-nginx', 'ingress-nginx')
|
58
|
+
true
|
59
|
+
rescue KubernetesCLI::GetResourceError
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
|
51
63
|
def after_initialize
|
52
64
|
@config = Config.new
|
53
65
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
|
1
4
|
module Kuby
|
2
5
|
module Kubernetes
|
3
6
|
module Plugins
|
@@ -11,27 +14,29 @@ module Kuby
|
|
11
14
|
'postgresql' => Postgres
|
12
15
|
}.freeze
|
13
16
|
|
14
|
-
def self.get(
|
15
|
-
|
17
|
+
def self.get(rails_app)
|
18
|
+
if rails_app.manage_database?
|
19
|
+
new(rails_app).database
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
23
|
def self.get_adapter(adapter)
|
19
24
|
ADAPTER_MAP.fetch(adapter) do
|
20
|
-
raise UnsupportedDatabaseError, "Kuby does not support the '#{adapter}'"\
|
25
|
+
raise UnsupportedDatabaseError, "Kuby does not support the '#{adapter}' "\
|
21
26
|
'database adapter'
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
25
|
-
attr_reader :
|
30
|
+
attr_reader :rails_app
|
26
31
|
|
27
|
-
def initialize(
|
28
|
-
@
|
32
|
+
def initialize(rails_app)
|
33
|
+
@rails_app = rails_app
|
29
34
|
end
|
30
35
|
|
31
36
|
def database
|
32
37
|
@database ||= self.class
|
33
38
|
.get_adapter(adapter)
|
34
|
-
.new(
|
39
|
+
.new(rails_app, environment, db_configs)
|
35
40
|
end
|
36
41
|
|
37
42
|
private
|
@@ -45,11 +50,27 @@ module Kuby
|
|
45
50
|
end
|
46
51
|
|
47
52
|
def environment
|
48
|
-
@environment ||= definition.environment
|
53
|
+
@environment ||= rails_app.definition.environment.name
|
49
54
|
end
|
50
55
|
|
51
56
|
def db_configs
|
52
|
-
@db_configs ||=
|
57
|
+
@db_configs ||= YAML.load(ERB.new(File.read(db_config_path)).result)
|
58
|
+
end
|
59
|
+
|
60
|
+
def db_config_path
|
61
|
+
@db_config_path ||= begin
|
62
|
+
db_config_paths.first or
|
63
|
+
raise "Couldn't find database config at #{rails_app.root}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def db_config_paths
|
68
|
+
@db_config_paths ||=
|
69
|
+
Dir.glob(
|
70
|
+
File.join(
|
71
|
+
rails_app.root, 'config', 'database.{yml,erb,yml.erb,yaml,yaml.erb}'
|
72
|
+
)
|
73
|
+
)
|
53
74
|
end
|
54
75
|
end
|
55
76
|
end
|
@@ -6,15 +6,35 @@ class KubyGenerator < Rails::Generators::Base
|
|
6
6
|
initializer(
|
7
7
|
'kuby.rb',
|
8
8
|
<<~END
|
9
|
+
require 'kuby'
|
10
|
+
|
11
|
+
Kuby.load!
|
12
|
+
END
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_config_file
|
17
|
+
create_file(
|
18
|
+
'kuby.rb',
|
19
|
+
<<~END
|
20
|
+
require 'active_support/encrypted_configuration'
|
21
|
+
|
9
22
|
# Define a production Kuby deploy environment
|
10
23
|
Kuby.define(:production) do
|
24
|
+
app_creds = ActiveSupport::EncryptedConfiguration.new(
|
25
|
+
config_path: File.join('config', 'credentials.yml.enc'),
|
26
|
+
key_path: File.join('config', 'master.key'),
|
27
|
+
env_key: 'RAILS_MASTER_KEY',
|
28
|
+
raise_if_missing_key: true
|
29
|
+
)
|
30
|
+
|
11
31
|
docker do
|
12
32
|
# Configure your Docker registry credentials here. Add them to your
|
13
33
|
# Rails credentials file by running `bundle exec rake credentials:edit`.
|
14
34
|
credentials do
|
15
|
-
username
|
16
|
-
password
|
17
|
-
email
|
35
|
+
username app_creds[:KUBY_DOCKER_USERNAME]
|
36
|
+
password app_creds[:KUBY_DOCKER_PASSWORD]
|
37
|
+
email app_creds[:KUBY_DOCKER_EMAIL]
|
18
38
|
end
|
19
39
|
|
20
40
|
# Configure the URL to your Docker image here, eg:
|
@@ -28,7 +48,8 @@ class KubyGenerator < Rails::Generators::Base
|
|
28
48
|
# Add a plugin that facilitates deploying a Rails app.
|
29
49
|
add_plugin :rails_app
|
30
50
|
|
31
|
-
# Use minikube as the default
|
51
|
+
# Use minikube as the provider, which is the default installed by
|
52
|
+
# Docker Desktop.
|
32
53
|
# See: https://github.com/kubernetes/minikube
|
33
54
|
#
|
34
55
|
# Note: you will likely want to use a different provider when deploying
|
@@ -41,4 +62,22 @@ class KubyGenerator < Rails::Generators::Base
|
|
41
62
|
END
|
42
63
|
)
|
43
64
|
end
|
65
|
+
|
66
|
+
def create_dockerignore
|
67
|
+
create_file(
|
68
|
+
'.dockerignore',
|
69
|
+
<<~END
|
70
|
+
.bundle/
|
71
|
+
vendor/bundle
|
72
|
+
node_modules/
|
73
|
+
.node_modules/
|
74
|
+
**/.git*
|
75
|
+
tmp/
|
76
|
+
log/
|
77
|
+
engines/**/log/
|
78
|
+
engines/**/tmp/
|
79
|
+
public/assets
|
80
|
+
END
|
81
|
+
)
|
82
|
+
end
|
44
83
|
end
|
@@ -56,6 +56,20 @@ module Kuby
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
def storage(amount)
|
60
|
+
database do
|
61
|
+
spec do
|
62
|
+
storage do
|
63
|
+
resources do
|
64
|
+
requests do
|
65
|
+
set :storage, amount
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
59
73
|
def secret(&block)
|
60
74
|
context = self
|
61
75
|
|
@@ -118,10 +132,6 @@ module Kuby
|
|
118
132
|
definition.kubernetes
|
119
133
|
end
|
120
134
|
|
121
|
-
def app
|
122
|
-
definition.app
|
123
|
-
end
|
124
|
-
|
125
135
|
private
|
126
136
|
|
127
137
|
def config
|
@@ -13,12 +13,17 @@ module Kuby
|
|
13
13
|
ENV_SECRETS = [MASTER_KEY_VAR].freeze
|
14
14
|
ENV_EXCLUDE = ['RAILS_ENV'].freeze
|
15
15
|
|
16
|
-
|
16
|
+
value_field :root, default: '.'
|
17
|
+
value_fields :hostname, :tls_enabled
|
18
|
+
value_fields :manage_database, :database, :replicas
|
19
|
+
|
20
|
+
alias_method :manage_database?, :manage_database
|
17
21
|
|
18
22
|
def initialize(definition)
|
19
23
|
@definition = definition
|
20
24
|
@tls_enabled = true
|
21
25
|
@replicas = 1
|
26
|
+
@manage_database = true
|
22
27
|
end
|
23
28
|
|
24
29
|
def configure(&block)
|
@@ -26,11 +31,7 @@ module Kuby
|
|
26
31
|
end
|
27
32
|
|
28
33
|
def after_configuration
|
29
|
-
|
30
|
-
# is here as a placeholder to indicate we'd like to be able to
|
31
|
-
# handle Rails apps that don't use a database, i.e. don't have
|
32
|
-
# activerecord configured
|
33
|
-
if @database = Database.get(definition)
|
34
|
+
if @database = Database.get(self)
|
34
35
|
definition.kubernetes.plugins[database] = @database
|
35
36
|
definition.kubernetes.add_plugin(:kube_db)
|
36
37
|
|
@@ -43,7 +44,11 @@ module Kuby
|
|
43
44
|
definition.kubernetes.add_plugin(:nginx_ingress)
|
44
45
|
|
45
46
|
if @tls_enabled
|
46
|
-
|
47
|
+
context = self
|
48
|
+
|
49
|
+
definition.kubernetes.add_plugin(:cert_manager) do
|
50
|
+
email context.definition.docker.credentials.email
|
51
|
+
end
|
47
52
|
end
|
48
53
|
end
|
49
54
|
|
@@ -178,9 +183,9 @@ module Kuby
|
|
178
183
|
if master_key = ENV[MASTER_KEY_VAR]
|
179
184
|
add MASTER_KEY_VAR.to_sym, master_key
|
180
185
|
else
|
181
|
-
master_key_path = spec.
|
186
|
+
master_key_path = File.join(spec.root, 'config', 'master.key')
|
182
187
|
|
183
|
-
if
|
188
|
+
if File.exist?(master_key_path)
|
184
189
|
add MASTER_KEY_VAR.to_sym, File.read(master_key_path).strip
|
185
190
|
end
|
186
191
|
end
|
@@ -344,7 +349,7 @@ module Kuby
|
|
344
349
|
app_secrets,
|
345
350
|
deployment,
|
346
351
|
ingress,
|
347
|
-
*database
|
352
|
+
*database&.resources
|
348
353
|
]
|
349
354
|
end
|
350
355
|
|
@@ -364,10 +369,6 @@ module Kuby
|
|
364
369
|
definition.kubernetes
|
365
370
|
end
|
366
371
|
|
367
|
-
def app
|
368
|
-
definition.app
|
369
|
-
end
|
370
|
-
|
371
372
|
def namespace
|
372
373
|
definition.kubernetes.namespace
|
373
374
|
end
|
@@ -1,10 +1,142 @@
|
|
1
|
+
require 'kube-dsl'
|
2
|
+
require 'kuby/kube-db'
|
3
|
+
|
1
4
|
module Kuby
|
2
5
|
module Kubernetes
|
3
6
|
module Plugins
|
4
7
|
module RailsApp
|
5
8
|
class Postgres < Kuby::Kubernetes::Plugin
|
9
|
+
ROLE = 'web'.freeze
|
10
|
+
|
11
|
+
attr_reader :definition, :environment, :configs
|
12
|
+
|
13
|
+
def initialize(definition, environment, configs)
|
14
|
+
@definition = definition
|
15
|
+
@environment = environment
|
16
|
+
@configs = configs
|
17
|
+
|
18
|
+
user(config['username'])
|
19
|
+
password(config['password'])
|
20
|
+
end
|
21
|
+
|
22
|
+
def resources
|
23
|
+
@resources ||= [secret, database]
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_configuration
|
27
|
+
definition.docker.package_phase.add(:postgres_dev)
|
28
|
+
definition.docker.package_phase.add(:postgres_client)
|
29
|
+
end
|
30
|
+
|
31
|
+
def host
|
32
|
+
# host is the same as the name thanks to k8s DNS
|
33
|
+
@host ||= database.metadata.name
|
34
|
+
end
|
35
|
+
|
36
|
+
def rewritten_configs
|
37
|
+
# deep dup
|
38
|
+
@rewritten_configs ||= Marshal.load(Marshal.dump(configs)).tap do |new_configs|
|
39
|
+
new_configs[environment]['host'] = host
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def user(user)
|
44
|
+
secret do
|
45
|
+
data do
|
46
|
+
set :POSTGRES_USER, user
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def password(password)
|
52
|
+
secret do
|
53
|
+
data do
|
54
|
+
set :POSTGRES_PASSWORD, password
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def secret(&block)
|
60
|
+
context = self
|
61
|
+
|
62
|
+
@secret ||= KubeDSL.secret do
|
63
|
+
metadata do
|
64
|
+
name "#{context.base_name}-postgres-secret"
|
65
|
+
namespace context.kubernetes.namespace.metadata.name
|
66
|
+
end
|
67
|
+
|
68
|
+
type 'Opaque'
|
69
|
+
end
|
70
|
+
|
71
|
+
@secret.instance_eval(&block) if block
|
72
|
+
@secret
|
73
|
+
end
|
74
|
+
|
75
|
+
def database(&block)
|
76
|
+
context = self
|
77
|
+
|
78
|
+
@database ||= Kuby::KubeDB.postgres do
|
79
|
+
api_version 'kubedb.com/v1alpha1'
|
80
|
+
|
81
|
+
metadata do
|
82
|
+
name "#{context.base_name}-postgres"
|
83
|
+
namespace context.kubernetes.namespace.metadata.name
|
84
|
+
end
|
85
|
+
|
86
|
+
spec do
|
87
|
+
database_secret do
|
88
|
+
secret_name context.secret.metadata.name
|
89
|
+
end
|
90
|
+
|
91
|
+
version '11.2'
|
92
|
+
standby_mode 'Hot'
|
93
|
+
streaming_mode 'asynchronous'
|
94
|
+
storage_type 'Durable'
|
95
|
+
|
96
|
+
storage do
|
97
|
+
storage_class_name context.kubernetes.provider.storage_class_name
|
98
|
+
access_modes ['ReadWriteOnce']
|
99
|
+
|
100
|
+
resources do
|
101
|
+
requests do
|
102
|
+
add :storage, '10Gi'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
termination_policy 'DoNotTerminate'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
@database.instance_eval(&block) if block
|
112
|
+
@database
|
113
|
+
end
|
114
|
+
|
115
|
+
def base_name
|
116
|
+
@base_name ||= "#{kubernetes.selector_app}-#{ROLE}"
|
117
|
+
end
|
118
|
+
|
119
|
+
def kubernetes
|
120
|
+
definition.kubernetes
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def config
|
126
|
+
configs[environment]
|
127
|
+
end
|
6
128
|
end
|
7
129
|
end
|
8
130
|
end
|
9
131
|
end
|
10
132
|
end
|
133
|
+
|
134
|
+
Kuby.register_package(:postgres_dev,
|
135
|
+
debian: 'postgresql-client',
|
136
|
+
alpine: 'postgresql-dev'
|
137
|
+
)
|
138
|
+
|
139
|
+
Kuby.register_package(:postgres_client,
|
140
|
+
debian: 'postgresql-client',
|
141
|
+
alpine: 'postgresql-client'
|
142
|
+
)
|
@@ -3,8 +3,28 @@ module Kuby
|
|
3
3
|
module Plugins
|
4
4
|
module RailsApp
|
5
5
|
class Sqlite < Kuby::Kubernetes::Plugin
|
6
|
+
attr_reader :definition
|
7
|
+
|
8
|
+
def initialize(definition, *)
|
9
|
+
@definition = definition
|
10
|
+
end
|
11
|
+
|
12
|
+
def after_configuration
|
13
|
+
definition.docker.package_phase.add(:sqlite_dev)
|
14
|
+
definition.docker.package_phase.add(:sqlite_client)
|
15
|
+
end
|
6
16
|
end
|
7
17
|
end
|
8
18
|
end
|
9
19
|
end
|
10
20
|
end
|
21
|
+
|
22
|
+
Kuby.register_package(:sqlite_dev,
|
23
|
+
debian: 'libsqlite3-dev',
|
24
|
+
alpine: 'sqlite-dev'
|
25
|
+
)
|
26
|
+
|
27
|
+
Kuby.register_package(:sqlite_client,
|
28
|
+
debian: 'sqlite3',
|
29
|
+
alpine: 'sqlite'
|
30
|
+
)
|
@@ -3,11 +3,16 @@ require 'rake'
|
|
3
3
|
namespace :kuby do
|
4
4
|
namespace :rails_app do
|
5
5
|
namespace :db do
|
6
|
-
task rewrite_config
|
7
|
-
|
6
|
+
task :rewrite_config do
|
7
|
+
Kuby.load!
|
8
|
+
|
9
|
+
config_file = File.join(Kuby.definition.kubernetes.plugin(:rails_app).root, 'config', 'database.yml')
|
8
10
|
database = Kuby.definition.kubernetes.plugin(:rails_app).database
|
9
|
-
|
10
|
-
|
11
|
+
|
12
|
+
if database.respond_to?(:rewritten_configs)
|
13
|
+
File.write(config_file, YAML.dump(database.rewritten_configs))
|
14
|
+
Kuby.logger.info("Wrote #{config_file}")
|
15
|
+
end
|
11
16
|
end
|
12
17
|
|
13
18
|
task :create_unless_exists do
|
data/lib/kuby/kubernetes/spec.rb
CHANGED
data/lib/kuby/railtie.rb
CHANGED
@@ -7,10 +7,6 @@ module Kuby
|
|
7
7
|
load File.expand_path(File.join('tasks', 'kuby.rake'), __dir__)
|
8
8
|
end
|
9
9
|
|
10
|
-
initializer 'kuby.startup' do |_app|
|
11
|
-
Kuby.logger = Kuby::BasicLogger.new(STDERR)
|
12
|
-
end
|
13
|
-
|
14
10
|
initializer 'kuby.health_check_middleware' do |app|
|
15
11
|
app.middleware.use Kuby::Middleware::HealthCheck
|
16
12
|
end
|
data/lib/kuby/tasks.rb
CHANGED
@@ -16,6 +16,10 @@ module Kuby
|
|
16
16
|
puts formatter.format(tokens)
|
17
17
|
end
|
18
18
|
|
19
|
+
def setup
|
20
|
+
definition.kubernetes.setup
|
21
|
+
end
|
22
|
+
|
19
23
|
def build
|
20
24
|
docker.cli.build(
|
21
25
|
dockerfile: docker.to_dockerfile,
|
@@ -49,6 +53,14 @@ module Kuby
|
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
56
|
+
def deploy
|
57
|
+
definition.kubernetes.deploy
|
58
|
+
end
|
59
|
+
|
60
|
+
def rollback
|
61
|
+
definition.kubernetes.rollback
|
62
|
+
end
|
63
|
+
|
52
64
|
def print_resources
|
53
65
|
kubernetes.before_deploy
|
54
66
|
|
data/lib/kuby/tasks/kuby.rake
CHANGED
@@ -2,67 +2,68 @@ require 'shellwords'
|
|
2
2
|
|
3
3
|
namespace :kuby do
|
4
4
|
def tasks
|
5
|
+
Kuby.load!
|
5
6
|
@tasks ||= Kuby::Tasks.new(Kuby.definition)
|
6
7
|
end
|
7
8
|
|
8
|
-
task dockerfile
|
9
|
+
task :dockerfile do
|
9
10
|
tasks.print_dockerfile
|
10
11
|
end
|
11
12
|
|
12
|
-
task build
|
13
|
+
task :build do
|
13
14
|
tasks.build
|
14
15
|
end
|
15
16
|
|
16
|
-
task run
|
17
|
+
task :run do
|
17
18
|
tasks.run
|
18
19
|
end
|
19
20
|
|
20
|
-
task push
|
21
|
+
task :push do
|
21
22
|
tasks.push
|
22
23
|
end
|
23
24
|
|
24
|
-
task resources
|
25
|
+
task :resources do
|
25
26
|
tasks.print_resources
|
26
27
|
end
|
27
28
|
|
28
|
-
task :kubectl, [:cmd]
|
29
|
+
task :kubectl, [:cmd] do |_, args|
|
29
30
|
tasks.kubectl(Shellwords.shellsplit(args[:cmd]))
|
30
31
|
end
|
31
32
|
|
32
|
-
task deploy
|
33
|
-
|
33
|
+
task :deploy do
|
34
|
+
tasks.deploy
|
34
35
|
end
|
35
36
|
|
36
|
-
task rollback
|
37
|
-
|
37
|
+
task :rollback do
|
38
|
+
tasks.rollback
|
38
39
|
end
|
39
40
|
|
40
|
-
task kubeconfig
|
41
|
+
task :kubeconfig do
|
41
42
|
tasks.print_kubeconfig
|
42
43
|
end
|
43
44
|
|
44
|
-
task setup
|
45
|
-
|
45
|
+
task :setup do
|
46
|
+
tasks.setup
|
46
47
|
end
|
47
48
|
|
48
49
|
namespace :remote do
|
49
|
-
task logs
|
50
|
+
task :logs do
|
50
51
|
tasks.remote_logs
|
51
52
|
end
|
52
53
|
|
53
|
-
task status
|
54
|
+
task :status do
|
54
55
|
tasks.remote_status
|
55
56
|
end
|
56
57
|
|
57
|
-
task shell
|
58
|
+
task :shell do
|
58
59
|
tasks.remote_shell
|
59
60
|
end
|
60
61
|
|
61
|
-
task console
|
62
|
+
task :console do
|
62
63
|
tasks.remote_console
|
63
64
|
end
|
64
65
|
|
65
|
-
task dbconsole
|
66
|
+
task :dbconsole do
|
66
67
|
tasks.remote_dbconsole
|
67
68
|
end
|
68
69
|
end
|
data/lib/kuby/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kuby-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cameron Dutro
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0.
|
61
|
+
version: '0.2'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0.
|
68
|
+
version: '0.2'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: kube-dsl
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,6 +164,8 @@ files:
|
|
164
164
|
- lib/kuby/docker/debian.rb
|
165
165
|
- lib/kuby/docker/dockerfile.rb
|
166
166
|
- lib/kuby/docker/errors.rb
|
167
|
+
- lib/kuby/docker/inline_layer.rb
|
168
|
+
- lib/kuby/docker/layer.rb
|
167
169
|
- lib/kuby/docker/layer_stack.rb
|
168
170
|
- lib/kuby/docker/local_tags.rb
|
169
171
|
- lib/kuby/docker/metadata.rb
|
@@ -175,7 +177,6 @@ files:
|
|
175
177
|
- lib/kuby/docker/packages/package.rb
|
176
178
|
- lib/kuby/docker/packages/simple_managed_package.rb
|
177
179
|
- lib/kuby/docker/packages/yarn.rb
|
178
|
-
- lib/kuby/docker/phase.rb
|
179
180
|
- lib/kuby/docker/remote_tags.rb
|
180
181
|
- lib/kuby/docker/setup_phase.rb
|
181
182
|
- lib/kuby/docker/spec.rb
|
@@ -183,6 +184,7 @@ files:
|
|
183
184
|
- lib/kuby/docker/timestamp_tag.rb
|
184
185
|
- lib/kuby/docker/webserver_phase.rb
|
185
186
|
- lib/kuby/docker/yarn_phase.rb
|
187
|
+
- lib/kuby/environment.rb
|
186
188
|
- lib/kuby/kubernetes.rb
|
187
189
|
- lib/kuby/kubernetes/deploy_task.rb
|
188
190
|
- lib/kuby/kubernetes/deployer.rb
|