chef-provisioning-docker 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -8
- data/chef-provisioning-docker.gemspec +1 -1
- data/lib/chef/provisioning/docker_driver/docker_container_machine.rb +199 -13
- data/lib/chef/provisioning/docker_driver/docker_run_options.rb +593 -0
- data/lib/chef/provisioning/docker_driver/docker_transport.rb +120 -57
- data/lib/chef/provisioning/docker_driver/driver.rb +82 -148
- data/lib/chef/provisioning/docker_driver/version.rb +1 -1
- metadata +12 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cd0cd2d71b1bd1aece33ccaf51de2f3d877226b
|
4
|
+
data.tar.gz: 7ea228d6b0a5c4daf39f14d60d35d0781e637fb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a09fbef723a466b7188f54467cb6a49bd7b3360288c90b34c945d91691660456a00e5dd47ef67392c8a754051ba6749079b5796e9f6aef3fba6a76e4264d717
|
7
|
+
data.tar.gz: 3d678d90f7e1578f5cb5eb41ed3995b9015e6a93ae7af03ff64bdb12cfdf27782a89939c0538802d30532f570ce4b8b58922ea6768f6548b6d9e92fa08a17ac1
|
data/README.md
CHANGED
@@ -16,15 +16,16 @@ Using this , you can then define a machine similar to the following example:
|
|
16
16
|
|
17
17
|
```ruby
|
18
18
|
require 'chef/provisioning/docker_driver'
|
19
|
+
with_driver 'docker'
|
19
20
|
|
20
21
|
machine 'wario' do
|
21
|
-
|
22
|
+
recipe 'openssh::default'
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
machine_options docker_options: {
|
25
|
+
base_image: {
|
26
|
+
name: 'ubuntu',
|
27
|
+
repository: 'ubuntu',
|
28
|
+
tag: '14.04'
|
28
29
|
},
|
29
30
|
:command => '/usr/sbin/sshd -p 8022 -D',
|
30
31
|
|
@@ -61,7 +62,12 @@ machine 'wario' do
|
|
61
62
|
# if you need to keep stdin open (i.e docker run -i)
|
62
63
|
# :keep_stdin_open => true
|
63
64
|
|
65
|
+
},
|
66
|
+
# optional, default timeout is 600
|
67
|
+
docker_connection: {
|
68
|
+
:read_timeout => 1000,
|
64
69
|
}
|
70
|
+
|
65
71
|
end
|
66
72
|
```
|
67
73
|
|
@@ -95,6 +101,5 @@ end
|
|
95
101
|
```
|
96
102
|
|
97
103
|
This will create a docker container based on Ubuntu 14.04 and
|
98
|
-
then execute the
|
104
|
+
then execute the openssh recipe and run the /usr/sbin/sshd command
|
99
105
|
as the container's run command.
|
100
|
-
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.add_dependency 'chef'
|
16
16
|
s.add_dependency 'chef-provisioning', '~> 1.0'
|
17
|
-
s.add_dependency 'docker-api'
|
17
|
+
s.add_dependency 'docker-api', '~> 1.26', '>= 1.26.2'
|
18
18
|
s.add_dependency 'minitar'
|
19
19
|
s.add_dependency 'sys-proctable'
|
20
20
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'chef/provisioning/machine/unix_machine'
|
2
|
+
require 'chef/provisioning/docker_driver/docker_run_options'
|
2
3
|
|
3
4
|
class Chef
|
4
5
|
module Provisioning
|
@@ -9,29 +10,214 @@ module DockerDriver
|
|
9
10
|
# Options is expected to contain the optional keys
|
10
11
|
# :command => the final command to execute
|
11
12
|
# :ports => a list of port numbers to listen on
|
12
|
-
def initialize(machine_spec, transport, convergence_strategy, command = nil)
|
13
|
+
def initialize(machine_spec, transport, convergence_strategy, connection, command = nil)
|
13
14
|
super(machine_spec, transport, convergence_strategy)
|
14
15
|
@command = command
|
15
16
|
@transport = transport
|
17
|
+
@connection = connection
|
18
|
+
end
|
19
|
+
|
20
|
+
def setup_convergence(action_handler)
|
21
|
+
# Build a converge container to converge in
|
22
|
+
transport.container = build_converge_container(action_handler)
|
23
|
+
unless transport.container.info['State']['Running']
|
24
|
+
action_handler.perform_action "start converge container chef-converge.#{machine_spec.name}" do
|
25
|
+
transport.container.start!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
super(action_handler)
|
29
|
+
# Commit after convergence setup (such as the install of Chef)
|
30
|
+
# to break up the cost of the commit and avoid read timeouts
|
31
|
+
transport.container.commit
|
16
32
|
end
|
17
33
|
|
18
34
|
def converge(action_handler)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
35
|
+
# First, grab and start the converge container if it's there ...
|
36
|
+
transport.container = converge_container_for(machine_spec)
|
37
|
+
if !transport.container
|
38
|
+
raise "No converge container found! Did you run `:converge` without first running `:setup`?"
|
39
|
+
end
|
40
|
+
unless transport.container.info['State']['Running']
|
41
|
+
action_handler.perform_action "start converge container chef-converge.#{machine_spec.name}" do
|
42
|
+
transport.container.start!
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Then, converge ...
|
47
|
+
super(action_handler)
|
48
|
+
|
49
|
+
# Save the converged image ...
|
50
|
+
converged_image = commit_converged_image(action_handler, machine_spec, transport.container)
|
51
|
+
|
52
|
+
# Build the new container
|
53
|
+
transport.container = create_container(action_handler, machine_spec, converged_image)
|
54
|
+
|
55
|
+
# Finally, start it!
|
56
|
+
action_handler.perform_action "start container #{machine_spec.name}" do
|
57
|
+
transport.container.start!
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def container_config(action_handler, machine_spec)
|
64
|
+
docker_options = machine_spec.reference['docker_options'] || {}
|
65
|
+
|
66
|
+
# We're going to delete things to make it easier on ourselves, back it up
|
67
|
+
docker_options = docker_options.dup
|
68
|
+
|
69
|
+
# Bring in from_image
|
70
|
+
if machine_spec.from_image
|
71
|
+
docker_options['base_image'] ||= {}
|
72
|
+
docker_options['base_image']['name'] = machine_spec.from_image
|
73
|
+
end
|
74
|
+
|
75
|
+
# Respect :container_config
|
76
|
+
config = stringize_keys(docker_options.delete('container_config') || {})
|
77
|
+
|
78
|
+
# Respect :base_image
|
79
|
+
image = base_image(action_handler, docker_options.delete('base_image'))
|
80
|
+
config['Image'] = image if image
|
81
|
+
|
82
|
+
# Respect everything else
|
83
|
+
DockerRunOptions.include_command_line_options_in_container_config(config, docker_options)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Get the converge container for this machine
|
87
|
+
def converge_container_for(machine_spec)
|
88
|
+
begin
|
89
|
+
Docker::Container.get("chef-converge.#{machine_spec.name}", {}, @connection)
|
90
|
+
rescue Docker::Error::NotFoundError
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def container_for(machine_spec)
|
95
|
+
begin
|
96
|
+
Docker::Container.get(machine_spec.name, {}, @connection)
|
97
|
+
rescue Docker::Error::NotFoundError
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Builds a container that has the same properties as the final container,
|
102
|
+
# but with a couple of tweaks to allow processes to run and converge the
|
103
|
+
# container.
|
104
|
+
def build_converge_container(action_handler)
|
105
|
+
# If a converge container already exists, do nothing. TODO check if it's different!!!
|
106
|
+
converge_container = converge_container_for(machine_spec)
|
107
|
+
if converge_container
|
108
|
+
return converge_container
|
109
|
+
end
|
110
|
+
|
111
|
+
# Create a chef-capable container (just like the final one, but with --net=host
|
112
|
+
# and a command that keeps it open). Base it on the image.
|
113
|
+
config = container_config(action_handler, machine_spec)
|
114
|
+
config.merge!(
|
115
|
+
'name' => "chef-converge.#{machine_spec.reference['container_name']}",
|
116
|
+
'Cmd' => [ "/bin/sh", "-c", "while true;do sleep 1000; done" ],
|
24
117
|
)
|
25
|
-
|
118
|
+
# If we're using Docker Toolkit, we need to use host networking for the converge
|
119
|
+
# so we can open up the port we need. Don't force it in other cases, though.
|
120
|
+
if transport.is_local_machine(URI(transport.config[:chef_server_url]).host) &&
|
121
|
+
transport.docker_toolkit_transport(@connection.url)
|
122
|
+
config['HostConfig'] ||= {}
|
123
|
+
config['HostConfig'].merge!('NetworkMode' => 'host')
|
124
|
+
# These are incompatible with NetworkMode: host
|
125
|
+
config['HostConfig'].delete('Links')
|
126
|
+
config['HostConfig'].delete('ExtraHosts')
|
127
|
+
config.delete('NetworkSettings')
|
128
|
+
end
|
129
|
+
# Don't use any resources that need to be shared (such as exposed ports)
|
130
|
+
config.delete('ExposedPorts')
|
131
|
+
|
132
|
+
Chef::Log.debug("Creating converge container with config #{config} ...")
|
133
|
+
action_handler.perform_action "create container to converge #{machine_spec.name}" do
|
134
|
+
# create deletes the name :(
|
135
|
+
Docker::Container.create(config.dup, @connection)
|
136
|
+
converge_container = Docker::Container.get(config['name'], {}, @connection)
|
137
|
+
Chef::Log.debug("Created converge container #{converge_container.id}")
|
138
|
+
end
|
139
|
+
converge_container
|
140
|
+
end
|
141
|
+
|
142
|
+
# Commit the converged container to an image. Called by converge.
|
143
|
+
def commit_converged_image(action_handler, machine_spec, converge_container)
|
144
|
+
# Commit the converged container to an image
|
145
|
+
converged_image = nil
|
146
|
+
action_handler.perform_action "commit and delete converged container for #{machine_spec.name}" do
|
147
|
+
converged_image = converge_container.commit
|
148
|
+
converge_container.stop!
|
149
|
+
converge_container.delete
|
150
|
+
end
|
151
|
+
converged_image
|
152
|
+
end
|
153
|
+
|
154
|
+
# Create the final container from the converged image
|
155
|
+
def create_container(action_handler, machine_spec, converged_image)
|
156
|
+
# Check if the container already exists.
|
157
|
+
container = container_for(machine_spec)
|
158
|
+
if container
|
159
|
+
# If it's the same image, just return; don't stop and start.
|
160
|
+
if container.info['Image'] == converged_image.id
|
161
|
+
return container
|
162
|
+
else
|
163
|
+
# If the container exists but is based on an old image, destroy it.
|
164
|
+
action_handler.perform_action "stop and delete running container for #{machine_spec.name}" do
|
165
|
+
container.stop!
|
166
|
+
container.delete
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
26
170
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
171
|
+
# Create the new container
|
172
|
+
config = container_config(action_handler, machine_spec)
|
173
|
+
config.merge!(
|
174
|
+
'name' => machine_spec.reference['container_name'],
|
175
|
+
'Image' => converged_image.id
|
176
|
+
)
|
177
|
+
action_handler.perform_action "create final container for #{machine_spec.name}" do
|
178
|
+
container = Docker::Container.create(config, @connection)
|
31
179
|
machine_spec.reference['container_id'] = container.id
|
32
|
-
|
180
|
+
machine_spec.save(action_handler)
|
181
|
+
end
|
182
|
+
container
|
183
|
+
end
|
184
|
+
|
185
|
+
def stringize_keys(hash)
|
186
|
+
hash.each_with_object({}) do |(k,v),hash|
|
187
|
+
v = stringize_keys(v) if v.is_a?(Hash)
|
188
|
+
hash[k.to_s] = v
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def base_image(action_handler, base_image_value)
|
193
|
+
case base_image_value
|
194
|
+
when Hash
|
195
|
+
params = base_image_value.dup
|
196
|
+
if !params['fromImage']
|
197
|
+
params['fromImage'] = params.delete('name')
|
198
|
+
params['fromImage'] = "#{params['fromImage']}:#{params.delete('tag')}" if params['tag']
|
199
|
+
end
|
200
|
+
when String
|
201
|
+
params = { 'fromImage' => base_image_value }
|
202
|
+
when nil
|
203
|
+
return nil
|
204
|
+
else
|
205
|
+
raise "Unexpected type #{base_image_value.class} for docker_options[:base_image]!"
|
206
|
+
end
|
207
|
+
|
208
|
+
image_name = params['fromImage']
|
209
|
+
repo, image_name = params['fromImage'].split('/', 2) if params['fromImage'].include?('/')
|
210
|
+
|
211
|
+
begin
|
212
|
+
image = Docker::Image.get(image_name, {}, @connection)
|
213
|
+
rescue Docker::Error::NotFoundError
|
214
|
+
# If it's not found, pull it.
|
215
|
+
action_handler.perform_action "pull #{params}" do
|
216
|
+
image = Docker::Image.create(params, @connection)
|
217
|
+
end
|
33
218
|
end
|
34
|
-
|
219
|
+
|
220
|
+
image.id
|
35
221
|
end
|
36
222
|
end
|
37
223
|
end
|
@@ -0,0 +1,593 @@
|
|
1
|
+
class Chef
|
2
|
+
module Provisioning
|
3
|
+
module DockerDriver
|
4
|
+
#
|
5
|
+
# Allows the user to specify docker options that calculate the desired container config
|
6
|
+
#
|
7
|
+
# Command line options follow later in the file (search for `cli_option :command` for the first one).
|
8
|
+
#
|
9
|
+
# The API allows these settings:
|
10
|
+
#
|
11
|
+
# (https://docs.docker.com/engine/reference/api/docker_remote_api_v1.22/#create-a-container)
|
12
|
+
#
|
13
|
+
# ArgsEscaped - bool // True if command is already escaped (Windows specific)
|
14
|
+
# AttachStderr - Boolean value, attaches to stderr.
|
15
|
+
# - `docker run --attach STDERR`
|
16
|
+
# AttachStdin - Boolean value, attaches to stdin.
|
17
|
+
# - `docker run --attach STDIN`
|
18
|
+
# - `docker run --interactive`
|
19
|
+
# AttachStdout - Boolean value, attaches to stdout.
|
20
|
+
# - `docker run --attach STDOUT`
|
21
|
+
# Cmd - Command to run specified as a string or an array of strings.
|
22
|
+
# - `docker run <image> COMMAND`
|
23
|
+
# Cpuset - Deprecated please don’t use. Use CpusetCpus instead.
|
24
|
+
# Domainname - A string value containing the domain name to use for the container.
|
25
|
+
# Entrypoint - Set the entry point for the container as a string or an array of strings.
|
26
|
+
# - `docker run --entrypoint "COMMAND"`
|
27
|
+
# Env - A list of environment variables in the form of ["VAR=value"[,"VAR2=value2"]]
|
28
|
+
# - `docker --env "A=B"`
|
29
|
+
# ExposedPorts - An object mapping ports to an empty object in the form of: "ExposedPorts": { "<port>/<tcp|udp>: {}" }
|
30
|
+
# - `docker run --expose PORT`
|
31
|
+
# - `docker run --publish 8080:8081`
|
32
|
+
# HostConfig/AutoRemove - bool // Automatically remove container when it exits
|
33
|
+
# - `docker run --rm`
|
34
|
+
# HostConfig/Binds – A list of volume bindings for this container. Each volume binding is a string in one of these forms:
|
35
|
+
# - container_path to create a new volume for the container
|
36
|
+
# - host_path:container_path to bind-mount a host path into the container
|
37
|
+
# - host_path:container_path:ro to make the bind-mount read-only inside the container.
|
38
|
+
# - volume_name:container_path to bind-mount a volume managed by a volume plugin into the container.
|
39
|
+
# - volume_name:container_path:ro to make the bind mount read-only inside the container.
|
40
|
+
# - `docker run --volume /host/path:/container/path`
|
41
|
+
# HostConfig/BlkioBps - uint64 // Maximum Bytes per second for the container system drive
|
42
|
+
# HostConfig/BlkioDeviceReadBps - Limit read rate (bytes per second) from a device in the form of: "BlkioDeviceReadBps": [{"Path": "device_path", "Rate": rate}], for example: "BlkioDeviceReadBps": [{"Path": "/dev/sda", "Rate": "1024"}]"
|
43
|
+
# - `docker run --device-read-bps=/dev/sda:1mb`
|
44
|
+
# HostConfig/BlkioDeviceReadIOps - Limit read rate (IO per second) from a device in the form of: "BlkioDeviceReadIOps": [{"Path": "device_path", "Rate": rate}], for example: "BlkioDeviceReadIOps": [{"Path": "/dev/sda", "Rate": "1000"}]
|
45
|
+
# - `docker run --device-read-iops=/dev/sda:1000`
|
46
|
+
# HostConfig/BlkioDeviceWriteBps - Limit write rate (bytes per second) to a device in the form of: "BlkioDeviceWriteBps": [{"Path": "device_path", "Rate": rate}], for example: "BlkioDeviceWriteBps": [{"Path": "/dev/sda", "Rate": "1024"}]"
|
47
|
+
# - `docker run --device-write-bps=/dev/sda:1mb`
|
48
|
+
# HostConfig/BlkioDeviceWriteIOps - Limit write rate (IO per second) to a device in the form of: "BlkioDeviceWriteIOps": [{"Path": "device_path", "Rate": rate}], for example: "BlkioDeviceWriteIOps": [{"Path": "/dev/sda", "Rate": "1000"}]
|
49
|
+
# - `docker run --device-write-iops=/dev/sda:1000`
|
50
|
+
# HostConfig/BlkioIOps - uint64 // Maximum IOps for the container system drive
|
51
|
+
# HostConfig/BlkioWeight - Block IO weight (relative weight) accepts a weight value between 10 and 1000.
|
52
|
+
# - `docker run --blkio-weight 0`
|
53
|
+
# HostConfig/BlkioWeightDevice - Block IO weight (relative device weight) in the form of: "BlkioWeightDevice": [{"Path": "device_path", "Weight": weight}]
|
54
|
+
# - `docker run --blkio-weight-device path:weight`
|
55
|
+
# HostConfig/CapAdd - A list of kernel capabilities to add to the container.
|
56
|
+
# - `docker run --cap-add capability`
|
57
|
+
# HostConfig/CapDrop - A list of kernel capabilities to drop from the container.
|
58
|
+
# - `docker run --cap-drop capability`
|
59
|
+
# HostConfig/CgroupParent - Path to cgroups under which the container’s cgroup is created. If the path is not absolute, the path is considered to be relative to the cgroups path of the init process. Cgroups are created if they do not already exist.
|
60
|
+
# - `docker run --cgroup-parent parent`
|
61
|
+
# HostConfig/ConsoleSize - [2]int // Initial console size
|
62
|
+
# HostConfig/ContainerIDFile - string // File (path) where the containerId is written
|
63
|
+
# - `docker run --cidfile file`
|
64
|
+
# HostConfig/CpuPeriod - The length of a CPU period in microseconds.
|
65
|
+
# - `docker run --cpu-period 0`
|
66
|
+
# HostConfig/CpuQuota - Microseconds of CPU time that the container can get in a CPU period.
|
67
|
+
# - `docker run --cpu-quota 0`
|
68
|
+
# HostConfig/CpuShares - An integer value containing the container’s CPU Shares (ie. the relative weight vs other containers).
|
69
|
+
# - `docker run --cpu-shares 0`
|
70
|
+
# HostConfig/CpusetCpus - String value containing the cgroups CpusetCpus to use.
|
71
|
+
# - `docker run --cpuset-cpus 0-3`
|
72
|
+
# HostConfig/CpusetMems - Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems.
|
73
|
+
# - `docker run --cpuset-mems 0-3`
|
74
|
+
# HostConfig/Devices - A list of devices to add to the container specified as a JSON object in the form { "PathOnHost": "/dev/deviceName", "PathInContainer": "/dev/deviceName", "CgroupPermissions": "mrw"}
|
75
|
+
# - `docker run --device path_on_host:path_in_container:cgroup_permissions`
|
76
|
+
# HostConfig/DiskQuota - int64 // Disk limit (in bytes)
|
77
|
+
# HostConfig/Dns - A list of DNS servers for the container to use.
|
78
|
+
# - `docker run --dns ip`
|
79
|
+
# HostConfig/DnsOptions - A list of DNS options
|
80
|
+
# - `docker run --dns-opt a=b`
|
81
|
+
# HostConfig/DnsSearch - A list of DNS search domains
|
82
|
+
# - `docker run --dns-opt domain`
|
83
|
+
# HostConfig/ExtraHosts - A list of hostnames/IP mappings to add to the container’s /etc/hosts file. Specified in the form ["hostname:IP"].
|
84
|
+
# - `docker run --add-host host:ip`
|
85
|
+
# HostConfig/GroupAdd - A list of additional groups that the container process will run as
|
86
|
+
# - `docker run --group-add blah`
|
87
|
+
# HostConfig/IpcMode - IpcMode // IPC namespace to use for the container
|
88
|
+
# - `docker run --ipc host`
|
89
|
+
# HostConfig/Isolation - Isolation // Isolation technology of the container (eg default, hyperv)
|
90
|
+
# - `docker run --isolation host`
|
91
|
+
# HostConfig/KernelMemory - Kernel memory limit in bytes.
|
92
|
+
# - `docker run --kernel-memory 4m`
|
93
|
+
# HostConfig/Links - A list of links for the container. Each link entry should be in the form of container_name:alias.
|
94
|
+
# - `docker run --link containername`
|
95
|
+
# HostConfig/LogConfig - Log configuration for the container, specified as a JSON object in the form { "Type": "<driver_name>", "Config": {"key1": "val1"}}. Available types: json-file, syslog, journald, gelf, awslogs, splunk, none. json-file logging driver.
|
96
|
+
# HostConfig/LogConfig/Type
|
97
|
+
# - `docker run --log-driver driver`
|
98
|
+
# HostConfig/LogConfig/Config
|
99
|
+
# - `docker run --log-opt a=b`
|
100
|
+
# HostConfig/Memory - Memory limit in bytes.
|
101
|
+
# - `docker run --memory 4G`
|
102
|
+
# HostConfig/MemoryReservation - Memory soft limit in bytes.
|
103
|
+
# - `docker run --memory-reservation 4G`
|
104
|
+
# HostConfig/MemorySwap - Total memory limit (memory + swap); set -1 to enable unlimited swap. You must use this with memory and make the swap value larger than memory.
|
105
|
+
# - `docker run --memory-swap 4G`
|
106
|
+
# HostConfig/MemorySwappiness - Tune a container’s memory swappiness behavior. Accepts an integer between 0 and 100.
|
107
|
+
# - `docker run --memory-swappiness 50`
|
108
|
+
# HostConfig/NetworkMode - Sets the networking mode for the container. Supported standard values are: bridge, host, none, and container:<name|id>. Any other value is taken as a custom network’s name to which this container should connect to.
|
109
|
+
# - `docker run --net host`
|
110
|
+
# HostConfig/OomKillDisable - Boolean value, whether to disable OOM Killer for the container or not.
|
111
|
+
# - `docker run --oom-kill-disable`
|
112
|
+
# HostConfig/OomScoreAdj - An integer value containing the score given to the container in order to tune OOM killer preferences.
|
113
|
+
# - `docker run --oom-score-adj 1`
|
114
|
+
# HostConfig/PidMode - PidMode // PID namespace to use for the container
|
115
|
+
# - `docker run --pid host`
|
116
|
+
# HostConfig/PidsLimit - int64 // Setting pids limit for a container
|
117
|
+
# HostConfig/PortBindings - A map of exposed container ports and the host port they should map to. A JSON object in the form { <port>/<protocol>: [{ "HostPort": "<port>" }] } Take note that port is specified as a string and not an integer value.
|
118
|
+
# - `docker run --publish 8080:8081`
|
119
|
+
# HostConfig/Privileged - Gives the container full access to the host. Specified as a boolean value.
|
120
|
+
# - `docker run --privileged`
|
121
|
+
# HostConfig/PublishAllPorts - Allocates a random host port for all of a container’s exposed ports. Specified as a boolean value.
|
122
|
+
# - `docker run --publish-all`
|
123
|
+
# HostConfig/ReadonlyRootfs - Mount the container’s root filesystem as read only. Specified as a boolean value.
|
124
|
+
# - `docker run --read-only`
|
125
|
+
# HostConfig/RestartPolicy – The behavior to apply when the container exits. The value is an object with a Name property of either "always" to always restart, "unless-stopped" to restart always except when user has manually stopped the container or "on-failure" to restart only when the container exit code is non-zero. If on-failure is used, MaximumRetryCount controls the number of times to retry before giving up. The default is not to restart. (optional) An ever increasing delay (double the previous delay, starting at 100mS) is added before each restart to prevent flooding the server.
|
126
|
+
# - `docker run --restart no`
|
127
|
+
# HostConfig/RestartPolicy/Name
|
128
|
+
# - `docker run --restart always`
|
129
|
+
# HostConfig/RestartPolicy/MaximumRetryCount
|
130
|
+
# - `docker run --restart on-failure:20`
|
131
|
+
# HostConfig/SandboxSize - uint64 // System drive will be expanded to at least this size (in bytes)
|
132
|
+
# HostConfig/SecurityOpt - A list of string values to customize labels for MLS systems, such as SELinux.
|
133
|
+
# - docker run --security-opt label:disabled
|
134
|
+
# HostConfig/ShmSize - Size of /dev/shm in bytes. The size must be greater than 0. If omitted the system uses 64MB.
|
135
|
+
# - `docker run --shm-size 4m`
|
136
|
+
# HostConfig/StorageOpt - []string // Storage driver options per container.
|
137
|
+
# HostConfig/Sysctls - map[string]string // List of Namespaced sysctls used for the container
|
138
|
+
# HostConfig/Tmpfs - map[string]string // List of tmpfs (mounts) used for the container
|
139
|
+
# HostConfig/Ulimits - A list of ulimits to set in the container, specified as { "Name": <name>, "Soft": <soft limit>, "Hard": <hard limit> }, for example: Ulimits: { "Name": "nofile", "Soft": 1024, "Hard": 2048 }
|
140
|
+
# - `docker run --ulimit /dev/sda:1024:2048`
|
141
|
+
# HostConfig/UTSMode - UTSMode // UTS namespace to use for the container
|
142
|
+
# - `docker run --uts host`
|
143
|
+
# HostConfig/UsernsMode - UsernsMode // The user namespace to use for the container
|
144
|
+
# HostConfig/VolumeDriver - Driver that this container users to mount volumes.
|
145
|
+
# - `docker run --volume-driver supervolume`
|
146
|
+
# HostConfig/VolumesFrom - A list of volumes to inherit from another container. Specified in the form <container name>[:<ro|rw>]
|
147
|
+
# - `docker run --volumes-from db`
|
148
|
+
# Hostname - A string value containing the hostname to use for the container.
|
149
|
+
# - `docker run --hostname blah`
|
150
|
+
# Image - A string specifying the image name to use for the container.
|
151
|
+
# - `docker run IMAGE_NAME ...`
|
152
|
+
# Labels - Adds a map of labels to a container. To specify a map: {"key":"value"[,"key2":"value2"]}
|
153
|
+
# - `docker run --label a=b`
|
154
|
+
# MacAddress - string // Mac Address of the container
|
155
|
+
# - `docker run --mac-address 92:d0:c6:0a:29:33`
|
156
|
+
# Mounts - An array of mount points in the container.
|
157
|
+
# NetworkDisabled - Boolean value, when true disables networking for the container
|
158
|
+
# NetworkSettings/<network>/IPAMConfig/IPv4Address
|
159
|
+
# - `docker run --ip address`
|
160
|
+
# NetworkSettings/<network>/IPAMConfig/IPv6Address
|
161
|
+
# - `docker run --ip6 address`
|
162
|
+
# NetworkSettings/<network>/Aliases
|
163
|
+
# - `docker run --net-alias blah`
|
164
|
+
# OnBuild - []string // ONBUILD metadata that were defined on the image Dockerfile
|
165
|
+
# OpenStdin - Boolean value, opens stdin,
|
166
|
+
# - `docker run --interactive`
|
167
|
+
# PublishService - string // Name of the network service exposed by the container
|
168
|
+
# StdinOnce - Boolean value, close stdin after the 1 attached client disconnects.
|
169
|
+
# StopSignal - Signal to stop a container as a string or unsigned integer. SIGTERM by default.
|
170
|
+
# - `docker run --stop-signal SIGKILL`
|
171
|
+
# Tty - Boolean value, Attach standard streams to a tty, including stdin if it is not closed.
|
172
|
+
# - `docker run --tty`
|
173
|
+
# User - A string value specifying the user inside the container.
|
174
|
+
# - `docker run --user bob:wheel`
|
175
|
+
# Volumes - map[string]struct{} // List of volumes (mounts) used for the container
|
176
|
+
# - `docker run --volume blarghle`
|
177
|
+
# WorkingDir - A string specifying the working directory for commands to run in.
|
178
|
+
# - `docker run --workdir /home/uber`
|
179
|
+
#
|
180
|
+
# The following are runtime updateable:
|
181
|
+
# HostConfig/BlkioBps
|
182
|
+
# HostConfig/BlkioIOps
|
183
|
+
# HostConfig/BlkioWeight
|
184
|
+
# HostConfig/BlkioWeightDevice
|
185
|
+
# HostConfig/BlkioDeviceReadBps
|
186
|
+
# HostConfig/BlkioDeviceWriteBps
|
187
|
+
# HostConfig/BlkioDeviceReadIOps
|
188
|
+
# HostConfig/BlkioDeviceWriteIOps
|
189
|
+
# HostConfig/CgroupParent
|
190
|
+
# HostConfig/CpuPeriod
|
191
|
+
# HostConfig/CpuQuota
|
192
|
+
# HostConfig/CpuShares
|
193
|
+
# HostConfig/CpusetCpus
|
194
|
+
# HostConfig/CpusetMems
|
195
|
+
# HostConfig/Devices
|
196
|
+
# HostConfig/DiskQuota
|
197
|
+
# HostConfig/KernelMemory
|
198
|
+
# HostConfig/Memory
|
199
|
+
# HostConfig/MemoryReservation
|
200
|
+
# HostConfig/MemorySwap
|
201
|
+
# HostConfig/MemorySwappiness
|
202
|
+
# HostConfig/OomKillDisable
|
203
|
+
# HostConfig/PidsLimit
|
204
|
+
# HostConfig/RestartPolicy
|
205
|
+
# HostConfig/SandboxSize
|
206
|
+
# HostConfig/Ulimits
|
207
|
+
#
|
208
|
+
class DockerRunOptions
|
209
|
+
def self.include_command_line_options_in_container_config(config, docker_options)
|
210
|
+
|
211
|
+
# Grab the command line options we've begun supporting
|
212
|
+
# The following are command line equivalents for `docker run`
|
213
|
+
docker_options.each do |key, value|
|
214
|
+
# Remove -, symbolize key
|
215
|
+
key = key.to_s.gsub('-', '_').to_sym
|
216
|
+
option = cli_options[key]
|
217
|
+
if !option
|
218
|
+
raise "Unknown option in docker_options: #{key.inspect}"
|
219
|
+
end
|
220
|
+
|
221
|
+
# Figure out the new value
|
222
|
+
if option[:type] == :boolean
|
223
|
+
value == !!value
|
224
|
+
elsif option[:type] == Array
|
225
|
+
value = Array(value)
|
226
|
+
elsif option[:type] == Integer
|
227
|
+
value = parse_int(value) if value.is_a?(String)
|
228
|
+
elsif option[:type].is_a?(String)
|
229
|
+
# If it's A:B:C, translate [ "a:b:c", "d:e:f" ] -> [ { "A" => "a", "B" => "b", "C" => "c" }, { "A" => "d", "B" => "e", "C" => "f" } ]
|
230
|
+
names = option[:type].split(":")
|
231
|
+
if names.size == 2 && value.is_a?(Hash)
|
232
|
+
value.map { |key,value| { names[0] => key, names[1] => value } }
|
233
|
+
else
|
234
|
+
Array(value).map do |item|
|
235
|
+
item_values = item.split(":", names.size)
|
236
|
+
item = Hash[names.zip(item_values)]
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
option[:api].each do |api|
|
242
|
+
# Grab the parent API key so we know what we're setting
|
243
|
+
api_parent = config
|
244
|
+
api.split("/")[0..-2].each do |api_key|
|
245
|
+
api_parent[api_key] = {} if !api_parent[api_key]
|
246
|
+
api_parent = api_parent[api_key]
|
247
|
+
end
|
248
|
+
api_key = api.split("/")[-1] if api
|
249
|
+
|
250
|
+
# Bring in the current value
|
251
|
+
if option[:type] == Array || option[:type].is_a?(String)
|
252
|
+
api_parent[api_key] ||= []
|
253
|
+
api_parent[api_key] += value
|
254
|
+
else
|
255
|
+
api_parent[api_key] = value
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# Call the block (if any)
|
260
|
+
if option[:block]
|
261
|
+
option[:block].call(config, value)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
config
|
265
|
+
end
|
266
|
+
|
267
|
+
def self.cli_options
|
268
|
+
@cli_options ||= {}
|
269
|
+
end
|
270
|
+
|
271
|
+
def self.cli_option(option_name, type=nil, aliases: nil, api: nil, &block)
|
272
|
+
api = Array(api)
|
273
|
+
cli_options[option_name] = { type: type, api: Array(api), block: block }
|
274
|
+
Array(aliases).each do |option_name|
|
275
|
+
cli_options[option_name] = { type: type, api: Array(api), block: block }
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# docker run [OPTIONS] IMAGE COMMAND
|
280
|
+
cli_option :command do |config, command|
|
281
|
+
command = Shellwords.split(command) if command.is_a?(String)
|
282
|
+
config["Cmd"] = command
|
283
|
+
end
|
284
|
+
|
285
|
+
# docker run [OPTIONS] IMAGE COMMAND
|
286
|
+
cli_option :image, api: "Image"
|
287
|
+
|
288
|
+
# -a, --attach=[] Attach to STDIN, STDOUT or STDERR
|
289
|
+
cli_option :attach, Array, aliases: :a do |config,value|
|
290
|
+
Array(value).each do |stream|
|
291
|
+
# STDIN -> Stdin
|
292
|
+
stream = stream.to_s.downcase.capitalize
|
293
|
+
config["Attach#{stream}"] = true
|
294
|
+
end
|
295
|
+
end
|
296
|
+
# --add-host=[] Add a custom host-to-IP mapping (host:ip)
|
297
|
+
cli_option :add_host, Array, api: "HostConfig/ExtraHosts", aliases: :add_hosts
|
298
|
+
# --blkio-weight=0 Block IO weight (relative weight)
|
299
|
+
cli_option :blkio_weight, api: "HostConfig/BlkioWeight"
|
300
|
+
# --blkio-weight-device=[] Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`)
|
301
|
+
cli_option :blkio_weight, Array, api: "HostConfig/BlkioWeightDevice", aliases: :blkio_weights
|
302
|
+
# --cap-add=[] Add Linux capabilities
|
303
|
+
cli_option :cap_add, Array, api: "HostConfig/CapAdd"
|
304
|
+
# --cap-drop=[] Drop Linux capabilities
|
305
|
+
cli_option :cap_drop, Array, api: "HostConfig/CapDrop"
|
306
|
+
# --cgroup-parent="" Optional parent cgroup for the container
|
307
|
+
cli_option :cgroup_parent, api: "HostConfig/CgroupParent"
|
308
|
+
# --cidfile="" Write the container ID to the file
|
309
|
+
cli_option :cidfile, api: "HostConfig/ContainerIDFile"
|
310
|
+
# --cpu-period=0 Limit CPU CFS (Completely Fair Scheduler) period
|
311
|
+
cli_option :cpu_period, api: "HostConfig/CpuShares"
|
312
|
+
# --cpu-quota=0 Limit CPU CFS (Completely Fair Scheduler) quota
|
313
|
+
cli_option :cpu_quota, api: "HostConfig/CpuQuota"
|
314
|
+
# --cpu-shares=0 CPU shares (relative weight)
|
315
|
+
cli_option :cpu_period, api: "HostConfig/CpuPeriod"
|
316
|
+
# --cpuset-cpus="" CPUs in which to allow execution (0-3, 0,1)
|
317
|
+
cli_option :cpuset_cpus, api: "HostConfig/CpusetCpus"
|
318
|
+
# --cpuset-mems="" Memory nodes (MEMs) in which to allow execution (0-3, 0,1)
|
319
|
+
cli_option :cpuset_mems, api: "HostConfig/CpusetMems"
|
320
|
+
# --device=[] Add a host device to the container
|
321
|
+
cli_option :device, "PathOnHost:PathInContainer", api: "HostConfig/Devices", aliases: :devices
|
322
|
+
# --device-read-bps=[] Limit read rate (bytes per second) from a device (e.g., --device-read-bps=/dev/sda:1mb)
|
323
|
+
cli_option :device_read_bps, "Path:Rate", api: "HostConfig/BlkioDeviceReadBps"
|
324
|
+
# --device-read-iops=[] Limit read rate (IO per second) from a device (e.g., --device-read-iops=/dev/sda:1000)
|
325
|
+
cli_option :device_read_iops, "Path:Rate", api: "HostConfig/BlkioDeviceReadIOps"
|
326
|
+
# --device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb)
|
327
|
+
cli_option :device_write_bps, "Path:Rate", api: "HostConfig/BlkioDeviceWriteBps"
|
328
|
+
# --device-write-iops=[] Limit write rate (IO per second) to a device (e.g., --device-write-bps=/dev/sda:1000)
|
329
|
+
cli_option :device_write_iops, "Path:Rate", api: "HostConfig/BlkioDeviceWriteIOps"
|
330
|
+
# --dns=[] Set custom DNS servers
|
331
|
+
cli_option :dns, Array, api: "HostConfig/Dns"
|
332
|
+
# --dns-opt=[] Set custom DNS options
|
333
|
+
cli_option :dns_opt, Array, api: "HostConfig/DnsOptions", aliases: :dns_opts
|
334
|
+
# --dns-search=[] Set custom DNS search domains
|
335
|
+
cli_option :dns_search, Array, api: "HostConfig/DnsSearch"
|
336
|
+
# --entrypoint="" Overwrite the default ENTRYPOINT of the image
|
337
|
+
cli_option :entrypoint do |config, command|
|
338
|
+
command = Shellwords.split(command) if command.is_a?(String)
|
339
|
+
config["Entrypoint"] = command
|
340
|
+
end
|
341
|
+
# -e, --env=[] Set environment variables
|
342
|
+
cli_option :env, aliases: :e do |config, env|
|
343
|
+
if env.is_a?(Hash)
|
344
|
+
env = env.map { |k,v| "#{k}=#{v}" }
|
345
|
+
end
|
346
|
+
config["Env"] ||= []
|
347
|
+
config["Env"] += Array(env)
|
348
|
+
end
|
349
|
+
# --expose=[] Expose a port or a range of ports
|
350
|
+
cli_option :expose do |config, value|
|
351
|
+
config["ExposedPorts"] ||= {}
|
352
|
+
Array(value).each do |port|
|
353
|
+
parse_port(port).each do |host_ip, host_port, container_port|
|
354
|
+
config["ExposedPorts"][container_port] = {}
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
# --group-add=[] Add additional groups to run as
|
359
|
+
cli_option :group_add, Array, api: 'HostConfig/GroupAdd'
|
360
|
+
# -h, --hostname="" Container host name
|
361
|
+
cli_option :hostname, api: 'HostConfig/Hostname', aliases: :h
|
362
|
+
# -i, --interactive Keep STDIN open even if not attached
|
363
|
+
cli_option :interactive, :boolean, api: [ 'OpenStdin', 'AttachStdin' ]
|
364
|
+
# --ip="" Container IPv4 address (e.g. 172.30.100.104)
|
365
|
+
cli_option :ip do |config, value|
|
366
|
+
# Where this goes depends on the network! TODO doesn't work with `--net`
|
367
|
+
config["NetworkSettings"] ||= {}
|
368
|
+
network = config["NetworkMode"] || "default"
|
369
|
+
config["NetworkSettings"][network] ||= {}
|
370
|
+
config["NetworkSettings"][network]["IPAMConfig"] ||= {}
|
371
|
+
config["NetworkSettings"][network]["IPAMConfig"]["IPv4Address"] = value
|
372
|
+
end
|
373
|
+
# --ip6="" Container IPv6 address (e.g. 2001:db8::33)
|
374
|
+
cli_option :ip6 do |config, value|
|
375
|
+
# Where this goes depends on the network! TODO doesn't work with `--net`
|
376
|
+
config["NetworkSettings"] ||= {}
|
377
|
+
network = config["NetworkMode"] || "default"
|
378
|
+
config["NetworkSettings"][network] ||= {}
|
379
|
+
config["NetworkSettings"][network]["IPAMConfig"] ||= {}
|
380
|
+
config["NetworkSettings"][network]["IPAMConfig"]["IPv6Address"] = value
|
381
|
+
end
|
382
|
+
# --ipc="" IPC namespace to use
|
383
|
+
cli_option :ipc, api: 'HostConfig/IpcMode' do |config, value|
|
384
|
+
# TODO this should ONLY be set if security-opt isn't set at all.
|
385
|
+
config["HostConfig"]["SecurityOpt"] ||= [ "label:disable" ]
|
386
|
+
end
|
387
|
+
# --isolation="" Container isolation technology
|
388
|
+
cli_option :isolation, api: 'Isolation'
|
389
|
+
# --kernel-memory="" Kernel memory limit
|
390
|
+
cli_option :kernel_memory, Integer, api: 'KernelMemory'
|
391
|
+
# -l, --label=[] Set metadata on the container (e.g., --label=com.example.key=value)
|
392
|
+
cli_option :label, Array, api: "Labels", aliases: [ :l, :labels ]
|
393
|
+
# --link=[] Add link to another container
|
394
|
+
cli_option :link, Array, api: "HostConfig/Links", aliases: :links
|
395
|
+
# --log-driver="" Logging driver for container
|
396
|
+
cli_option :log_driver, api: "HostConfig/LogConfig/Type"
|
397
|
+
# --log-opt=[] Log driver specific options
|
398
|
+
cli_option :log_opt, aliases: :log_opts do |config, value|
|
399
|
+
config["HostConfig"] ||= {}
|
400
|
+
config["HostConfig"]["LogConfig"] ||= {}
|
401
|
+
config["HostConfig"]["LogConfig"]["Type"] ||= {}
|
402
|
+
Array(value).each do |keyval|
|
403
|
+
k,v = keyval.split("=", 2)
|
404
|
+
config["HostConfig"]["LogConfig"][k] = v
|
405
|
+
end
|
406
|
+
end
|
407
|
+
# --mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33)
|
408
|
+
cli_option :mac_address, api: "MacAddress"
|
409
|
+
# -m, --memory="" Memory limit
|
410
|
+
cli_option :memory, Integer, api: "HostConfig/Memory", aliases: :m
|
411
|
+
# --memory-reservation="" Memory soft limit
|
412
|
+
cli_option :memory_reservation, Integer, api: "HostConfig/MemoryReservation"
|
413
|
+
# --memory-swap="" A positive integer equal to memory plus swap. Specify -1 to enable unlimited swap.
|
414
|
+
cli_option :memory_swap, Integer, api: "HostConfig/MemorySwap"
|
415
|
+
# --memory-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
|
416
|
+
cli_option :memory_swappiness, Integer, api: "HostConfig/MemorySwappiness"
|
417
|
+
# --net="bridge" Connect a container to a network
|
418
|
+
# 'bridge': create a network stack on the default Docker bridge
|
419
|
+
# 'none': no networking
|
420
|
+
# 'container:<name|id>': reuse another container's network stack
|
421
|
+
# 'host': use the Docker host network stack
|
422
|
+
# '<network-name>|<network-id>': connect to a user-defined network
|
423
|
+
cli_option :net do |config, value|
|
424
|
+
value = value.to_s
|
425
|
+
old_network = config["NetworkMode"] || "default"
|
426
|
+
config["NetworkMode"] = value
|
427
|
+
# If we already stored stuff in the default network, move it to the new network
|
428
|
+
if config["NetworkSettings"] && config["NetworkSettings"][old_network]
|
429
|
+
config["NetworkSettings"][value] = config["NetworkSettings"].delete(old_network)
|
430
|
+
end
|
431
|
+
end
|
432
|
+
# --net-alias=[] Add network-scoped alias for the container
|
433
|
+
cli_option :net_alias, aliases: :net_aliases do |config, value|
|
434
|
+
# Where this goes depends on the network! TODO doesn't work with `--net`
|
435
|
+
config["NetworkSettings"] ||= {}
|
436
|
+
network = config["NetworkMode"] || "default"
|
437
|
+
config["NetworkSettings"][network] ||= {}
|
438
|
+
config["NetworkSettings"][network]["Aliases"] ||= []
|
439
|
+
config["NetworkSettings"][network]["Aliases"] += Array(value)
|
440
|
+
end
|
441
|
+
# --oom-kill-disable Whether to disable OOM Killer for the container or not
|
442
|
+
cli_option :oom_kill_disable, :boolean, api: "HostConfig/OomKillDisable"
|
443
|
+
# --oom-score-adj=0 Tune the host's OOM preferences for containers (accepts -1000 to 1000)
|
444
|
+
cli_option :oom_score_adj, Integer, api: "HostConfig/OomScoreAdj"
|
445
|
+
# --pid="" PID namespace to use
|
446
|
+
cli_option :pid, api: "HostConfig/PidMode" do |config, value|
|
447
|
+
# TODO this should ONLY be set if security-opt isn't set at all.
|
448
|
+
config["HostConfig"]["SecurityOpt"] ||= [ "label:disable" ]
|
449
|
+
end
|
450
|
+
# --privileged Give extended privileges to this container
|
451
|
+
cli_option :privileged, :boolean, api: "HostConfig/Privileged"
|
452
|
+
# -p, --publish=[] Publish a container's port(s) to the host
|
453
|
+
cli_option :publish, aliases: [ :p, :ports ] do |config, value|
|
454
|
+
config["HostConfig"] ||= {}
|
455
|
+
config["HostConfig"]["PortBindings"] ||= {}
|
456
|
+
config["ExposedPorts"] ||= {}
|
457
|
+
|
458
|
+
Array(value).each do |port|
|
459
|
+
parse_port(port).each do |host_ip, host_port, container_port|
|
460
|
+
config["HostConfig"]["PortBindings"][container_port] ||= []
|
461
|
+
config["HostConfig"]["PortBindings"][container_port] << { "HostIp" => host_ip, "HostPort" => host_port }
|
462
|
+
config["ExposedPorts"][container_port] = {}
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
# -P, --publish-all Publish all exposed ports to random ports
|
467
|
+
cli_option :publish_all, :boolean, api: "HostConfig/PublishAllPorts", aliases: :P
|
468
|
+
# --read-only Mount the container's root filesystem as read only
|
469
|
+
cli_option :read_only, :boolean, api: "HostConfig/ReadonlyRootfs"
|
470
|
+
# --restart="no" Restart policy (no, on-failure[:max-retry], always, unless-stopped)
|
471
|
+
cli_option :restart do |config, value|
|
472
|
+
name, retries = value.split(':')
|
473
|
+
config["HostConfig"] ||= {}
|
474
|
+
config["HostConfig"]["RestartPolicy"] ||= {}
|
475
|
+
config["HostConfig"]["RestartPolicy"]["Name"] = name
|
476
|
+
if retries
|
477
|
+
config["HostConfig"]["RestartPolicy"]["MaximumRetryCount"] = retries
|
478
|
+
else
|
479
|
+
config["HostConfig"]["RestartPolicy"].delete("MaximumRetryCount")
|
480
|
+
end
|
481
|
+
end
|
482
|
+
# --rm Automatically remove the container when it exits
|
483
|
+
cli_option :rm, :boolean, api: "HostConfig/AutoRemove"
|
484
|
+
# --shm-size=[] Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`. Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`.
|
485
|
+
cli_option :shm_size, Integer, api: "HostConfig/ShmSize", aliases: :shm_sizes
|
486
|
+
# --security-opt=[] Security Options
|
487
|
+
cli_option :security_opt, Array, api: "HostConfig/SecurityOpt", aliases: :security_opts
|
488
|
+
# --stop-signal="SIGTERM" Signal to stop a container
|
489
|
+
cli_option :stop_signal, api: "StopSignal"
|
490
|
+
# -t, --tty Allocate a pseudo-TTY
|
491
|
+
cli_option :tty, :boolean, api: "Tty", aliases: :tty
|
492
|
+
# -u, --user="" Username or UID (format: <name|uid>[:<group|gid>])
|
493
|
+
cli_option :user, api: "User", aliases: :u
|
494
|
+
# --ulimit=[] Ulimit options
|
495
|
+
cli_option :ulimit, aliases: :ulimits do |config, value|
|
496
|
+
config["HostConfig"] ||= {}
|
497
|
+
config["HostConfig"]["Ulimits"] ||= []
|
498
|
+
value.each do |ulimit|
|
499
|
+
type, values = ulimit.split("=", 2)
|
500
|
+
soft, hard = values.split(":", 2)
|
501
|
+
config["HostConfig"]["Ulimits"] << { "Name" => type, "Soft" => soft, "Hard" => hard }
|
502
|
+
end
|
503
|
+
end
|
504
|
+
# --uts="" UTS namespace to use
|
505
|
+
cli_option :uts, api: "HostConfig/UTSMode"
|
506
|
+
# -v, --volume=[host-src:]container-dest[:<options>]
|
507
|
+
# Bind mount a volume. The comma-delimited
|
508
|
+
# `options` are [rw|ro], [z|Z], or
|
509
|
+
# [[r]shared|[r]slave|[r]private]. The
|
510
|
+
# 'host-src' is an absolute path or a name
|
511
|
+
# value.
|
512
|
+
cli_option :volume, aliases: [ :v, :volumes ] do |config, value|
|
513
|
+
# Things without : in them at all, are just volumes.
|
514
|
+
binds, volumes = Array(value).partition { |v| v.include?(':') }
|
515
|
+
config["HostConfig"] ||= {}
|
516
|
+
unless binds.empty?
|
517
|
+
config["HostConfig"]["Binds"] ||= []
|
518
|
+
config["HostConfig"]["Binds"] += binds
|
519
|
+
end
|
520
|
+
unless volumes.empty?
|
521
|
+
config["Volumes"] ||= []
|
522
|
+
config["Volumes"] += volumes
|
523
|
+
end
|
524
|
+
end
|
525
|
+
# --volume-driver="" Container's volume driver
|
526
|
+
cli_option :volume_driver, api: "HostConfig/VolumeDriver"
|
527
|
+
# -w, --workdir="" Working directory inside the container
|
528
|
+
cli_option :workdir, api: "WorkingDir", aliases: :w
|
529
|
+
# --volumes-from=[] Mount volumes from the specified container(s)
|
530
|
+
cli_option :volumes_from, Array, api: 'HostConfig/VolumesFrom'
|
531
|
+
|
532
|
+
# Not relevant to API or Chef:
|
533
|
+
# -d, --detach Run container in background and print container ID
|
534
|
+
# --detach-keys Specify the escape key sequence used to detach a container
|
535
|
+
# --disable-content-trust=true Skip image verification
|
536
|
+
# --env-file=[] Read in a file of environment variables
|
537
|
+
# --help Print usage
|
538
|
+
# --label-file=[] Read in a file of labels (EOL delimited)
|
539
|
+
# --name="" Assign a name to the container
|
540
|
+
# --sig-proxy=true Proxy received signals to the process
|
541
|
+
|
542
|
+
private
|
543
|
+
|
544
|
+
# Lifted from docker cookbook
|
545
|
+
def self.parse_port(v)
|
546
|
+
parts = v.to_s.split(':')
|
547
|
+
case parts.length
|
548
|
+
when 3
|
549
|
+
host_ip = parts[0]
|
550
|
+
host_port = parts[1]
|
551
|
+
container_port = parts[2]
|
552
|
+
when 2
|
553
|
+
host_ip = '0.0.0.0'
|
554
|
+
host_port = parts[0]
|
555
|
+
container_port = parts[1]
|
556
|
+
when 1
|
557
|
+
host_ip = ''
|
558
|
+
host_port = ''
|
559
|
+
container_port = parts[0]
|
560
|
+
end
|
561
|
+
port_range, protocol = container_port.split('/')
|
562
|
+
if port_range.include?('-')
|
563
|
+
port_range = container_port.split('-')
|
564
|
+
port_range.map!(&:to_i)
|
565
|
+
Chef::Log.fatal("FATAL: Invalid port range! #{container_port}") if port_range[0] > port_range[1]
|
566
|
+
port_range = (port_range[0]..port_range[1]).to_a
|
567
|
+
end
|
568
|
+
# qualify the port-binding protocol even when it is implicitly tcp #427.
|
569
|
+
protocol = 'tcp' if protocol.nil?
|
570
|
+
Array(port_range).map do |port|
|
571
|
+
[ host_ip, host_port, "#{port}/#{protocol}"]
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
def self.parse_int(value)
|
576
|
+
value = value.upcase
|
577
|
+
if value.end_with?("TB") || value.end_with?("T")
|
578
|
+
value.to_i * 1024*1024*1024*1024
|
579
|
+
elsif value.end_with?("GB") || value.end_with?("G")
|
580
|
+
value.to_i * 1024*1024*1024
|
581
|
+
elsif value.end_with?("MB") || value.end_with?("M")
|
582
|
+
value.to_i * 1024*1024
|
583
|
+
elsif value.end_with?("KB") || value.end_with?("K")
|
584
|
+
value.to_i * 1024
|
585
|
+
else
|
586
|
+
value.to_i
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
end
|
591
|
+
end
|
592
|
+
end
|
593
|
+
end
|