keel 0.1.2 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ae5771e28c49313b1b90d71a280c481c0268de00
4
- data.tar.gz: 85969874e3bd3d217946c1a62058b91ffb2b09ff
3
+ metadata.gz: 3837deed0bba2d9618d452af738a4dca69c109e5
4
+ data.tar.gz: a069e3ba4d3bf4035b49d98ec60369f54b5a2669
5
5
  SHA512:
6
- metadata.gz: a580124ef47f0ddc0f9cc723dcea47f273020d606d60a60402fa6488ce062ba8a1c264c710f801f5a51d300fe56119b8214dfadae01a4aeb50680f81705220c0
7
- data.tar.gz: dca6f0cfc23daf0c9dc4aa56d62189647b4bd66ad7f9b7cac798ea136a47533bd8b6858da180854a2a4e0b88c8a330054da61a143795a410cb2b1360a2e67165
6
+ metadata.gz: 55344a32cc6baf594e379ce440e00317435fb0e0e53d54276a1030604c2b3145c6ddb63863c012b5bdd648161dc5586a8d85728975a7fad9a818f28d846df064
7
+ data.tar.gz: 73c7f65984d998f7b177263321c6504e22c9b4b3afd5ca2f67d45393ea89bea8f517ce883d95778f3619fcb2d5fa11c24ad738fc75088ccc3cc126dfee81552b
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.5
data/README.md CHANGED
@@ -106,6 +106,11 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
106
106
 
107
107
  Bug reports and pull requests are welcome on GitHub at https://github.com/o19s/keel. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
108
108
 
109
+ ## Contributors
110
+
111
+ * [Chris Bradford](https://github.com/bradfordcp) did the original work
112
+ * [Youssef Chaker](https://github.com/ychaker) extracted out the gem
113
+ * [Matt Overstreet](https://github.com/omnifroodle) added support for kubernetes deployments
109
114
 
110
115
  ## License
111
116
 
data/circle.yml ADDED
@@ -0,0 +1,7 @@
1
+ machine:
2
+ ruby:
3
+ version: 2.2.3
4
+ dependencies:
5
+ pre:
6
+ - echo Y | rvm @global do gem uninstall bundler
7
+ - gem install bundler -v '1.11'
@@ -7,6 +7,7 @@ module Keel
7
7
 
8
8
  def copy_config
9
9
  copy_file "gcloud.yml", "config/gcloud.yml"
10
+ copy_file "Dockerfile", "Dockerfile"
10
11
  end
11
12
  end
12
13
  end
@@ -1,3 +1,4 @@
1
+ # TODO, kill these and their templates
1
2
  module Keel
2
3
  module Generators
3
4
  class ControllerGenerator < ::Rails::Generators::Base
@@ -1,3 +1,4 @@
1
+ # TODO, kill these and their templates
1
2
  module Keel
2
3
  module Generators
3
4
  class ServiceGenerator < ::Rails::Generators::Base
@@ -0,0 +1 @@
1
+ FROM rails:onbuild
@@ -0,0 +1,13 @@
1
+ module Keel::Docker
2
+ class Image
3
+ def self.create(label, project_id, app_name)
4
+ command = "docker build -t gcr.io/#{project_id}/#{app_name}:#{label} ."
5
+ Keel::GCloud::Cli.new.execute(command)
6
+ end
7
+
8
+ def self.push(label, project_id, app_name)
9
+ command = "gcloud docker push gcr.io/#{project_id}/#{app_name}:#{label}"
10
+ Keel::GCloud::Cli.new.execute(command)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1 @@
1
+ require_relative 'docker/image'
@@ -1,3 +1,4 @@
1
+ require 'open3'
1
2
  module Keel::GCloud
2
3
  #
3
4
  # A helper class to run system commands and handle interrupts.
@@ -5,7 +6,17 @@ module Keel::GCloud
5
6
  class Cli
6
7
  def execute command
7
8
  begin
8
- `#{command}`
9
+ out = ""
10
+ Open3.popen3(command) do |stdout, stderr, stdin, thread|
11
+ # TODO do smarter things with status and stdout
12
+ while line=stderr.gets do
13
+ out += line
14
+ print '.'
15
+ end
16
+ print "\n"
17
+ raise "error while processing. " + out unless thread.value.success?
18
+ return out
19
+ end
9
20
  rescue Interrupt
10
21
  puts 'Task interrupted.'
11
22
  end
@@ -0,0 +1,41 @@
1
+ module Keel::GCloud
2
+ #
3
+ # A helper for prompts that integrate other services
4
+ #
5
+ class Interactions
6
+ @@namespace = nil
7
+ @@label = nil
8
+
9
+ #
10
+ # Prompts for the deployment namespace if there are multiple available and one has
11
+ # not been already chosen
12
+ #
13
+ # @param namespace [String] the default option to present for the namespace
14
+ #
15
+ def self.pick_namespace(namespace)
16
+ unless @@namespace
17
+ prompter = Keel::GCloud::Prompter.new
18
+ namespaces = Keel::GCloud::Kubernetes::Namespace.fetch_all
19
+ unless namespaces
20
+ message = 'Unable to connect to Kubernetes, please try again later...'
21
+ prompter.print message, :error
22
+ abort
23
+ end
24
+ @@namespace = prompter.prompt_for_namespace namespaces, namespace
25
+ end
26
+ @@namespace
27
+ end
28
+
29
+ #
30
+ # Prompts for a Docker image label if one has not already been selected
31
+ #
32
+ # @params label [String] the default value to present to the user
33
+ def self.pick_image_label(label)
34
+ unless @@label
35
+ prompter = Keel::GCloud::Prompter.new
36
+ @@label = prompter.prompt_for_label label
37
+ end
38
+ @@label
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,34 @@
1
+ module Keel::GCloud
2
+ module Kubernetes
3
+ #
4
+ # A class to represent a Kubernetes Deployment
5
+ class Deployment < ReplicationController
6
+
7
+ #
8
+ # Fetches the correct deployment or replication controller from Kubernetes.
9
+ #
10
+ # @param env [String] the namespace/environment for which to fetch the controllers
11
+ # @param app [String] the app for which to fetch the controllers
12
+ # @return [Hash] the parsed result of the API call
13
+ #
14
+ def self.fetch_all env, app
15
+ command = "kubectl get deployment --namespace=#{env} -l app=#{app} -o yaml"
16
+ rcs_yaml = YAML.load Cli.new.execute(command)
17
+ return false unless rcs_yaml["items"].count > 0
18
+ self.from_yaml rcs_yaml
19
+ end
20
+
21
+ #
22
+ # Create a Deployment and expose it on kubernetes
23
+ #
24
+ def self.create app_name, image_path, port, sha, namespace
25
+ cli = Cli.new
26
+ deploy_command = "kubectl run #{app_name} --image=#{image_path}:#{sha} --namespace=#{namespace}"
27
+ expose_command = "kubectl expose deployment #{app_name} --port=80 --target-port=#{port} --type=LoadBalancer --namespace=#{namespace}"
28
+ cli.execute(deploy_command)
29
+ cli.execute(expose_command)
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -35,24 +35,22 @@ module Keel::GCloud
35
35
  original: item,
36
36
  uid: item['metadata']['uid'],
37
37
  }
38
-
39
38
  self.new params
40
39
  end
41
40
  end
42
41
 
43
42
  #
44
- # Fetches all the controllers from Kubernetes.
43
+ # Fetches the correct deployment or replication controller from Kubernetes.
45
44
  #
46
45
  # @param env [String] the namespace/environment for which to fetch the controllers
47
46
  # @param app [String] the app for which to fetch the controllers
48
47
  # @return [Hash] the parsed result of the API call
49
48
  #
50
49
  def self.fetch_all env, app
51
- command = "kubectl get rc --namespace=#{env} -l app=#{app} -o yaml"
52
- rcs_yaml = YAML.load Cli.new.execute(command)
53
- return false unless rcs_yaml
54
-
55
- self.from_yaml rcs_yaml
50
+ command = "kubectl get rc --namespace=#{env} -l app=#{app} -o yaml"
51
+ rcs_yaml = YAML.load Cli.new.execute(command)
52
+ return false unless rcs_yaml["items"].count > 0
53
+ self.from_yaml rcs_yaml
56
54
  end
57
55
 
58
56
  #
@@ -1,3 +1,4 @@
1
1
  require_relative 'kubernetes/namespace'
2
2
  require_relative 'kubernetes/replication_controller'
3
+ require_relative 'kubernetes/deployment'
3
4
  require_relative 'kubernetes/pod'
@@ -35,23 +35,27 @@ module Keel::GCloud
35
35
  def prompt_for_namespace namespaces, default=nil
36
36
  return default unless default.blank?
37
37
 
38
- options = namespaces.map { |namespace| namespace.name }
39
- index = Ask.list 'Please choose an environment (destination)', options
40
- options[index]
38
+ options = namespaces.map { |namespace| namespace.name } - ['kube-system']
39
+ if options.count > 1
40
+ index = Ask.list 'Please choose an environment (destination)', options
41
+ options[index]
42
+ else
43
+ options[0]
44
+ end
41
45
  end
42
46
 
43
47
  #
44
- # Prompts the user to provide a SHA.
48
+ # Prompts the user to provide a label. Defaults to the current git branch shortened SHA.
45
49
  # If a default is provided it returns that instead.
46
50
  #
47
51
  # @param default [String, nil] the default choice
48
52
  #
49
- def prompt_for_sha default=nil
53
+ def prompt_for_label default=nil
50
54
  return default unless default.blank?
51
55
 
52
56
  # Get current git SHA
53
57
  current_sha = `git rev-parse --short HEAD`.lines.first.split(' ')[0]
54
- Ask.input 'Git SHA', default: current_sha
58
+ Ask.input 'Image Label (defaults to Git SHA)', default: current_sha
55
59
  end
56
60
 
57
61
  #
data/lib/keel/gcloud.rb CHANGED
@@ -4,3 +4,4 @@ require_relative 'gcloud/component'
4
4
  require_relative 'gcloud/config'
5
5
  require_relative 'gcloud/kubernetes'
6
6
  require_relative 'gcloud/prompter'
7
+ require_relative 'gcloud/interactions'
data/lib/keel/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Keel
2
- VERSION = "0.1.2" # :nodoc:
2
+ VERSION = "0.1.5" # :nodoc:
3
3
  end
data/lib/keel.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'keel/version'
2
2
  require 'keel/railtie' if defined?(Rails)
3
3
  require 'keel/gcloud'
4
+ require 'keel/docker'
4
5
  require 'keel/notifier'
5
6
 
6
7
  # {file:README.md Usage#usage}
data/lib/tasks/keel.rake CHANGED
@@ -1,24 +1,57 @@
1
1
  namespace :keel do
2
- desc 'Deploy the specified SHA to a given environment'
3
- task :deploy, [:environment, :deploy_sha] do |_, args|
4
- prompter = Keel::GCloud::Prompter.new
5
- config = Keel::GCloud::Config.new
6
- app = config.app_name
2
+ config = Keel::GCloud::Config.new
3
+ prompter = Keel::GCloud::Prompter.new
4
+
5
+ desc "build a docker image suitable for pushing"
6
+ task :pack, [:deploy_sha] do |_, args|
7
+ prompter.print 'Building Docker image', :info
8
+ image_label = Keel::GCloud::Interactions.pick_image_label args[:deploy_sha]
9
+ Keel::Docker::Image.create image_label, config.project_id, config.app_name
10
+ prompter.print 'finished build', :info
11
+ end
7
12
 
8
- # Fetch namespaces from k8s
9
- namespaces = Keel::GCloud::Kubernetes::Namespace.fetch_all
10
- unless namespaces
11
- message = 'Unable to connect to Kubernetes, please try again later...'
12
- prompter.print message, :error
13
- abort
13
+ desc "ship the image to gcloud"
14
+ task :push, [:deploy_sha] do |_, args|
15
+ prompter.print 'Pushing image to Docker repository, this may take some time', :info
16
+ image_label = Keel::GCloud::Interactions.pick_image_label args[:deploy_sha]
17
+ Keel::Docker::Image.push image_label, config.project_id, config.app_name
18
+ prompter.print 'finished push', :info
19
+ end
20
+
21
+ desc "provision a deployment and service on kubernetes"
22
+ task :provision, [:deploy_sha] do |_, args|
23
+ image_label = Keel::GCloud::Interactions.pick_image_label args[:deploy_sha]
24
+ deploy_env = Keel::GCloud::Interactions.pick_namespace args[:environment]
25
+
26
+ # Retrieve a replication controller configuration from the cluster
27
+ rcs = Keel::GCloud::Kubernetes::ReplicationController.fetch_all deploy_env, config.app_name
28
+ if rcs
29
+ message = "Found an existing deployment or replication controller for #{config.app_name}"
30
+ prompter.print message, :success
31
+ else
32
+ message = Keel::GCloud::Kubernetes::ReplicationController.create config.app_name, config.container_app_image_path, "3000", image_label, deploy_env
33
+ prompter.print message, :success
14
34
  end
35
+ end
15
36
 
16
- # Prompt the user for the env and git commit to deploy
17
- deploy_env = prompter.prompt_for_namespace namespaces, args[:environment]
18
- deploy_sha = prompter.prompt_for_sha args[:deploy_sha]
37
+ task :shipit, [:deploy_sha] => [:set_gcloud_properties,
38
+ :pack,
39
+ :push,
40
+ :provision,
41
+ :deploy] do |_, args|
42
+ prompter.print "packed, pushed, provisioned and deployed #{config.app_name}!", :success
43
+ end
44
+
45
+ desc 'Deploy the specified SHA to a given environment'
46
+ task :deploy, [:environment, :deploy_sha] do |_, args|
47
+ app = config.app_name
48
+ deploy_sha = Keel::GCloud::Interactions.pick_image_label args[:deploy_sha]
49
+ deploy_env = Keel::GCloud::Interactions.pick_namespace args[:environment]
50
+ #rc_type = :replication_controller
19
51
 
20
52
  # Retrieve a replication controller configuration from the cluster
21
- rcs = Keel::GCloud::Kubernetes::ReplicationController.fetch_all deploy_env, app
53
+ rcs = Keel::GCloud::Kubernetes::ReplicationController.fetch_all(deploy_env, app) || Keel::GCloud::Kubernetes::Deployment.fetch_all(deploy_env, app)
54
+
22
55
  unless rcs
23
56
  message = 'Unable to connect to Kubernetes, please try again later...'
24
57
  prompter.print message, :error
@@ -34,54 +67,60 @@ namespace :keel do
34
67
 
35
68
  # Prep deployment:
36
69
  # 1. Update image
37
- # 2. Update replica count
38
- # 3. Write out to a tmp file
39
- # 4. Replace the running controller
40
- # - this will create 1 new pod with the updated code
41
-
42
- # We can get away with first since it is a single container pod
43
70
  container = rc.containers.first
44
71
  container['image'] = "#{config.container_app_image_path}:#{deploy_sha}"
45
- rc.increment_replica_count
46
- rc.update
47
72
 
48
- # Get a list of pods for the RC, this must be done pre-change
49
- pods = Keel::GCloud::Kubernetes::Pod.fetch_all deploy_env, app
50
- unless pods
51
- message = 'Unable to connect to Kubernetes, please try again later...'
52
- prompter.print message, :error
53
- abort
54
- end
73
+ if rc.is_a? Keel::GCloud::Kubernetes::Deployment
74
+ rc.update
75
+ else
76
+ # Additionally for replication controllers
77
+ # 2. Update replica count
78
+ # 3. Write out to a tmp file
79
+ # 4. Replace the running controller
80
+ # - this will create 1 new pod with the updated code
81
+
82
+ # We can get away with first since it is a single container pod
83
+
84
+ rc.increment_replica_count
85
+ rc.update
86
+
87
+ # Get a list of pods for the RC, this must be done pre-change
88
+ pods = Keel::GCloud::Kubernetes::Pod.fetch_all deploy_env, app
89
+ unless pods
90
+ message = 'Unable to connect to Kubernetes, please try again later...'
91
+ prompter.print message, :error
92
+ abort
93
+ end
55
94
 
56
- # Iterate over all pods, checking to see if they are running
57
- all_pods_running = false
58
- while !all_pods_running do
59
- prompter.print 'Waiting for new pods to start', :info
60
- sleep 5
61
- new_pods = Keel::GCloud::Kubernetes::Pod.fetch_all deploy_env, app
62
-
63
- all_pods_running = true
64
- new_pods.each do |pod|
65
- if !pod.running?
66
- prompter.print "Pod \"#{pod.name}\" is not running", :info
67
- all_pods_running = false
95
+ # Iterate over all pods, checking to see if they are running
96
+ all_pods_running = false
97
+ while !all_pods_running do
98
+ prompter.print 'Waiting for new pods to start', :info
99
+ sleep 5
100
+ new_pods = Keel::GCloud::Kubernetes::Pod.fetch_all deploy_env, app
101
+
102
+ all_pods_running = true
103
+ new_pods.each do |pod|
104
+ if !pod.running?
105
+ prompter.print "Pod \"#{pod.name}\" is not running", :info
106
+ all_pods_running = false
107
+ end
68
108
  end
69
109
  end
70
- end
71
-
72
- # Nuke old pods
73
- pods.each do |pod|
74
- pod.delete
75
- sleep 3
76
- end
77
110
 
78
- # Bring the replica count down and resubmit to the cluster,
79
- # this kills the 1 extra pod
80
- rcs = Keel::GCloud::Kubernetes::ReplicationController.fetch_all deploy_env, app
81
- rc = rcs.first
82
- rc.decrement_replica_count
83
- rc.update
111
+ # Nuke old pods
112
+ pods.each do |pod|
113
+ pod.delete
114
+ sleep 3
115
+ end
84
116
 
117
+ # Bring the replica count down and resubmit to the cluster,
118
+ # this kills the 1 extra pod
119
+ rcs = Keel::GCloud::Kubernetes::ReplicationController.fetch_all deploy_env, app
120
+ rc = rcs.first
121
+ rc.decrement_replica_count
122
+ rc.update
123
+ end
85
124
  prompter.print 'Notifying NewRelic of deployment', :info
86
125
  notifier = Keel::Notifier::NewRelic.new env: deploy_env, sha: deploy_sha
87
126
  notifier.notify
@@ -90,9 +129,15 @@ namespace :keel do
90
129
  end
91
130
 
92
131
  desc 'Configures the local machine for communication with gcloud and k8s'
93
- task :setup do |_|
94
- prompter = Keel::GCloud::Prompter.new
95
- config = Keel::GCloud::Config.new
132
+ task :setup => [:check_gcloud_executables,
133
+ :check_configuration,
134
+ :update_tools,
135
+ :gcloud_auth,
136
+ :set_gcloud_properties,
137
+ :install_k8s,
138
+ :authenticate_k8s]
139
+
140
+ task :check_gcloud_executables do
96
141
 
97
142
  if config.executable_missing?
98
143
  message = 'Install Google Cloud command line tools'
@@ -101,44 +146,46 @@ namespace :keel do
101
146
 
102
147
  abort message.red
103
148
  end
149
+ end
150
+
151
+ task :check_configuration do
104
152
 
105
153
  if config.system_configured?
106
154
  abort 'App appears to already be configured on your system.'.green
107
155
  end
156
+ end
108
157
 
109
- prompter.print 'Updating tools', :info
110
- Keel::GCloud::Component.update
158
+ task :install_k8s do
159
+ prompter.print 'Install Kubernetes', :info
160
+ Keel::GCloud::Component.install_k8s
161
+ end
111
162
 
163
+ task :authenticate_k8s do
164
+ prompter.print 'Pulling Kubernetes auth configuration', :info
165
+ auth = Keel::GCloud::Auth.new config: config
166
+ auth.authenticate_k8s
167
+ end
168
+
169
+ task :gcloud_auth do
112
170
  prompter.print 'Authenticating with Google Cloud', :info
113
171
  Keel::GCloud::Auth.authenticate
172
+ end
114
173
 
115
- prompter.print 'Install Kubernetes', :info
116
- Keel::GCloud::Component.install_k8s
174
+ task :update_tools do
175
+ prompter.print 'Updating tools', :info
176
+ Keel::GCloud::Component.update
177
+ end
117
178
 
179
+ task :set_gcloud_properties do
118
180
  prompter.print 'Setting gcloud properties', :info
119
181
  config.set_properties
120
-
121
- prompter.print 'Pulling Kubernetes auth configuration', :info
122
- auth = Keel::GCloud::Auth.new config: config
123
- auth.authenticate_k8s
124
182
  end
125
183
 
126
184
  desc 'Pulls logs for a given environment'
127
185
  task :logs, [:environment] do |_, args|
128
- prompter = Keel::GCloud::Prompter.new
129
- config = Keel::GCloud::Config.new
130
- app = config.app_name
131
-
132
- # Fetch namespaces from k8s
133
- namespaces = Keel::GCloud::Kubernetes::Namespace.fetch_all
134
- unless namespaces
135
- message = 'Unable to connect to Kubernetes, please try again later...'
136
- prompter.print message, :error
137
- abort
138
- end
139
-
186
+ app = config.app_name
140
187
  # Prompt the user for the env and to log and whether to tail the logs
141
- deploy_env = prompter.prompt_for_namespace namespaces, args[:environment]
188
+ deploy_env = Keel::GCloud::Interactions.pick_namespace args[:environment]
142
189
  tail = prompter.prompt_for_tailing_logs
143
190
 
144
191
  prompter.print "Getting pod information for #{deploy_env}", :info
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Youssef Chaker
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-17 00:00:00.000000000 Z
11
+ date: 2016-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -88,6 +88,7 @@ extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
90
  - ".gitignore"
91
+ - ".ruby-version"
91
92
  - ".travis.yml"
92
93
  - CODE_OF_CONDUCT.md
93
94
  - Gemfile
@@ -96,20 +97,26 @@ files:
96
97
  - Rakefile
97
98
  - bin/console
98
99
  - bin/setup
100
+ - circle.yml
99
101
  - keel.gemspec
100
102
  - lib/generators/keel/config_generator.rb
101
103
  - lib/generators/keel/controller_generator.rb
102
104
  - lib/generators/keel/service_generator.rb
105
+ - lib/generators/keel/templates/Dockerfile
103
106
  - lib/generators/keel/templates/gc-controller.yml.erb
104
107
  - lib/generators/keel/templates/gc-service.yml.erb
105
108
  - lib/generators/keel/templates/gcloud.yml
106
109
  - lib/keel.rb
110
+ - lib/keel/docker.rb
111
+ - lib/keel/docker/image.rb
107
112
  - lib/keel/gcloud.rb
108
113
  - lib/keel/gcloud/auth.rb
109
114
  - lib/keel/gcloud/cli.rb
110
115
  - lib/keel/gcloud/component.rb
111
116
  - lib/keel/gcloud/config.rb
117
+ - lib/keel/gcloud/interactions.rb
112
118
  - lib/keel/gcloud/kubernetes.rb
119
+ - lib/keel/gcloud/kubernetes/deployment.rb
113
120
  - lib/keel/gcloud/kubernetes/namespace.rb
114
121
  - lib/keel/gcloud/kubernetes/pod.rb
115
122
  - lib/keel/gcloud/kubernetes/replication_controller.rb
@@ -140,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
147
  version: '0'
141
148
  requirements: []
142
149
  rubyforge_project:
143
- rubygems_version: 2.4.5
150
+ rubygems_version: 2.4.5.1
144
151
  signing_key:
145
152
  specification_version: 4
146
153
  summary: Deploy your Rails app to Kubernetes.