kuby-core 0.5.0 → 0.6.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 +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
|