moby-derp 0.4.1 → 0.7.2
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/.gitignore +1 -0
- data/.travis.yml +12 -0
- data/README.md +4 -4
- data/example.yml +29 -2
- data/lib/moby_derp/config_file.rb +2 -2
- data/lib/moby_derp/container.rb +36 -2
- data/lib/moby_derp/container_config.rb +56 -4
- data/lib/moby_derp/error.rb +4 -0
- data/lib/moby_derp/freedom_patches/docker/credential.rb +91 -0
- data/lib/{freedom_patches → moby_derp/freedom_patches}/docker/image.rb +0 -0
- data/lib/moby_derp/pod.rb +14 -0
- data/lib/moby_derp/pod_config.rb +21 -1
- data/lib/moby_derp/system_config.rb +9 -4
- data/moby-derp.gemspec +0 -1
- metadata +6 -19
- data/lib/moby_derp/moby_info.rb +0 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e1d04c23ce729679e9e1cd34fa7fbb63dac8672a2212cbed442cdaef698ac20e
|
|
4
|
+
data.tar.gz: f7cfa0d0fa9f21e6f02766669cd2a763614828a75e60ba6b35146c9c2b3d5877
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 877ef1db2ccb0f5b32cdb2bca422edc2bb3995fa650d65fad0fa581fc89c5ae4b3873759f2da706700c0a3a2b8b8392cc315659d4cf58b480efd5fcc1e91fc18
|
|
7
|
+
data.tar.gz: bf4261f7c31c01628df29e43cc42b84346525802225999e790e0268c6246b2730f9716dc087c8270cde96a75730a345276cb176e78a5d38603517532fd9c07ee
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
|
@@ -84,7 +84,7 @@ removed. This is used as the prefix for the name of all containers in the pod.
|
|
|
84
84
|
Some aspects of `moby-derp`'s operation are security-sensitive, and thus shouldn't
|
|
85
85
|
be able to be modified by the ordinary user. There is a
|
|
86
86
|
system-wide configuration file for this purpose, by default located at
|
|
87
|
-
`/etc/moby-derp.
|
|
87
|
+
`/etc/moby-derp.conf`.
|
|
88
88
|
|
|
89
89
|
Its structure is quite simple. A full example looks like this:
|
|
90
90
|
|
|
@@ -134,7 +134,7 @@ wrapper script, like this:
|
|
|
134
134
|
|
|
135
135
|
set -e
|
|
136
136
|
|
|
137
|
-
MOBY_DERP_SYSTEM_CONFIG_FILE=/opt/srv/etc/moby-derp/moby-derp.yaml
|
|
137
|
+
export MOBY_DERP_SYSTEM_CONFIG_FILE=/opt/srv/etc/moby-derp/moby-derp.yaml
|
|
138
138
|
|
|
139
139
|
exec /usr/local/bin/moby-derp "$@"
|
|
140
140
|
|
|
@@ -185,7 +185,7 @@ to `moby-derp`. This means that, yes, different users need to use different
|
|
|
185
185
|
filenames. The benefit of this is that the `sudo` configuration becomes a lot
|
|
186
186
|
easier to audit -- the pod name is right there.
|
|
187
187
|
|
|
188
|
-
This means that no matter a user does, they cannot have any effect on any
|
|
188
|
+
This means that no matter what a user does, they cannot have any effect on any
|
|
189
189
|
container which is not named for the pod they're manipulating. There are also
|
|
190
190
|
safety valves around `moby-derp`-managed containers being labelled as such, so
|
|
191
191
|
that in the event that someone does inadvertently name a container in such a
|
|
@@ -220,7 +220,7 @@ still publish to ephemeral ports (using the `:containerPort` syntax, or
|
|
|
220
220
|
`publish_all: true`) if they wish.
|
|
221
221
|
|
|
222
222
|
If a pod *does* need to bind to a specific host port, then that pod/port pair
|
|
223
|
-
should be whitelisted in the system configuration file.
|
|
223
|
+
should be whitelisted in the [system configuration file](#system-configuration).
|
|
224
224
|
|
|
225
225
|
|
|
226
226
|
# Contributing
|
data/example.yml
CHANGED
|
@@ -213,6 +213,33 @@ containers:
|
|
|
213
213
|
ulimit-rttime: 15:16
|
|
214
214
|
ulimit-stack: 17:18
|
|
215
215
|
|
|
216
|
+
# If you're a bit suss as to whether or not one of your containers will
|
|
217
|
+
# successfully start up, you can use the following section to define a
|
|
218
|
+
# start-time health checking regime.
|
|
219
|
+
#
|
|
220
|
+
# How it works is that the defined command is run in the container (using
|
|
221
|
+
# `exec`), and if-and-when that command returns a `0` exit status, the
|
|
222
|
+
# container is considered to be healthy and we're done. If the command
|
|
223
|
+
# returns a non-zero exit status, we wait for `interval` seconds and then
|
|
224
|
+
# retry. If the command executes `attempts` times without receiving a `0`
|
|
225
|
+
# exit status, the container is considered "failed", and no further
|
|
226
|
+
# containers in the pod will be processed, and the `moby-derp` execution
|
|
227
|
+
# will itself exit with a non-zero status.
|
|
228
|
+
startup_health_check:
|
|
229
|
+
# The command to run inside the container via `exec`. You can specify
|
|
230
|
+
# this as a string, or as an array of strings if you prefer to avoid
|
|
231
|
+
# shell quoting hell.
|
|
232
|
+
command: '/usr/local/bin/r-u-ok'
|
|
233
|
+
|
|
234
|
+
# How many seconds to wait between invocations of the command, when
|
|
235
|
+
# it fails. Can be any non-negative number. Defaults to 3.
|
|
236
|
+
interval: 3
|
|
237
|
+
|
|
238
|
+
# How many times to attempt to execute the health-check command before
|
|
239
|
+
# declaring the container hopelessly busticated, and aborting the
|
|
240
|
+
# `moby-derp` run. Must be a positive integer. Defaults to 10.
|
|
241
|
+
attempts: 10
|
|
242
|
+
|
|
216
243
|
# SECTION 2: POD-LEVEL CONFIGURATION
|
|
217
244
|
#
|
|
218
245
|
# The remainder of the configuration items in this file correspond to settings
|
|
@@ -295,8 +322,8 @@ expose:
|
|
|
295
322
|
# in the `moby-derp` README).
|
|
296
323
|
#
|
|
297
324
|
publish:
|
|
298
|
-
- :80
|
|
299
|
-
- :1234-1237
|
|
325
|
+
- ":80"
|
|
326
|
+
- ":1234-1237"
|
|
300
327
|
|
|
301
328
|
# If you have a burning desire to have all exposed ports automatically published
|
|
302
329
|
# to (not-so-)randomly chosen ephemeral ports, you can set this option to `true`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require_relative "./error"
|
|
2
2
|
require_relative "./logging_helpers"
|
|
3
3
|
|
|
4
|
-
require "
|
|
4
|
+
require "yaml"
|
|
5
5
|
|
|
6
6
|
module MobyDerp
|
|
7
7
|
class ConfigFile
|
|
@@ -12,7 +12,7 @@ module MobyDerp
|
|
|
12
12
|
def initialize(filename)
|
|
13
13
|
begin
|
|
14
14
|
@logger.debug(logloc) { "Reading configuration file #{filename}" }
|
|
15
|
-
@config =
|
|
15
|
+
@config = YAML.safe_load(File.read(filename))
|
|
16
16
|
rescue Errno::ENOENT
|
|
17
17
|
raise ConfigurationError,
|
|
18
18
|
"file does not exist"
|
data/lib/moby_derp/container.rb
CHANGED
|
@@ -5,6 +5,8 @@ require "docker-api"
|
|
|
5
5
|
require "ipaddr"
|
|
6
6
|
require "json/canonicalization"
|
|
7
7
|
|
|
8
|
+
require_relative "./freedom_patches/docker/credential"
|
|
9
|
+
|
|
8
10
|
module MobyDerp
|
|
9
11
|
class Container
|
|
10
12
|
include LoggingHelpers
|
|
@@ -43,7 +45,35 @@ module MobyDerp
|
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
begin
|
|
46
|
-
Docker::Container.create(hash_labelled(container_creation_parameters))
|
|
48
|
+
c = Docker::Container.create(hash_labelled(container_creation_parameters))
|
|
49
|
+
c.start!.object_id
|
|
50
|
+
|
|
51
|
+
if @config.startup_health_check
|
|
52
|
+
attempts = @config.startup_health_check[:attempts]
|
|
53
|
+
|
|
54
|
+
while attempts > 0
|
|
55
|
+
stdout, stderr, exitstatus = c.exec(@config.startup_health_check[:command])
|
|
56
|
+
if exitstatus > 0
|
|
57
|
+
stdout_lines = stdout.empty? ? [] : ["stdout:"] + stdout.join("\n").split("\n").map { |l| " #{l}" }
|
|
58
|
+
stderr_lines = stderr.empty? ? [] : ["stderr:"] + stderr.join("\n").split("\n").map { |l| " #{l}" }
|
|
59
|
+
output_lines = stdout_lines + stderr_lines
|
|
60
|
+
@logger.warn(logloc) { "Startup health check failed on #{container_name} with status #{exitstatus}." + (output_lines.empty? ? "" : ([" Output:"] + output_lines.join("\n "))) }
|
|
61
|
+
|
|
62
|
+
attempts -= 1
|
|
63
|
+
sleep @config.startup_health_check[:interval]
|
|
64
|
+
else
|
|
65
|
+
@logger.info(logloc) { "Startup health check passed." }
|
|
66
|
+
break
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if attempts == 0
|
|
71
|
+
raise MobyDerp::StartupHealthCheckError,
|
|
72
|
+
"Container #{container_name} has failed the startup health check command #{@config.startup_health_check[:attempts]} times. Aborting."
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
c.id
|
|
47
77
|
rescue Docker::Error::ClientError => ex
|
|
48
78
|
raise MobyDerp::ContainerError,
|
|
49
79
|
"moby daemon returned error: #{ex.message}"
|
|
@@ -60,7 +90,7 @@ module MobyDerp
|
|
|
60
90
|
"Init" => true,
|
|
61
91
|
}
|
|
62
92
|
params["MacAddress"] = container_mac_address
|
|
63
|
-
if network_uses_ipv6?
|
|
93
|
+
if network_uses_ipv6? && user_defined_network?
|
|
64
94
|
params["NetworkingConfig"] = {
|
|
65
95
|
"EndpointsConfig" => {
|
|
66
96
|
@pod.network_name => {
|
|
@@ -224,6 +254,10 @@ module MobyDerp
|
|
|
224
254
|
docker_network.info["EnableIPv6"]
|
|
225
255
|
end
|
|
226
256
|
|
|
257
|
+
def user_defined_network?
|
|
258
|
+
!%w{bridge host none}.include?(@pod.network_name)
|
|
259
|
+
end
|
|
260
|
+
|
|
227
261
|
def container_ipv6_address
|
|
228
262
|
network, masklen = ipv6_network.split("/", 2)
|
|
229
263
|
network = IPAddr.new(network)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require_relative "
|
|
1
|
+
require_relative "./freedom_patches/docker/image"
|
|
2
2
|
require_relative "./error"
|
|
3
3
|
require_relative "./mount"
|
|
4
4
|
|
|
@@ -8,7 +8,8 @@ require "shellwords"
|
|
|
8
8
|
module MobyDerp
|
|
9
9
|
class ContainerConfig
|
|
10
10
|
attr_reader :name, :image, :update_image, :command, :environment, :mounts,
|
|
11
|
-
:labels, :readonly, :stop_signal, :stop_timeout, :user, :restart, :limits
|
|
11
|
+
:labels, :readonly, :stop_signal, :stop_timeout, :user, :restart, :limits,
|
|
12
|
+
:startup_health_check
|
|
12
13
|
|
|
13
14
|
def initialize(system_config:,
|
|
14
15
|
pod_config:,
|
|
@@ -24,13 +25,14 @@ module MobyDerp
|
|
|
24
25
|
stop_timeout: 10,
|
|
25
26
|
user: nil,
|
|
26
27
|
restart: "no",
|
|
27
|
-
limits: {}
|
|
28
|
+
limits: {},
|
|
29
|
+
startup_health_check: nil
|
|
28
30
|
)
|
|
29
31
|
@system_config, @pod_config, @name, @image = system_config, pod_config, "#{pod_config.name}.#{container_name}", image
|
|
30
32
|
|
|
31
33
|
@update_image, @command, @environment, @mounts, @labels = update_image, command, environment, mounts, labels
|
|
32
34
|
@readonly, @stop_signal, @stop_timeout, @user, @restart = readonly, stop_signal, stop_timeout, user, restart
|
|
33
|
-
@limits = limits
|
|
35
|
+
@limits, @startup_health_check = limits, startup_health_check
|
|
34
36
|
|
|
35
37
|
validate_image
|
|
36
38
|
validate_update_image
|
|
@@ -44,6 +46,7 @@ module MobyDerp
|
|
|
44
46
|
validate_user
|
|
45
47
|
validate_restart
|
|
46
48
|
validate_limits
|
|
49
|
+
validate_startup_health_check
|
|
47
50
|
end
|
|
48
51
|
|
|
49
52
|
private
|
|
@@ -58,6 +61,10 @@ module MobyDerp
|
|
|
58
61
|
raise ConfigurationError,
|
|
59
62
|
"image is not a valid image reference"
|
|
60
63
|
end
|
|
64
|
+
|
|
65
|
+
if @image.match(Docker::Image::IMAGE_REFERENCE)[9].nil?
|
|
66
|
+
@image += ":latest"
|
|
67
|
+
end
|
|
61
68
|
end
|
|
62
69
|
|
|
63
70
|
def validate_update_image
|
|
@@ -331,6 +338,51 @@ module MobyDerp
|
|
|
331
338
|
end
|
|
332
339
|
end
|
|
333
340
|
|
|
341
|
+
def validate_startup_health_check
|
|
342
|
+
if @startup_health_check.nil?
|
|
343
|
+
# This is fine
|
|
344
|
+
return
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
unless @startup_health_check.is_a?(Hash)
|
|
348
|
+
raise ConfigurationError,
|
|
349
|
+
"startup_health_check must be a hash"
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
case @startup_health_check[:command]
|
|
353
|
+
when String
|
|
354
|
+
@startup_health_check[:command] = Shellwords.split(@startup_health_check[:command])
|
|
355
|
+
when Array
|
|
356
|
+
unless @startup_health_check[:command].all? { |c| String === c }
|
|
357
|
+
raise ConfigurationError, "all elements of the health check command array must be strings"
|
|
358
|
+
end
|
|
359
|
+
when NilClass
|
|
360
|
+
raise ConfigurationError, "health check command must be specified"
|
|
361
|
+
else
|
|
362
|
+
raise ConfigurationError,
|
|
363
|
+
"health check command must be string or array of strings"
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
@startup_health_check[:interval] ||= 3
|
|
367
|
+
@startup_health_check[:attempts] ||= 10
|
|
368
|
+
|
|
369
|
+
unless Numeric === @startup_health_check[:interval]
|
|
370
|
+
raise ConfigurationError, "startup health check interval must be a number"
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
if @startup_health_check[:interval] < 0
|
|
374
|
+
raise ConfigurationError, "startup health check interval cannot be negative"
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
unless Integer === @startup_health_check[:attempts]
|
|
378
|
+
raise ConfigurationError, "startup health check attempt count must be an integer"
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
if @startup_health_check[:attempts] < 1
|
|
382
|
+
raise ConfigurationError, "startup health check attempt count must be a positive integer"
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
334
386
|
def validate_boolean(name)
|
|
335
387
|
v = instance_variable_get(:"@#{name}")
|
|
336
388
|
unless v == true || v == false
|
data/lib/moby_derp/error.rb
CHANGED
|
@@ -9,6 +9,10 @@ module MobyDerp
|
|
|
9
9
|
# Indicates there was a problem manipulating a live container
|
|
10
10
|
class ContainerError < Error; end
|
|
11
11
|
|
|
12
|
+
# Raised when the startup health check has failed spectacularly for
|
|
13
|
+
# a container
|
|
14
|
+
class StartupHealthCheckError < Error; end
|
|
15
|
+
|
|
12
16
|
# Only appears when an inviolable assertion is invalid, and indicates
|
|
13
17
|
# there is a bug in the code
|
|
14
18
|
class BugError < Error; end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "open3"
|
|
3
|
+
require "pathname"
|
|
4
|
+
require "uri"
|
|
5
|
+
|
|
6
|
+
module Docker
|
|
7
|
+
module Credential
|
|
8
|
+
#:nocov:
|
|
9
|
+
def self.for(ref)
|
|
10
|
+
image_cred(ref)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def self.image_cred(ref)
|
|
16
|
+
cred_helper = hunt_for_image_domain_cred(ref, docker_config.fetch("credHelpers", {}))
|
|
17
|
+
|
|
18
|
+
if cred_helper
|
|
19
|
+
out, rv = Open3.capture2e("docker-credential-#{cred_helper}", "get", stdin_data: image_domain(ref))
|
|
20
|
+
|
|
21
|
+
if rv.exitstatus == 0
|
|
22
|
+
cred_data = JSON.parse(out)
|
|
23
|
+
|
|
24
|
+
{ username: cred_data["Username"], password: cred_data["Secret"], serveraddress: image_domain(ref) }
|
|
25
|
+
else
|
|
26
|
+
raise RuntimeError, "Credential helper docker-credential-#{cred_helper} exited with #{rv.exitstatus}: #{out}"
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
cred = hunt_for_image_domain_cred(ref, docker_config.fetch("auths", {}))
|
|
30
|
+
|
|
31
|
+
if cred
|
|
32
|
+
user, pass = cred["auth"]&.unpack("m")&.first&.split(":", 2)
|
|
33
|
+
|
|
34
|
+
if user && pass
|
|
35
|
+
{ username: user, password: pass, serveraddress: image_domain(ref) }
|
|
36
|
+
else
|
|
37
|
+
{}
|
|
38
|
+
end
|
|
39
|
+
else
|
|
40
|
+
{}
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.hunt_for_image_domain_cred(ref, section)
|
|
46
|
+
section.find do |k, v|
|
|
47
|
+
if k =~ /:\/\//
|
|
48
|
+
# Doin' it URL style
|
|
49
|
+
URI(k).host == image_domain(ref)
|
|
50
|
+
else
|
|
51
|
+
k == image_domain(ref)
|
|
52
|
+
end
|
|
53
|
+
end&.last
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.image_domain(ref)
|
|
57
|
+
if match_data = ref.match(Docker::Image::IMAGE_REFERENCE)
|
|
58
|
+
if match_data[1] =~ /[.:]/
|
|
59
|
+
match_data[1].gsub(/\/\z/, '')
|
|
60
|
+
else
|
|
61
|
+
"index.docker.io"
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
raise ArgumentError, "Could not parse image ref #{ref.inspect}"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.docker_config
|
|
69
|
+
if (f = Pathname.new(ENV.fetch("DOCKER_CONFIG", "~/.docker")).expand_path.join("config.json")).exist?
|
|
70
|
+
JSON.parse(f.read)
|
|
71
|
+
else
|
|
72
|
+
{}
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
module ImageClassMixin
|
|
77
|
+
def create(opts = {}, creds = nil, conn = Docker.connection, &block)
|
|
78
|
+
if creds.nil?
|
|
79
|
+
image = opts["fromImage"] || opts[:fromImage]
|
|
80
|
+
|
|
81
|
+
creds = Docker::Credential.for(image)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
super(opts, creds, conn, &block)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
#:nocov:
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
Docker::Image.singleton_class.prepend(Docker::Credential::ImageClassMixin)
|
|
File without changes
|
data/lib/moby_derp/pod.rb
CHANGED
|
@@ -18,6 +18,20 @@ module MobyDerp
|
|
|
18
18
|
|
|
19
19
|
@logger.debug(logloc) { "Root container ID is #{@root_container_id}" }
|
|
20
20
|
|
|
21
|
+
desired_container_names = @config.containers.map(&:name)
|
|
22
|
+
|
|
23
|
+
Docker::Container.all(all: true).each do |c|
|
|
24
|
+
c_name = c.info["Names"].first.sub(/^\//, '')
|
|
25
|
+
|
|
26
|
+
if c.info["Labels"]["org.hezmatt.moby-derp.pod-name"] == name &&
|
|
27
|
+
!c.info["Labels"]["org.hezmatt.moby-derp.root-container-id"].nil? &&
|
|
28
|
+
!desired_container_names.include?(c_name)
|
|
29
|
+
@logger.info(logloc) { "Removing stale container #{c_name}" }
|
|
30
|
+
c.stop
|
|
31
|
+
c.delete
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
21
35
|
@config.containers.each do |cfg|
|
|
22
36
|
@logger.info(logloc) { "Checking container #{cfg.name}" }
|
|
23
37
|
|
data/lib/moby_derp/pod_config.rb
CHANGED
|
@@ -3,13 +3,24 @@ require_relative "./container_config"
|
|
|
3
3
|
require_relative "./logging_helpers"
|
|
4
4
|
require_relative "./mount"
|
|
5
5
|
|
|
6
|
-
require "safe_yaml"
|
|
7
6
|
require "socket"
|
|
8
7
|
|
|
9
8
|
module MobyDerp
|
|
10
9
|
class PodConfig < ConfigFile
|
|
11
10
|
include LoggingHelpers
|
|
12
11
|
|
|
12
|
+
VALID_CONFIG_KEYS = %w{
|
|
13
|
+
containers
|
|
14
|
+
hostname
|
|
15
|
+
common_environment
|
|
16
|
+
common_labels
|
|
17
|
+
root_labels
|
|
18
|
+
common_mounts
|
|
19
|
+
expose
|
|
20
|
+
publish
|
|
21
|
+
publish_all
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
attr_reader :name,
|
|
14
25
|
:containers,
|
|
15
26
|
:hostname,
|
|
@@ -34,6 +45,10 @@ module MobyDerp
|
|
|
34
45
|
@name = File.basename(filename, ".*")
|
|
35
46
|
validate_name
|
|
36
47
|
|
|
48
|
+
unless (bad_keys = @config.keys - VALID_CONFIG_KEYS).empty?
|
|
49
|
+
raise ConfigurationError,
|
|
50
|
+
"Invalid pod configuration key(s): #{bad_keys.inspect}"
|
|
51
|
+
end
|
|
37
52
|
|
|
38
53
|
unless @config.has_key?("containers")
|
|
39
54
|
raise ConfigurationError,
|
|
@@ -100,6 +115,11 @@ module MobyDerp
|
|
|
100
115
|
raise ConfigurationError,
|
|
101
116
|
"container name #{name.inspect} is invalid (must contain only alphanumerics, underscores, and hyphens)"
|
|
102
117
|
end
|
|
118
|
+
|
|
119
|
+
unless data.is_a?(Hash)
|
|
120
|
+
raise ConfigurationError,
|
|
121
|
+
"container data must be a hash"
|
|
122
|
+
end
|
|
103
123
|
end
|
|
104
124
|
|
|
105
125
|
begin
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
require_relative "./config_file"
|
|
2
2
|
|
|
3
|
-
require "safe_yaml"
|
|
4
|
-
|
|
5
3
|
module MobyDerp
|
|
6
4
|
class SystemConfig < ConfigFile
|
|
7
5
|
attr_reader :mount_root, :port_whitelist, :network_name, :use_host_resolv_conf,
|
|
8
6
|
:cpu_count, :cpu_bits
|
|
9
7
|
|
|
10
|
-
def initialize(
|
|
8
|
+
def initialize(config_data_or_filename, moby_info, logger)
|
|
11
9
|
@logger = logger
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
case config_data_or_filename
|
|
12
|
+
when String
|
|
13
|
+
super(config_data_or_filename)
|
|
14
|
+
when Hash
|
|
15
|
+
@config = stringify_keys(config_data_or_filename)
|
|
16
|
+
else
|
|
17
|
+
raise ArgumentError, "Unsupported type for config_data_or_filename parameter"
|
|
18
|
+
end
|
|
14
19
|
|
|
15
20
|
@mount_root = @config["mount_root"]
|
|
16
21
|
@port_whitelist = stringify_keys(@config["port_whitelist"] || {})
|
data/moby-derp.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moby-derp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matt Palmer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-07-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: docker-api
|
|
@@ -38,20 +38,6 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: safe_yaml
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - ">="
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '0'
|
|
48
|
-
type: :runtime
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - ">="
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '0'
|
|
55
41
|
- !ruby/object:Gem::Dependency
|
|
56
42
|
name: bundler
|
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -201,6 +187,7 @@ extensions: []
|
|
|
201
187
|
extra_rdoc_files: []
|
|
202
188
|
files:
|
|
203
189
|
- ".gitignore"
|
|
190
|
+
- ".travis.yml"
|
|
204
191
|
- ".yardopts"
|
|
205
192
|
- CODE_OF_CONDUCT.md
|
|
206
193
|
- CONTRIBUTING.md
|
|
@@ -208,13 +195,13 @@ files:
|
|
|
208
195
|
- README.md
|
|
209
196
|
- bin/moby-derp
|
|
210
197
|
- example.yml
|
|
211
|
-
- lib/freedom_patches/docker/image.rb
|
|
212
198
|
- lib/moby_derp/config_file.rb
|
|
213
199
|
- lib/moby_derp/container.rb
|
|
214
200
|
- lib/moby_derp/container_config.rb
|
|
215
201
|
- lib/moby_derp/error.rb
|
|
202
|
+
- lib/moby_derp/freedom_patches/docker/credential.rb
|
|
203
|
+
- lib/moby_derp/freedom_patches/docker/image.rb
|
|
216
204
|
- lib/moby_derp/logging_helpers.rb
|
|
217
|
-
- lib/moby_derp/moby_info.rb
|
|
218
205
|
- lib/moby_derp/mount.rb
|
|
219
206
|
- lib/moby_derp/pod.rb
|
|
220
207
|
- lib/moby_derp/pod_config.rb
|
|
@@ -243,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
243
230
|
- !ruby/object:Gem::Version
|
|
244
231
|
version: '0'
|
|
245
232
|
requirements: []
|
|
246
|
-
rubygems_version: 3.0.
|
|
233
|
+
rubygems_version: 3.0.3
|
|
247
234
|
signing_key:
|
|
248
235
|
specification_version: 4
|
|
249
236
|
summary: A simple management system for a pod of moby containers
|
data/lib/moby_derp/moby_info.rb
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
module MobyDerp
|
|
2
|
-
class MobyInfo
|
|
3
|
-
attr_reader :cpu_count, :cpu_bits
|
|
4
|
-
|
|
5
|
-
def initialize(info)
|
|
6
|
-
@cpu_count = info["NCPU"]
|
|
7
|
-
# As far as I can tell, the only 32-bit platform Moby supports is
|
|
8
|
-
# armhf; if that turns out to be incorrect, amend the list below.
|
|
9
|
-
@cpu_bits = %w{armhf}.include?(info["Architecture"]) ? 32 : 64
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|