mkit 0.2.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03e23a426169a1815c4f92ef46461db9275e60aabe3ac62e9eb57d5a36e34ded
4
- data.tar.gz: f05140fed7e69015dcfe19e2f9d52498a7cf260da0ffb31fbcbaddf505f204f0
3
+ metadata.gz: '03388845cec9ae0e648bd0692ce1f3b0608127bfd3f4da3019ca78fa8c188d1c'
4
+ data.tar.gz: 9aa7ded98a1198a4f3dc81a313cd4eddee05df42ec0da5e3e48eb53ab639fd3f
5
5
  SHA512:
6
- metadata.gz: dcfb2eca9b54bd5871c9899640abba32e6da653f3db94ba9701ccc7271225d0634c77361444c1683f1f71bb138afc4e3d86e416fb930a3f6bf74a6bd93449974
7
- data.tar.gz: 9d3efacb12c9dc6959501101d3f2ad31b8367909beb36eb139d7a702e57ad05046363330d253dc6f39c163541c24d62f42ce780aca900ca82754054b93ed4404
6
+ metadata.gz: 55978a84196d4bd5f72ef0f8fa745d5f74a24d4e6ecb62d4b52bc5076b8b1a63a9e3fdfc2c80a07f8b8d6a7d19fae99b6d2b2f7365a2258678d46380c60e4803
7
+ data.tar.gz: c1c2dea9ae37f80db6a8bca1c63b3556e5642b84d882e96fd323f483df767600ee5b58e72ba930af6ec086641d41eeee0252bfec567fff182cfc4fcfe45157fc
data/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  This is micro kubernetes(tm) on Ruby(tm), a simple tool to deploy containers to mimic a (very) minimalistic k8 cluster with a nice REST API.
4
4
 
5
- It contains a internal DNS and uses HAProxy for routing/balancing/fail-over for Pods access.
5
+ It contains an internal DNS and uses HAProxy for routing/balancing/fail-over for Pods access.
6
6
  The database is a simple sqlite3 db and the server is a Sinatra based application.
7
7
 
8
- The client is not done yet, only includes a simple wrapper to `curl`
8
+ A client is also included to access the API, e.g. `mkitc ps`.
9
9
 
10
- The daemon is responsible for HAProxy pods routing configuration. It also provides the cluster DNS and manages the internal host interface.
10
+ The daemon is responsible for HAProxy pods routing configuration. It also provides the cluster DNS and manages the internal host interface and the docker instances.
11
11
 
12
12
  ## Requirements
13
13
 
@@ -16,9 +16,16 @@ The daemon is responsible for HAProxy pods routing configuration. It also provid
16
16
  * Docker
17
17
  * Linux (iproute2 package)
18
18
 
19
+ ## Install
20
+
21
+ This is a simple ruby gem, so to install run
22
+ ```
23
+ # gem install mkit
24
+ ```
25
+
19
26
  ## Running
20
27
 
21
- The `daemon` requires `root` user, you can run it directly on the repository root...
28
+ The `daemon` requires `root` user (due to `ip` and `haproxy`), you can run it directly on the repository root...
22
29
 
23
30
  ```
24
31
  # ./mkitd --help
@@ -47,22 +54,23 @@ There's also samples on the samples dir, for daemontools and systemd.
47
54
  ### Accessing the API
48
55
 
49
56
  * Create new service
50
- * `mkitc POST services -F "file=@samples/apps/rabbitmq.yml"`
57
+ * `mkitc create samples/apps/rabbitmq.yml`
51
58
  * Update service
52
- * `mkitc PUT services/{id|service_name} -F "file=@samples/apps/rabbitmq.yml"`
53
- * Get services
54
- * `mkitc GET services/{id|service_name}[?verbose=true]`
59
+ * `mkitc update samples/apps/rabbitmq.yml`
60
+ * Get service
61
+ * `mkitc ps {id|service_name}`
55
62
  * Delete service
56
- * `mkitc DELETE services/{id|service_name}`
63
+ * `mkitc rm {id|service_name}`
57
64
  * List services
58
- * `mkitc GET services?verbose=true`
65
+ * `mkitc ps [-v (verbose)]`
59
66
  * Control service
60
- * `mkitc PUT services/{id|service_name}/start`
61
- * `mkitc PUT services/{id|service_name}/stop`
67
+ * `mkitc start {id|service_name}`
68
+ * `mkitc stop {id|service_name}`
62
69
 
63
70
  Example:
64
71
 
65
72
  ```
73
+ $ mkitc ps postgres
66
74
  id name addr ports status
67
75
  4 postgres 10.210.198.10 tcp/5432 RUNNING
68
76
  pods
@@ -98,15 +106,19 @@ CONFIG="/etc/haproxy/haproxy.d"
98
106
  service:
99
107
  name: rabbitmq # unique
100
108
  image: rabbitmq:3-management-alpine # image
101
- network: bridge # docker network
102
- ports: # haproxy port mapping: <external_port>|<internal_port>|<tcp|http>|round_robin
109
+ network: bridge # docker network - it will be created if it does not exists
110
+ ports: # haproxy port mapping
111
+ # <external_port>:[internal_port]:<tcp|http>:[round_robin (default)|leastconn]
112
+ # to define a range on `external_port`, leave `internal_port` blank
113
+ # - 5000-5100::tcp:round_robin
114
+ # range on `internal_port` is not supported
103
115
  - 5672:5672:tcp:round_robin
104
116
  - 80:15672:http:round_robin
105
117
  resources:
106
118
  max_replicas: 1
107
119
  min_replicas: 1
108
120
  volumes:
109
- - docker://mkit_rabbitmq_data:/var/lib/rabbitmq # a docker volume
121
+ - docker://mkit_rabbitmq_data:/var/lib/rabbitmq # a docker volume - it will be created if it does not exists
110
122
  - /var/log/rabbitmq/logs:/var/log/rabbitmq # a local volume
111
123
  environment:
112
124
  RABBITMQ_DEFAULT_USER: admin
data/bin/mkitc CHANGED
@@ -2,30 +2,157 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'rubygems'
5
+ require 'optparse'
6
+ require 'yaml'
7
+ require 'net/http'
8
+ require 'json'
9
+ require 'net_http_unix'
10
+ require 'securerandom'
5
11
 
6
12
  class MKItClient
7
13
 
8
- VERBS = %w{GET POST PUT DELETE}
9
- def usage
10
- puts
11
- puts "usage: mkitc <verb> <path>"
12
- puts " where <verb> is one of GET | POST | PUT | DELETE"
13
- puts "e.g."
14
- puts " mkitc GET applications"
15
- puts
14
+ def initialize
15
+ @client = NetX::HTTPUnix.new("localhost",4567)
16
16
  end
17
17
 
18
- def run
19
- if ARGV.size < 2 || VERBS.index(ARGV[0]).nil?
20
- usage
21
- exit 1
18
+ def parse_args(args)
19
+ request = nil
20
+ case args[0]
21
+ when /^ps$/
22
+ if args.include?('-v')
23
+ params = {verbose: 'true'}
24
+ args.delete('-v')
25
+ else
26
+ params = {}
27
+ end
28
+ case args.size
29
+ when 1
30
+ #mkitc ps [-v] GET services[?verbose=true]
31
+ request = { verb: :get, uri: '/services', params: params }
32
+ when 2
33
+ #mkitc ps {id} GET services/{id}
34
+ id = args[1]
35
+ request = { verb: :get, uri: "/services/#{id}" }
36
+ else
37
+ raise 'invalid parameters'
38
+ end
39
+ when /^config:show$/
40
+ #mkitc config:show {id} => GET services/{id}/config
41
+ #TODO
42
+ when /^stop$/
43
+ #mkitc stop {id} => PUT services/{id}/stop
44
+ case args.size
45
+ when 2
46
+ id = args[1]
47
+ request = { verb: :put, uri: "/services/#{id}/stop" }
48
+ else
49
+ raise 'invalid parameters'
50
+ end
51
+ when /^start$/
52
+ #mkitc start {id} => PUT services/{id}/start
53
+ case args.size
54
+ when 2
55
+ id = args[1]
56
+ request = { verb: :put, uri: "/services/#{id}/start" }
57
+ else
58
+ raise 'invalid parameters'
59
+ end
60
+ when /^rm$/
61
+ #mkitc rm {id} => DELETE services/{id}
62
+ case args.size
63
+ when 2
64
+ id = args[1]
65
+ request = { verb: :delete, uri: "/services/#{id}" }
66
+ else
67
+ raise 'invalid parameters'
68
+ end
69
+ when /^create$/
70
+ #mkitc create service.yaml => POST services service.yaml
71
+ case args.size
72
+ when 2
73
+ file = args[1]
74
+ request = { verb: :post, uri: "/services", file: file }
75
+ else
76
+ raise 'invalid parameters'
77
+ end
78
+ when /^update$/
79
+ #mkitc update service.yaml => PUT services/{id} service.yaml
80
+ case args.size
81
+ when 2
82
+ file = args[1]
83
+ yaml = YAML.load_file(file)
84
+ if yaml["service"].nil?
85
+ raise 'invalid configuration file'
86
+ else
87
+ id = yaml["service"]["name"]
88
+ request = { verb: :put, uri: "/services/#{id}", file: file }
89
+ end
90
+ else
91
+ raise 'invalid parameters'
92
+ end
93
+ else
94
+ raise "Usage: invalid parameters"
22
95
  end
96
+ request
97
+ end
98
+
99
+ def doIt(args)
100
+ operation = parse_args(args)
101
+ puts request(operation).body
102
+ end
103
+
104
+ def request(request)
105
+ req = nil
106
+ uri = request[:uri]
107
+ unless request[:params].nil? || request[:params].empty?
108
+ uri = uri + '?' + request[:params].map{|k,v| "#{k}=#{v}"}.join('&')
109
+ end
110
+ case request[:verb]
111
+ when :post
112
+ req = Net::HTTP::Post.new(uri)
113
+ unless request[:file].nil?
114
+ (body, boundary) = attach(request[:file])
115
+ req.body = body
116
+ req["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
117
+ end
118
+ when :put
119
+ req = Net::HTTP::Put.new(uri)
120
+ unless request[:file].nil?
121
+ (body, boundary) = attach(request[:file])
122
+ req.body = body
123
+ req["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
124
+ end
125
+ when :patch
126
+ req = Net::HTTP::Patch.new(uri)
127
+ when :get
128
+ req = Net::HTTP::Get.new(uri)
129
+ when :delete
130
+ req = Net::HTTP::Delete.new(uri)
131
+ end
132
+ @client.request(req)
133
+ end
23
134
 
24
- response = %x{curl -sL -X #{ARGV[0]} http://localhost:4567/#{ARGV[1]} #{ARGV[2]} #{ARGV[3]} #{ARGV[4]} #{ARGV[5]} #{ARGV[6]} #{ARGV[7]}}
25
- puts response
135
+ def attach(file)
136
+ boundary=SecureRandom.alphanumeric
137
+ body = []
138
+ body << "--#{boundary}\r\n"
139
+ body << "Content-Disposition: form-data; name=file; filename='#{File.basename(file)}'\r\n"
140
+ body << "Content-Type: text/plain\r\n"
141
+ body << "\r\n"
142
+ body << File.read(file)
143
+ body << "\r\n--#{boundary}--\r\n"
144
+ [ body.join, boundary]
26
145
  end
27
146
  end
28
147
 
148
+ #
149
+ # go
150
+ #
29
151
  client = MKItClient.new
30
- client.run
152
+ client.doIt(ARGV.dup)
153
+ #
154
+ # if ARGV.any?
155
+ # parse args
156
+ # host, socket, config file
157
+ # end
31
158
 
@@ -41,9 +41,6 @@ class ServicesController < MKIt::Server
41
41
  srv.update!(yaml.to_o)
42
42
  end
43
43
  format_response(srv)
44
- rescue MKIt::BaseException => e
45
- MKItLogger.debug e
46
- error e.error_code, e.message
47
44
  end
48
45
 
49
46
  # curl -X DELETE localhost:4567/services/1
@@ -62,9 +59,6 @@ class ServicesController < MKIt::Server
62
59
  srv = Service.create(yaml.to_o)
63
60
  end
64
61
  format_response(srv)
65
- rescue MKIt::BaseException => e
66
- MKItLogger.debug e
67
- error e.error_code, e.message
68
62
  end
69
63
 
70
64
  #
@@ -84,4 +78,3 @@ class ServicesController < MKIt::Server
84
78
  format_response(srv)
85
79
  end
86
80
  end
87
-
@@ -38,9 +38,9 @@ module MKIt
38
38
  MKIt::CmdRunner.run("docker network create #{network_name}")
39
39
  end
40
40
 
41
- def inspect_network(network_name)
42
- x = MKIt::CmdRunner.run("docker network inspect #{network_name}")
43
- JSON.parse(x).first
41
+ def network_exists?(network_name)
42
+ x = MKIt::CmdRunner.run("docker network ls")
43
+ x.match(/\b#{network_name}\b/)
44
44
  end
45
45
 
46
46
  def dettach_network(network_id, instance_id)
@@ -3,6 +3,18 @@ require 'mkit/exceptions'
3
3
  module MKIt
4
4
  class Server < Sinatra::Base
5
5
  set :default_content_type, :json
6
- # set :dump_errors, false
6
+ set :dump_errors, true
7
+ set :show_exceptions, false
8
+ set :raise_errors, false
9
+
10
+ error MKIt::BaseException do |e|
11
+ MKItLogger.debug e
12
+ error e.error_code, e.message
13
+ end
14
+
15
+ error do |e|
16
+ MKItLogger.debug e
17
+ error 500, e.message
18
+ end
7
19
  end
8
20
  end
@@ -16,21 +16,20 @@ class Pool < ActiveRecord::Base
16
16
  ips = range.split('-')
17
17
  next_ip = ips[0]
18
18
  next_ip = next_ip.to_i
19
- lease.select(:status == MKIt::PoolStatus::IN_USE || :status == MKIt::PoolStatus::RESERVED).each { |l|
20
- leased_ip = l.ip.split('.')[3]
21
- leased_ip = leased_ip.to_i
22
- if leased_ip >= next_ip
23
- next_ip = leased_ip+1
19
+ ip_add = self.ip.split('.')
20
+ while next_ip <= ips[1].to_i + 1 do
21
+ if (lease.select{|l| l.ip == "#{ip_add[0]}.#{ip_add[1]}.#{ip_add[2]}.#{next_ip}"}.size == 0)
22
+ break
23
+ else
24
+ next_ip+=1
24
25
  end
25
- }
26
+ end
27
+
26
28
  if next_ip > ips[1].to_i
27
29
  self.status = MKIt::PoolStatus::EXAUSTED
28
30
  self.save
29
31
  raise PoolExaustedException.new
30
32
  end
31
-
32
- ip_add = self.ip.split('.')
33
-
34
33
  "#{ip_add[0]}.#{ip_add[1]}.#{ip_add[2]}.#{next_ip}"
35
34
  end
36
35
 
@@ -9,11 +9,7 @@ require 'mkit/status'
9
9
  require 'mkit/utils'
10
10
  require 'mkit/ctypes'
11
11
  require 'mkit/app/model/pool'
12
- require 'mkit/app/model/service'
13
- require 'mkit/app/model/pod'
14
12
  require 'mkit/app/model/dns_host'
15
- require 'mkit/app/helpers/erb_helper'
16
- require 'mkit/app/helpers/docker_helper'
17
13
  require 'mkit/app/helpers/haproxy'
18
14
 
19
15
  #
@@ -46,13 +42,6 @@ class Service < ActiveRecord::Base
46
42
  status: MKIt::Status::CREATING
47
43
  )
48
44
 
49
- # docker network
50
- if config.network.nil? || config.network.empty?
51
- srv.pods_network="mkit"
52
- else
53
- srv.pods_network=config.network
54
- end
55
-
56
45
  # reserve pool ip
57
46
  srv.lease = Pool.find_by_name(MKIt::Utils.me).reserve_for(srv)
58
47
 
@@ -91,6 +80,14 @@ class Service < ActiveRecord::Base
91
80
  end
92
81
  self.max_replicas = self.min_replicas if self.min_replicas > self.max_replicas
93
82
 
83
+ # docker network
84
+ if config.network.nil? || config.network.empty?
85
+ self.pods_network="mkit"
86
+ else
87
+ self.pods_network=config.network
88
+ end
89
+ self.create_pods_network
90
+
94
91
  # haproxy ports
95
92
  self.service_port = []
96
93
  config.ports&.each do |p|
@@ -130,16 +127,13 @@ class Service < ActiveRecord::Base
130
127
  end
131
128
 
132
129
  def create_pods_network
133
- netw = inspect_network(self.pods_network)
134
- create_network(self.pods_network) if netw.nil?
130
+ create_network(self.pods_network) if !network_exists?(self.pods_network)
135
131
  end
136
132
 
137
133
  def deploy_network
138
134
  # create service interface...
139
135
  self.lease.confirm
140
136
  self.lease.up
141
- # ...and pods network
142
- self.create_pods_network
143
137
  end
144
138
 
145
139
  def add_volume(volume_config)
@@ -201,19 +195,6 @@ class Service < ActiveRecord::Base
201
195
  #
202
196
  # ha proxy configs & template
203
197
  #
204
- def public_ports
205
- self.service_port.each.map{|p| p.external_port}.uniq
206
- end
207
-
208
- def ports_by_external(external_port)
209
- self.service_port.where('external_port = ?', external_port)
210
- end
211
-
212
- def ports_mode_by_external(external_port)
213
- ports = self.service_port.where('external_port = ?', external_port).first
214
- ports.mode if ports
215
- end
216
-
217
198
  def update_proxy
218
199
  MkitJob.publish(topic: :update_proxy_config, application_id: self.id, data: proxy_config)
219
200
  end
@@ -1,30 +1,47 @@
1
1
  require 'mkit/app/model/service'
2
+ require 'mkit/exceptions'
2
3
 
3
4
  class ServicePort < ActiveRecord::Base
4
5
  belongs_to :service
5
6
 
7
+ CONFIG_EXPRESSION=/^(.*?):(.*?):(tcp|http):(.*?)$/
8
+
6
9
  def self.create(service:, config:)
7
10
  sp = ServicePort.new(service: service, version: service.version)
8
11
  sp.parse_config(config)
9
12
  sp
10
13
  end
11
14
 
12
- # haproxy support for port range - leave src blank
15
+ # haproxy support for port range - leave dest blank
13
16
  # service:
14
17
  # ports:
15
- # # src:dest:tcp|http:load-balancing
18
+ # # src:dest:tcp|http:round_robin|leastconn
16
19
  # - 5532:5432:tcp:round_robin
20
+ # - 5532-6000::tcp:round_robin
17
21
  # model:
18
22
  # service_ports:
19
23
  # - external: 5432
20
24
  # internal: 5432
21
25
  # mode: tcp|http
22
- # load_bal:
26
+ # load_bal: round_robin
23
27
  def parse_config(config)
24
- ports = config.split(':')
25
- self.external_port = ports[0]
26
- self.internal_port = ports[1]
27
- self.mode = ports[2]
28
- self.load_bal = ports[3]
28
+ ports = config.match(CONFIG_EXPRESSION)
29
+ raise MKIt::InvalidPortsConfiguration.new("no match with config expression $#{CONFIG_EXPRESSION}") if ports.nil?
30
+
31
+ self.external_port = ports[1]
32
+ self.internal_port = ports[2]
33
+ self.mode = ports[3]
34
+ self.load_bal = ports[4]
35
+ end
36
+
37
+ def load_balance
38
+ case self.load_bal
39
+ when /^round_robin$/
40
+ "roundrobin"
41
+ when /^leastconn$/
42
+ "leastconn"
43
+ else
44
+ "roundrobin"
45
+ end
29
46
  end
30
47
  end
@@ -1,30 +1,27 @@
1
1
  #
2
2
  # MKIt generated file
3
3
  #
4
- <% public_ports.each { |external_port|%>
4
+ <% service_port.each { |port|%>
5
5
  #
6
- # start <%=name%>-<%=external_port%>
6
+ # start <%=name%>-<%=port.external_port%>
7
7
  #
8
- frontend <%=name%>-<%=external_port%>-front
9
- bind <%=lease.ip%>:<%=external_port%>
10
- mode <%=ports_mode_by_external(external_port)%>
8
+ frontend <%=name%>-<%=port.external_port%>-front
9
+ bind <%=lease.ip%>:<%=port.external_port%>
10
+ mode <%=port.mode%>
11
11
  #
12
- use_backend <%=name%>-<%=external_port%>-back
12
+ use_backend <%=name%>-<%=port.external_port%>-back
13
13
 
14
- backend <%=name%>-<%=external_port%>-back
15
- mode <%=ports_mode_by_external(external_port)%>
16
- #balance leastconn
17
- balance roundrobin
18
- <%if ports_mode_by_external(external_port) == 'http'%>
19
- option httpclose
20
- option forwardfor
21
- cookie JSESSIONID prefix
22
- <%end%>
23
- <%ports_by_external(external_port).each { |port| %>
24
- <%port.service.pod.each { | pod | %>
25
- server <%=pod.name%> <%=pod.ip%>:<%=port.internal_port%> <%if port.mode == 'http'%>cookie A<%end%> check<%}%><%}%>
26
- #
27
- # end of <%=name%>-<%=external_port%>
14
+ backend <%=name%>-<%=port.external_port%>-back
15
+ mode <%=port.mode%>
16
+ balance <%=port.load_balance%>
17
+ <%if port.mode == 'http'%>
18
+ option httpclose
19
+ option forwardfor
20
+ cookie JSESSIONID prefix
21
+ <%end%><%port.service.pod.each { | pod | %>
22
+ server <%=pod.name%> <%=pod.ip%><%unless port.internal_port.nil? || port.internal_port.empty? then%><%=":#{port.internal_port}"%> <%if port.mode == 'http'%>cookie A<%end%> check<%end%>
23
+ <%}%>
28
24
  #
29
- <%}%>
30
-
25
+ # end of <%=name%>-<%=port.external_port%>
26
+ #
27
+ <%}%>
@@ -17,6 +17,11 @@ module MKIt
17
17
  super(400, message)
18
18
  end
19
19
  end
20
+ class InvalidPortsConfiguration < BaseException
21
+ def initialize(message = nil)
22
+ super(400, message)
23
+ end
24
+ end
20
25
  class ServiceNotFoundException < StandardError; end
21
26
  class PodNotFoundException < StandardError; end
22
27
  class AppAlreadyDeployedException < StandardError; end
data/lib/mkit/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module MKIt
2
- VERSION = "0.2.0"
2
+ VERSION = "0.4.0"
3
3
  end
4
4
 
data/lib/mkit.rb CHANGED
@@ -110,6 +110,9 @@ module MKIt
110
110
  srv.deploy_network
111
111
  srv.update_status!
112
112
  }
113
+ # daemontools would eventually start haproxy; systemd does not.
114
+ # so, restart here.
115
+ MKIt::HAProxy.restart
113
116
  end
114
117
 
115
118
  def self.startup(options: {})
data/mkit.gemspec CHANGED
@@ -6,12 +6,12 @@ require "mkit/version"
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = 'mkit'
9
- s.summary = 'micro kubernets'
9
+ s.summary = 'Micro Kubernets on Ruby'
10
10
  s.bindir = 'bin'
11
- s.homepage = 'http://vars.pt'
11
+ s.homepage = 'https://github.com/valexsantos/mkit'
12
12
  s.license = 'Apache-2.0'
13
13
  s.rubyforge_project = ''
14
- s.description = 'micro kubernets impl'
14
+ s.description = 'Micro k8s on Ruby - a simple tool to deploy containers to mimic a (very) minimalistic k8 cluster with a nice REST API'
15
15
  # s.require_paths = ["."]
16
16
  s.author = 'Vasco Santos'
17
17
  s.email = ['valexsantos@gmail.com']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasco Santos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-08 00:00:00.000000000 Z
11
+ date: 2024-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ping
@@ -290,7 +290,8 @@ dependencies:
290
290
  - - ">="
291
291
  - !ruby/object:Gem::Version
292
292
  version: 0.2.2
293
- description: micro kubernets impl
293
+ description: Micro k8s on Ruby - a simple tool to deploy containers to mimic a (very)
294
+ minimalistic k8 cluster with a nice REST API
294
295
  email:
295
296
  - valexsantos@gmail.com
296
297
  executables:
@@ -367,7 +368,7 @@ files:
367
368
  - samples/daemontools/log/run
368
369
  - samples/daemontools/run
369
370
  - samples/systemd/mkitd.service
370
- homepage: http://vars.pt
371
+ homepage: https://github.com/valexsantos/mkit
371
372
  licenses:
372
373
  - Apache-2.0
373
374
  metadata: {}
@@ -389,5 +390,5 @@ requirements: []
389
390
  rubygems_version: 3.3.5
390
391
  signing_key:
391
392
  specification_version: 4
392
- summary: micro kubernets
393
+ summary: Micro Kubernets on Ruby
393
394
  test_files: []