Module: Spoon
- Includes:
- Methadone::CLILogging, Methadone::Main, Methadone::SH
- Defined in:
- lib/spoon.rb,
lib/spoon/version.rb
Constant Summary collapse
- VERSION =
"0.6.0"
Class Method Summary collapse
- .apply_prefix(name) ⇒ Object
- .D(message) ⇒ Object
- .docker_url ⇒ Object
- .get_all_containers ⇒ Object
- .get_container(name) ⇒ Object
- .get_port(port, container) ⇒ Object
- .get_running_containers ⇒ Object
- .host_available?(hostname, port) ⇒ Boolean
- .image_build ⇒ Object
- .image_list ⇒ Object
- .image_name(container) ⇒ Object
- .instance_connect(name, command = '') ⇒ Object
- .instance_create(name) ⇒ Object
- .instance_destroy(name) ⇒ Object
- .instance_exists?(name) ⇒ Boolean
- .instance_list ⇒ Object
- .instance_network(name) ⇒ Object
- .instance_ssh(name, command = '') ⇒ Object
- .instance_start(container) ⇒ Object
- .is_running?(container) ⇒ Boolean
- .print_docker_response(json) ⇒ Object
- .print_parsed_response(response) ⇒ Object
- .remove_prefix(name) ⇒ Object
- .strip_slash(name) ⇒ Object
Class Method Details
.apply_prefix(name) ⇒ Object
67 68 69 |
# File 'lib/spoon.rb', line 67 def self.apply_prefix(name) "#{options[:prefix]}#{name}" end |
.D(message) ⇒ Object
291 292 293 294 295 |
# File 'lib/spoon.rb', line 291 def self.D() if [:debug] puts "D: #{message}" end end |
.docker_url ⇒ Object
283 284 285 |
# File 'lib/spoon.rb', line 283 def self.docker_url Docker.url = [:url] end |
.get_all_containers ⇒ Object
234 235 236 |
# File 'lib/spoon.rb', line 234 def self.get_all_containers Docker::Container.all(:all => true) end |
.get_container(name) ⇒ Object
246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/spoon.rb', line 246 def self.get_container(name) docker_url container_list = get_all_containers l_name = strip_slash(name) container_list.each do |container| if container.info["Names"].first.to_s == "/#{l_name}" return container end end return nil end |
.get_port(port, container) ⇒ Object
287 288 289 |
# File 'lib/spoon.rb', line 287 def self.get_port(port, container) container.json['NetworkSettings']['Ports']["#{port}/tcp"].first['HostPort'] end |
.get_running_containers ⇒ Object
238 239 240 |
# File 'lib/spoon.rb', line 238 def self.get_running_containers Docker::Container.all end |
.host_available?(hostname, port) ⇒ Boolean
270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/spoon.rb', line 270 def self.host_available?(hostname, port) socket = TCPSocket.new(hostname, port) IO.select([socket], nil, nil, 5) rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, IOError sleep(0.25) false rescue Errno::EPERM, Errno::ETIMEDOUT false ensure socket && socket.close end |
.image_build ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/spoon.rb', line 75 def self.image_build # Run pre-build commands ["pre-build-commands"].each do |command| sh command end unless ["pre-build-commands"].nil? D "pre-build commands complete, building Docker image" docker_url build_opts = { 't' => [:image], 'rm' => true } docker_connection = ::Docker::Connection.new([:url], :read_timeout => 3000) Docker::Image.build_from_dir([:builddir], build_opts, docker_connection) do |chunk| print_docker_response(chunk) end end |
.image_list ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/spoon.rb', line 91 def self.image_list docker_url Docker::Image.all.each do |image| next if image.info["RepoTags"] == ["<none>:<none>"] puts "Image: #{image.info["RepoTags"]}" end end |
.image_name(container) ⇒ Object
151 152 153 154 |
# File 'lib/spoon.rb', line 151 def self.image_name(container) env = Hash[container.json['Config']['Env'].collect { |v| v.split('=') }] return env['IMAGE_NAME'] || container.json['Config']['Image'].split(':').first end |
.instance_connect(name, command = '') ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/spoon.rb', line 121 def self.instance_connect(name, command='') docker_url if not instance_exists? name puts "The `#{name}` container doesn't exist, creating..." instance_create(name) end container = get_container(name) unless is_running?(container) instance_start(container) end puts "Connecting to `#{name}`" instance_ssh(name, command) end |
.instance_create(name) ⇒ Object
259 260 261 262 263 264 265 266 267 268 |
# File 'lib/spoon.rb', line 259 def self.instance_create(name) docker_url container = Docker::Container.create({ 'Image' => [:image], 'name' => name, 'Entrypoint' => 'runit', 'Hostname' => remove_prefix(name) }) container = container.start({ 'PublishAllPorts' => true }) end |
.instance_destroy(name) ⇒ Object
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/spoon.rb', line 192 def self.instance_destroy(name) docker_url container = get_container(name) if container puts "Destroying #{name}" begin container.kill rescue puts "Failed to kill container #{container.id}" end container.wait(10) begin container.delete(:force => true) rescue puts "Failed to remove container #{container.id}" end puts "Done!" else puts "No container named: #{name}" end end |
.instance_exists?(name) ⇒ Boolean
217 218 219 |
# File 'lib/spoon.rb', line 217 def self.instance_exists?(name) get_container(name) end |
.instance_list ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/spoon.rb', line 137 def self.instance_list docker_url puts "List of available spoon containers:" container_list = get_all_containers.select { |c| c.info["Names"].first.to_s.start_with? "/#{options[:prefix]}" } .sort { |c1, c2| c1.info["Names"].first.to_s <=> c2.info["Names"].first.to_s } max_width_container_name = remove_prefix(container_list.max_by {|c| c.info["Names"].first.to_s.length }.info["Names"].first.to_s) max_name_width = max_width_container_name.length container_list.each do |container| name = container.info["Names"].first.to_s running = is_running?(container) ? Rainbow("Running").green : Rainbow("Stopped").red puts "#{remove_prefix(name)} [ #{running} ]".rjust(max_name_width + 22) + " " + Rainbow(image_name(container)).yellow end end |
.instance_network(name) ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/spoon.rb', line 174 def self.instance_network(name) docker_url container = get_container(name) if is_running?(container) host = URI.parse([:url]).host puts "Host: #{host}" ports = container.json['NetworkSettings']['Ports'] ports.each do |p_name, p_port| tcp_name = p_name.split('/')[0] puts "#{tcp_name} -> #{p_port.first['HostPort']}" end else puts "Container is not running, cannot show ports" end end |
.instance_ssh(name, command = '') ⇒ Object
221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/spoon.rb', line 221 def self.instance_ssh(name, command='') container = get_container(name) host = URI.parse([:url]).host if container ssh_command = "\"#{command}\"" if not command.empty? ssh_port = get_port('22', container) puts "Waiting for #{name}:#{ssh_port}..." until host_available?(host, ssh_port) exec("ssh -t -o StrictHostKeyChecking=no -p #{ssh_port} pairing@#{host} #{ssh_command}") else puts "No container named: #{container.inspect}" end end |
.instance_start(container) ⇒ Object
242 243 244 |
# File 'lib/spoon.rb', line 242 def self.instance_start(container) container.start! end |
.is_running?(container) ⇒ Boolean
164 165 166 167 168 169 170 171 172 |
# File 'lib/spoon.rb', line 164 def self.is_running?(container) container = Docker::Container.get(container.info["id"]) status = container.info["State"]["Running"] || nil unless status.nil? return status else return false end end |
.print_docker_response(json) ⇒ Object
117 118 119 |
# File 'lib/spoon.rb', line 117 def self.print_docker_response(json) print_parsed_response(JSON.parse(json)) end |
.print_parsed_response(response) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/spoon.rb', line 99 def self.print_parsed_response(response) case response when Hash response.each do |key, value| case key when 'stream' puts value else puts "#{key}: #{value}" end end when Array response.each do |hash| print_parsed_response(hash) end end end |
.remove_prefix(name) ⇒ Object
71 72 73 |
# File 'lib/spoon.rb', line 71 def self.remove_prefix(name) name.gsub(/\/?#{options[:prefix]}/, '') end |
.strip_slash(name) ⇒ Object
156 157 158 159 160 161 162 |
# File 'lib/spoon.rb', line 156 def self.strip_slash(name) if name.start_with? "/" name[1..-1] else name end end |