Class: Chef::Provisioning::DockerDriver::Driver

Inherits:
Chef::Provisioning::Driver
  • Object
show all
Includes:
Mixin::ShellOut
Defined in:
lib/chef/provisioning/docker_driver/driver.rb

Overview

Provisions machines using Docker

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(driver_url, config) ⇒ Driver

Returns a new instance of Driver.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 35

def initialize(driver_url, config)
  super
  url = Driver.connection_url(driver_url)

  if url
    # Export this as it's expected
    # to be set for command-line utilities
    ENV['DOCKER_HOST'] = url
    Chef::Log.debug("Setting Docker URL to #{url}")
  end

  ENV['DOCKER_HOST'] ||= url if url
  Docker.logger = Chef::Log
  options = Docker.options.dup || {}
  options.merge!(read_timeout: 600)
  options.merge!(config[:docker_connection].hash_dup) if config && config[:docker_connection]
  @connection = Docker::Connection.new(url || Docker.url, options)
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



22
23
24
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 22

def connection
  @connection
end

Class Method Details

.canonicalize_url(driver_url, config) ⇒ Object



54
55
56
57
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 54

def self.canonicalize_url(driver_url, config)
  url = Driver.connection_url(driver_url)
  [ "docker:#{url}", config ]
end

.connection_url(driver_url) ⇒ Object

Parse the url from a URL, try to clean it up Returns a proper URL from the driver_url string. Examples include:

docker:/var/run/docker.sock => unix:///var/run/docker.sock
docker:192.168.0.1:1234 => tcp://192.168.0.1:1234


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 63

def self.connection_url(driver_url)
  scheme, url = driver_url.split(':', 2)

  if url && url.size > 0
    # Clean up the URL with the protocol if needed (within reason)
    case url
    when /^\d+\.\d+\.\d+\.\d+:\d+$/
      "tcp://#{url}"
    when /^\//
      "unix://#{url}"
    when /^(tcp|unix)/
      url
    else
      "tcp://#{url}"
    end
  end
end

.from_url(driver_url, config) ⇒ Object

URL scheme: docker:<path> canonical URL calls realpath on <path>



27
28
29
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 27

def self.from_url(driver_url, config)
  Driver.new(driver_url, config)
end

Instance Method Details

#allocate_image(action_handler, image_spec, image_options, machine_spec, machine_options) ⇒ Object

Images



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 153

def allocate_image(action_handler, image_spec, image_options, machine_spec, machine_options)
  tag_container_image(action_handler, machine_spec, image_spec)

  # Set machine options on the image to match our newly created image
  image_spec.reference = {
    'driver_url' => driver_url,
    'driver_version' => Chef::Provisioning::DockerDriver::VERSION,
    'allocated_at' => Time.now.to_i,
    'docker_options' => {
      'base_image' => {
        'name' => image_spec.name
      }
    }
  }

  # Workaround for chef/chef-provisioning-docker#37
  machine_spec.attrs[:keep_image] = true
end

#allocate_machine(action_handler, machine_spec, machine_options) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 81

def allocate_machine(action_handler, machine_spec, machine_options)
  machine_spec.from_image = from_image_from_action_handler(
    action_handler,
    machine_spec
  )

  # Grab options from existing machine (TODO seems wrong) and set the machine_spec to that
  docker_options = machine_options[:docker_options]
  container_id = nil
  image_id = machine_options[:image_id]
  if machine_spec.reference
    container_name = machine_spec.reference['container_name']
    container_id = machine_spec.reference['container_id']
    image_id ||= machine_spec.reference['image_id']
    docker_options ||= machine_spec.reference['docker_options']
  end
  container_name ||= machine_spec.name
  machine_spec.reference = {
    'driver_url' => driver_url,
    'driver_version' => Chef::Provisioning::DockerDriver::VERSION,
    'allocated_at' => Time.now.utc.to_s,
    'host_node' => action_handler.host_node,
    'container_name' => container_name,
    'image_id' => image_id,
    'docker_options' => stringize_keys(docker_options),
    'container_id' => container_id
  }
end

#connect_to_machine(machine_spec, machine_options) ⇒ Object

Connect to machine without acquiring it



124
125
126
127
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 124

def connect_to_machine(machine_spec, machine_options)
  Chef::Log.debug('Connect to machine')
  machine_for(machine_spec, machine_options)
end

#destroy_image(action_handler, image_spec, image_options, machine_options = {}) ⇒ Object



177
178
179
180
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 177

def destroy_image(action_handler, image_spec, image_options, machine_options={})
  image = image_for(image_spec)
  image.delete unless image.nil?
end

#destroy_machine(action_handler, machine_spec, machine_options) ⇒ Object



129
130
131
132
133
134
135
136
137
138
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 129

def destroy_machine(action_handler, machine_spec, machine_options)
  container = container_for(machine_spec)
  if container
    image_id = container.info['Image']
    action_handler.perform_action "stop and destroy container #{machine_spec.name}" do
      container.stop
      container.delete
    end
  end
end

#driver_urlObject



31
32
33
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 31

def driver_url
  "docker:#{Docker.url}"
end

#ready_image(action_handler, image_spec, image_options) ⇒ Object



172
173
174
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 172

def ready_image(action_handler, image_spec, image_options)
  Chef::Log.debug('READY IMAGE!')
end

#ready_machine(action_handler, machine_spec, machine_options) ⇒ Object



110
111
112
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 110

def ready_machine(action_handler, machine_spec, machine_options)
  machine_for(machine_spec, machine_options)
end

#start_machine(action_handler, machine_spec, machine_options) ⇒ Object



114
115
116
117
118
119
120
121
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 114

def start_machine(action_handler, machine_spec, machine_options)
  container = container_for(machine_spec)
  if container && !container.info['State']['Running']
    action_handler.perform_action "start container #{machine_spec.name}" do
      container.start!
    end
  end
end

#stop_machine(action_handler, machine_spec, machine_options) ⇒ Object



140
141
142
143
144
145
146
147
# File 'lib/chef/provisioning/docker_driver/driver.rb', line 140

def stop_machine(action_handler, machine_spec, machine_options)
  container = container_for(machine_spec)
  if container.info['State']['Running']
    action_handler.perform_action "stop container #{machine_spec.name}" do
      container.stop!
    end
  end
end