mkit 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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: []