kuby-core 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +16 -0
- data/LICENSE +21 -0
- data/README.md +186 -0
- data/Rakefile +14 -0
- data/kuby-core.gemspec +27 -0
- data/lib/kuby.rb +112 -0
- data/lib/kuby/basic_logger.rb +22 -0
- data/lib/kuby/cli_base.rb +75 -0
- data/lib/kuby/definition.rb +29 -0
- data/lib/kuby/docker.rb +27 -0
- data/lib/kuby/docker/alpine.rb +62 -0
- data/lib/kuby/docker/assets_phase.rb +11 -0
- data/lib/kuby/docker/bundler_phase.rb +56 -0
- data/lib/kuby/docker/cli.rb +72 -0
- data/lib/kuby/docker/copy_phase.rb +23 -0
- data/lib/kuby/docker/credentials.rb +11 -0
- data/lib/kuby/docker/debian.rb +66 -0
- data/lib/kuby/docker/dockerfile.rb +128 -0
- data/lib/kuby/docker/errors.rb +22 -0
- data/lib/kuby/docker/layer_stack.rb +42 -0
- data/lib/kuby/docker/local_tags.rb +38 -0
- data/lib/kuby/docker/metadata.rb +69 -0
- data/lib/kuby/docker/package_list.rb +34 -0
- data/lib/kuby/docker/package_phase.rb +59 -0
- data/lib/kuby/docker/packages.rb +10 -0
- data/lib/kuby/docker/packages/managed_package.rb +29 -0
- data/lib/kuby/docker/packages/nodejs.rb +29 -0
- data/lib/kuby/docker/packages/package.rb +22 -0
- data/lib/kuby/docker/packages/yarn.rb +47 -0
- data/lib/kuby/docker/phase.rb +21 -0
- data/lib/kuby/docker/remote_tags.rb +24 -0
- data/lib/kuby/docker/setup_phase.rb +29 -0
- data/lib/kuby/docker/spec.rb +147 -0
- data/lib/kuby/docker/tags.rb +39 -0
- data/lib/kuby/docker/timestamp_tag.rb +36 -0
- data/lib/kuby/docker/webserver_phase.rb +51 -0
- data/lib/kuby/docker/yarn_phase.rb +11 -0
- data/lib/kuby/kubernetes.rb +16 -0
- data/lib/kuby/kubernetes/deployer.rb +94 -0
- data/lib/kuby/kubernetes/docker_config.rb +27 -0
- data/lib/kuby/kubernetes/errors.rb +22 -0
- data/lib/kuby/kubernetes/manifest.rb +56 -0
- data/lib/kuby/kubernetes/minikube_provider.rb +51 -0
- data/lib/kuby/kubernetes/plugin.rb +55 -0
- data/lib/kuby/kubernetes/plugins.rb +8 -0
- data/lib/kuby/kubernetes/plugins/nginx_ingress.rb +61 -0
- data/lib/kuby/kubernetes/plugins/rails_app.rb +16 -0
- data/lib/kuby/kubernetes/plugins/rails_app/database.rb +58 -0
- data/lib/kuby/kubernetes/plugins/rails_app/mysql.rb +142 -0
- data/lib/kuby/kubernetes/plugins/rails_app/plugin.rb +393 -0
- data/lib/kuby/kubernetes/plugins/rails_app/postgres.rb +10 -0
- data/lib/kuby/kubernetes/plugins/rails_app/rewrite_db_config.rb +13 -0
- data/lib/kuby/kubernetes/plugins/rails_app/sqlite.rb +10 -0
- data/lib/kuby/kubernetes/plugins/rails_app/tasks.rake +23 -0
- data/lib/kuby/kubernetes/provider.rb +77 -0
- data/lib/kuby/kubernetes/registry_secret.rb +26 -0
- data/lib/kuby/kubernetes/spec.rb +152 -0
- data/lib/kuby/middleware.rb +5 -0
- data/lib/kuby/middleware/health_check.rb +16 -0
- data/lib/kuby/railtie.rb +18 -0
- data/lib/kuby/tasks.rb +135 -0
- data/lib/kuby/tasks/kuby.rake +63 -0
- data/lib/kuby/trailing_hash.rb +19 -0
- data/lib/kuby/version.rb +3 -0
- metadata +233 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5ecf6df1172c327a682b1db7ea6ef1b0d9df936f9ae3599f09a548ebdad20980
|
4
|
+
data.tar.gz: ebb10f441864a243a61ac493594461d4c5c6223f82f063ca0c58f2ba2bb97aba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 432a5cfc254e69243a4a8c6009592b67aec84a77b91db62ec64496fca0d858fec4ee167d6995eded577ad96511eafb3eaa96e2993a8913167d301fae6b9534ce
|
7
|
+
data.tar.gz: 36df0acb5eca66ad07dea436f34434a61a6a841c8c84503af72d3222e18325224b648ae0828091dcd09344e41a22436b26013b51a45a4d16309f02b2409b0f32
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem 'kube-dsl', path: '../kube-dsl'
|
6
|
+
gem 'kuby-kube-db', path: '../kuby-kube-db'
|
7
|
+
gem 'kuby-cert-manager', path: '../kuby-cert-manager'
|
8
|
+
|
9
|
+
group :development, :test do
|
10
|
+
gem 'pry-byebug'
|
11
|
+
gem 'rake'
|
12
|
+
end
|
13
|
+
|
14
|
+
group :test do
|
15
|
+
gem 'rspec', '~> 3.0'
|
16
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Cameron Dutro
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
## Kuby
|
2
|
+
|
3
|
+
Deploy your Rails app the easy way.
|
4
|
+
|
5
|
+
## What is Kuby?
|
6
|
+
|
7
|
+
At its core, Kuby is a set of tools and smart defaults that encapsulate and codify years of established best-practices around deploying webapps, reducing the amount of time required to take your Rails project from an app that runs on your computer to an app that runs on the Internet.
|
8
|
+
|
9
|
+
Under the hood, Kuby leverages the power of Docker and Kubernetes. It tries to make these technologies accessible to the average Rails dev without requiring a devops black belt.
|
10
|
+
|
11
|
+
## Raison d'etre
|
12
|
+
|
13
|
+
One of Rails' most notorious mantras is "convention over configuration," i.e. sane defaults that limit the cognitive overhead of application development. Rails has survived for as long as it has precisely because it makes so many decisions for you, especially compared to other web application frameworks. It's easy to learn and easy to build with. The development experience is fantastic... right up until the point you want to deploy your app to production. It's at that point that the hand-holding stops. Like the Roadrunner, Rails stops right before the cliff and lets you, Wile E. Coyote, sail over the edge.
|
14
|
+
|
15
|
+
![Wile E. Coytote](coyote.jpg)
|
16
|
+
|
17
|
+
Perhaps [Stefan Wintermeyer](https://twitter.com/wintermeyer) said it best during his appearance on the Ruby Rogues podcast, [episode 403](https://devchat.tv/ruby-rogues/rr-403-rails-needs-active-deployment-with-stefan-wintermeyer/):
|
18
|
+
|
19
|
+
> "In my experience, deployment is one of the major problems of normal Rails users. It is a big pain to set up a deployment system for a Rails application, and I don't see anything out there that makes it easier. [...] I believe that we lose quite a lot of companies and new developers on this step. Because everything else [is] so much easier with Rails. But that last step - and it's a super important step - is still super complicated."
|
20
|
+
|
21
|
+
## Docker and Kubernetes
|
22
|
+
|
23
|
+
Why bet the farm on Docker and Kubernetes?
|
24
|
+
|
25
|
+
### Docker
|
26
|
+
|
27
|
+
When Docker came on the scene in 2013 it was seen as a game-changer. Applications that used to be deployed onto hand-provisioned servers can now be bundled up into neat little packages and transferred between computers in their entirety. Since the whole application - dependencies, operating system components, assets, code, etc - can be passed around as a single artifact, Docker images curtail the need for manually provisioned servers and eliminate a whole class of "works on my machine" problems.
|
28
|
+
|
29
|
+
### Kubernetes
|
30
|
+
|
31
|
+
Kubernetes has taken the ops world by storm. It's resilient to failure, portable across a variety of cloud providers, and backed by industry-leading organizations like the CNCF. Kubernetes configuration is portable enough to be used, without modification, on just about any Kubernetes cluster, making migrations not only feasible, but easy. Many cloud providers like Google GCP, Amazon AWS, Microsoft Azure, DigitalOcean, and Linode support Kubernetes. Most of these providers will manage the Kubernetes cluster for you, and in some cases will even provide it free of charge (you pay only for the compute resources).
|
32
|
+
|
33
|
+
## Getting Started
|
34
|
+
|
35
|
+
NOTE: Kuby is designed to work with Rails 5.2 and up.
|
36
|
+
|
37
|
+
### Choosing a Provider
|
38
|
+
|
39
|
+
The first step in deploying your app is to choose a hosting provider. At the time of this writing, Kuby supports DigitalOcean and Linode, but support for more providers is coming soon. Use your provider's dashboard to spin up a Kubernetes cluster. In most cases, this shouldn't involve more than a few button clicks.
|
40
|
+
|
41
|
+
### The Container Registry
|
42
|
+
|
43
|
+
Kuby uses Docker to package up your application into a Docker _image_. Images are then pushed (i.e. uploaded) to something called a "container registry." Container registries host Docker images so they can be pulled (i.e. downloaded) later.
|
44
|
+
|
45
|
+
Although there are a number of container registries available (some free and some paid), consider using the Gitlab registry. Gitlab's registry is free and unlimited. You don't have to host your code on Gitlab to take advantage of the registry, but they're great for that too.
|
46
|
+
|
47
|
+
### Integrating Kuby
|
48
|
+
|
49
|
+
Kuby configuration is done via a [DSL](https://en.wikipedia.org/wiki/Domain-specific_language). There are two main sections, one for Docker and one for Kubernetes. Put the config into a Rails initializer, eg. config/initializers/kuby.rb.
|
50
|
+
|
51
|
+
Here's what a complete config looks like:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
Kuby.define(:production) do
|
55
|
+
docker do
|
56
|
+
credentials do
|
57
|
+
username ENV['DOCKER_USERNAME']
|
58
|
+
password ENV['DOCKER_PASSWORD']
|
59
|
+
email ENV['DOCKER_EMAIL']
|
60
|
+
end
|
61
|
+
|
62
|
+
image_url 'registry.gitlab.com/username/repo'
|
63
|
+
end
|
64
|
+
|
65
|
+
kubernetes do
|
66
|
+
provider :digitalocean do
|
67
|
+
access_token ENV['DIGITALOCEAN_ACCESS_TOKEN']
|
68
|
+
cluster_id 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
|
69
|
+
end
|
70
|
+
|
71
|
+
add_plugin :rails_app do
|
72
|
+
hostname 'mywebsite.com'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
Let's go over this config in detail.
|
79
|
+
|
80
|
+
### Deploy Environments
|
81
|
+
|
82
|
+
The first line defines the _deploy environment_:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
Kuby.define(:production)
|
86
|
+
```
|
87
|
+
|
88
|
+
Deploy environments usually closely mirror your Rails environments. For example, you might create a new Rails environment called "staging" or "preprod" that's used to test production changes before they go live. You'll want to create a "staging" Kuby deploy environment as well.
|
89
|
+
|
90
|
+
If you're a small shop or hobbyist though, chances are the "production" deploy environment is all you need.
|
91
|
+
|
92
|
+
### Configuring Docker
|
93
|
+
|
94
|
+
Kuby can automatically "dockerize" your application. You just need to tell it where to push images and provide some credentials:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
docker do
|
98
|
+
credentials do
|
99
|
+
username ENV['DOCKER_USERNAME']
|
100
|
+
password ENV['DOCKER_PASSWORD']
|
101
|
+
email ENV['DOCKER_EMAIL']
|
102
|
+
end
|
103
|
+
|
104
|
+
image_url 'registry.gitlab.com/username/repo'
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
The username, password, and email fields are used to authenticate with the Docker registry that hosts your images. For Gitlab, you'll need to create a [personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) instead of your password. The `image_url` field is the full URL to your image, including the registry's domain.
|
109
|
+
|
110
|
+
In the example above, the username, password, and email are all provided as environment variables. **NEVER** hard-code sensitive information like this in your Kuby config or check it into source control (i.e. git). Consider using a tool like [dotenv](https://github.com/bkeepers/dotenv) to automatically load the variables from a file when your app starts (NOTE: don't check the .env file into git either!)
|
111
|
+
|
112
|
+
### Configuring Kubernetes
|
113
|
+
|
114
|
+
Now that your app can be packaged up into a Docker image, it's time to use Kubernetes to run it. There are two top-level concerns in the Kubernetes section of your Kuby config: providers and plugins.
|
115
|
+
|
116
|
+
#### Providers
|
117
|
+
|
118
|
+
Each Kubernetes definition must have a provider configured. Providers correspond to the hosting provider you chose earlier. For example, you'll need to add the `:digitalocean` provider to deploy to a managed DigitalOcean Kubernetes cluster.
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
kubernetes do
|
122
|
+
provider :digitalocean do
|
123
|
+
access_token ENV['DIGITALOCEAN_ACCESS_TOKEN']
|
124
|
+
cluster_id 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
Kuby providers are distributed as individual rubygems. Add the one you need to your Gemfile, for example:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
gem 'kuby-digitalocean', '~> 0.1'
|
133
|
+
```
|
134
|
+
|
135
|
+
Providers can have different config options, so make sure you consult the gem's README for the provider you've chosen.
|
136
|
+
|
137
|
+
#### Plugins
|
138
|
+
|
139
|
+
Nearly all Kuby's functionality is provided via plugins. For example, simply add the `:rails_app` plugin to get your Rails app ready to deploy:
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
add_plugin :rails_app
|
143
|
+
```
|
144
|
+
|
145
|
+
To indicate your app exists behind a particular domain name, specify the `hostname` option:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
add_plugin :rails_app do
|
149
|
+
hostname 'mywebsite.com'
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
153
|
+
Configuring DNS to point to your Kubernetes cluster is outside the scope of this README, but all the hosting providers should have tutorials. For example, [here's the one](https://www.digitalocean.com/community/tutorials/how-to-point-to-digitalocean-nameservers-from-common-domain-registrars) from DigitalOcean.
|
154
|
+
|
155
|
+
## Deploying
|
156
|
+
|
157
|
+
Now that Kuby is configured and your Kubernetes cluster is ready, it's time to deploy!
|
158
|
+
|
159
|
+
1. Build the Docker image
|
160
|
+
|
161
|
+
```sh
|
162
|
+
bundle exec rake kuby:build
|
163
|
+
```
|
164
|
+
1. Push the Docker image to the container registry
|
165
|
+
|
166
|
+
```sh
|
167
|
+
bundle exec rake kuby:push
|
168
|
+
```
|
169
|
+
1. Deploy!
|
170
|
+
|
171
|
+
```sh
|
172
|
+
bundle exec rake kuby:deploy
|
173
|
+
```
|
174
|
+
1. Rejoice
|
175
|
+
|
176
|
+
## Running Tests
|
177
|
+
|
178
|
+
`bundle exec rspec` should do the trick... or at least it would if there were any tests. Don't worry, it's on my radar.
|
179
|
+
|
180
|
+
## License
|
181
|
+
|
182
|
+
Licensed under the MIT license. See LICENSE for details.
|
183
|
+
|
184
|
+
## Authors
|
185
|
+
|
186
|
+
* Cameron C. Dutro: http://github.com/camertron
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
|
5
|
+
require 'kuby'
|
6
|
+
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
9
|
+
task default: :spec
|
10
|
+
|
11
|
+
desc 'Run specs'
|
12
|
+
RSpec::Core::RakeTask.new do |t|
|
13
|
+
t.pattern = './spec/**/*_spec.rb'
|
14
|
+
end
|
data/kuby-core.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
|
+
require 'kuby/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'kuby-core'
|
6
|
+
s.version = ::Kuby::VERSION
|
7
|
+
s.authors = ['Cameron Dutro']
|
8
|
+
s.email = ['camertron@gmail.com']
|
9
|
+
s.homepage = 'http://github.com/getkuby/kuby-core'
|
10
|
+
|
11
|
+
s.description = s.summary = 'Deploy your Rails app onto Kubernetes the easy way.'
|
12
|
+
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
|
15
|
+
s.add_dependency 'colorize', '~> 0.8'
|
16
|
+
s.add_dependency 'docker-remote', '~> 0.1'
|
17
|
+
s.add_dependency 'krane', '~> 1.0'
|
18
|
+
s.add_dependency 'kuby-cert-manager', '~> 0.1'
|
19
|
+
s.add_dependency 'kube-dsl', '~> 0.1'
|
20
|
+
s.add_dependency 'kuby-kube-db', '~> 0.1'
|
21
|
+
s.add_dependency 'kubernetes-cli', '~> 0.1'
|
22
|
+
s.add_dependency 'railties', '~> 6.0'
|
23
|
+
s.add_dependency 'rouge', '~> 3.0'
|
24
|
+
|
25
|
+
s.require_path = 'lib'
|
26
|
+
s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'LICENSE', 'CHANGELOG.md', 'README.md', 'Rakefile', 'kuby-core.gemspec']
|
27
|
+
end
|
data/lib/kuby.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'kuby/railtie'
|
2
|
+
|
3
|
+
module Kuby
|
4
|
+
autoload :BasicLogger, 'kuby/basic_logger'
|
5
|
+
autoload :CLIBase, 'kuby/cli_base'
|
6
|
+
autoload :Definition, 'kuby/definition'
|
7
|
+
autoload :Docker, 'kuby/docker'
|
8
|
+
autoload :Kubernetes, 'kuby/kubernetes'
|
9
|
+
autoload :Middleware, 'kuby/middleware'
|
10
|
+
autoload :Tasks, 'kuby/tasks'
|
11
|
+
autoload :TrailingHash, 'kuby/trailing_hash'
|
12
|
+
|
13
|
+
class UndefinedEnvironmentError < StandardError; end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_reader :definition
|
17
|
+
attr_accessor :logger
|
18
|
+
|
19
|
+
def define(environment, app = Rails.application, &block)
|
20
|
+
environment = environment.to_s
|
21
|
+
definitions[environment] ||= Definition.new(environment, app, &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def definitions
|
25
|
+
@definitions ||= {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def definition(environment = env)
|
29
|
+
definitions.fetch(environment.to_s) do
|
30
|
+
raise UndefinedEnvironmentError, "couldn't find a Kuby environment named "\
|
31
|
+
"'#{environment}'"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def register_provider(provider_name, provider_klass)
|
36
|
+
providers[provider_name] = provider_klass
|
37
|
+
end
|
38
|
+
|
39
|
+
def providers
|
40
|
+
@providers ||= {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def register_plugin(plugin_name, plugin_klass)
|
44
|
+
plugins[plugin_name] = plugin_klass
|
45
|
+
end
|
46
|
+
|
47
|
+
def register_distro(distro_name, distro_klass)
|
48
|
+
distros[distro_name] = distro_klass
|
49
|
+
end
|
50
|
+
|
51
|
+
def distros
|
52
|
+
@distros ||= {}
|
53
|
+
end
|
54
|
+
|
55
|
+
def plugins
|
56
|
+
@plugins ||= {}
|
57
|
+
end
|
58
|
+
|
59
|
+
def register_package(package_name, package_def)
|
60
|
+
packages[package_name] = case package_def
|
61
|
+
when String
|
62
|
+
Kuby::Docker::Packages::ManagedPackage.new(
|
63
|
+
package_name, debian: package_def, alpine: package_def
|
64
|
+
)
|
65
|
+
when Hash
|
66
|
+
Kuby::Docker::Packages::ManagedPackage.new(
|
67
|
+
package_name, package_def
|
68
|
+
)
|
69
|
+
else
|
70
|
+
package_def.new(package_name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def packages
|
75
|
+
@packages ||= {}
|
76
|
+
end
|
77
|
+
|
78
|
+
def env
|
79
|
+
ENV.fetch('KUBY_ENV') do
|
80
|
+
(definitions.keys.first || Rails.env).to_s
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# providers
|
87
|
+
Kuby.register_provider(:minikube, Kuby::Kubernetes::MinikubeProvider)
|
88
|
+
|
89
|
+
# plugins
|
90
|
+
Kuby.register_plugin(:rails_app, Kuby::Kubernetes::Plugins::RailsApp::Plugin)
|
91
|
+
Kuby.register_plugin(:nginx_ingress, Kuby::Kubernetes::Plugins::NginxIngress)
|
92
|
+
|
93
|
+
# distros
|
94
|
+
Kuby.register_distro(:debian, Kuby::Docker::Debian)
|
95
|
+
Kuby.register_distro(:alpine, Kuby::Docker::Alpine)
|
96
|
+
|
97
|
+
# packages
|
98
|
+
Kuby.register_package(:nodejs, Kuby::Docker::Packages::Nodejs)
|
99
|
+
Kuby.register_package(:yarn, Kuby::Docker::Packages::Yarn)
|
100
|
+
|
101
|
+
Kuby.register_package(:ca_certificates, 'ca-certificates')
|
102
|
+
Kuby.register_package(:tzdata, 'tzdata')
|
103
|
+
|
104
|
+
Kuby.register_package(:c_toolchain,
|
105
|
+
debian: 'build-essential',
|
106
|
+
alpine: 'build-base'
|
107
|
+
)
|
108
|
+
|
109
|
+
Kuby.register_package(:sqlite_dev,
|
110
|
+
debian: 'libsqlite3-dev',
|
111
|
+
alpine: 'sqlite-dev'
|
112
|
+
)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'colorized_string'
|
3
|
+
|
4
|
+
module Kuby
|
5
|
+
class BasicLogger < Logger
|
6
|
+
def initialize(*args)
|
7
|
+
super
|
8
|
+
|
9
|
+
self.formatter = proc do |_severity, _datetime, _progname, msg|
|
10
|
+
"#{msg}\n"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def info(msg, *args)
|
15
|
+
super(ColorizedString[msg].yellow, *args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def fatal(msg, *args)
|
19
|
+
super(ColorizedString[msg].red, *args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module Kuby
|
5
|
+
class CLIBase
|
6
|
+
def last_status
|
7
|
+
Thread.current[status_key]
|
8
|
+
end
|
9
|
+
|
10
|
+
def before_execute(&block)
|
11
|
+
@before_execute ||= []
|
12
|
+
@before_execute << block
|
13
|
+
end
|
14
|
+
|
15
|
+
def after_execute(&block)
|
16
|
+
@after_execute ||= []
|
17
|
+
@after_execute << block
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def open3_w(env, cmd, opts = {}, &block)
|
23
|
+
run_before_callbacks(cmd)
|
24
|
+
cmd_s = cmd.join(' ')
|
25
|
+
|
26
|
+
Open3.pipeline_w([env, cmd_s], opts) do |stdin, wait_threads|
|
27
|
+
yield(stdin, wait_threads).tap do
|
28
|
+
stdin.close
|
29
|
+
self.last_status = wait_threads.last.value
|
30
|
+
run_after_callbacks(cmd)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def execc(cmd)
|
36
|
+
run_before_callbacks(cmd)
|
37
|
+
cmd_s = cmd.join(' ')
|
38
|
+
exec(cmd_s)
|
39
|
+
end
|
40
|
+
|
41
|
+
def systemm(cmd)
|
42
|
+
run_before_callbacks(cmd)
|
43
|
+
cmd_s = cmd.join(' ')
|
44
|
+
system(cmd_s).tap do
|
45
|
+
self.last_status = $?
|
46
|
+
run_after_callbacks(cmd)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def backticks(cmd)
|
51
|
+
run_before_callbacks(cmd)
|
52
|
+
cmd_s = cmd.join(' ')
|
53
|
+
`#{cmd_s}`.tap do
|
54
|
+
self.last_status = $?
|
55
|
+
run_after_callbacks(cmd)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def run_before_callbacks(cmd)
|
60
|
+
(@before_execute || []).each { |cb| cb.call(cmd) }
|
61
|
+
end
|
62
|
+
|
63
|
+
def run_after_callbacks(cmd)
|
64
|
+
(@after_execute || []).each { |cb| cb.call(cmd, last_status) }
|
65
|
+
end
|
66
|
+
|
67
|
+
def last_status=(status)
|
68
|
+
Thread.current[status_key] = status
|
69
|
+
end
|
70
|
+
|
71
|
+
def status_key
|
72
|
+
raise NotImplementedError, "#{__method__} must be defined in derived classes"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|