class EzPaaS::Helpers::ContainerManager
Attributes
connection[R]
slug_dir[R]
Public Class Methods
new()
click to toggle source
# File lib/ezpaas/helpers/container_manager.rb, line 18 def initialize ensure_paths end
Public Instance Methods
create_slug(src_tar_stream, emitter = nil)
click to toggle source
# File lib/ezpaas/helpers/container_manager.rb, line 22 def create_slug(src_tar_stream, emitter = nil) temp_tar = Tempfile.new('ezpaas') # Temporary place to copy the slug tarball emitter.emit :message, '-----> Creating slug compilation container' if emitter container = Docker::Container.create({'Image' => 'deis/slugbuilder', 'OpenStdin' => true, 'StdinOnce' => true}, connection) begin # Start the container emitter.emit :message, '-----> Starting slug compilation container' if emitter container.start # Redirect container output to HTTP stream container.attach(stdin: src_tar_stream) do |_fd, chunk| emitter.emit :message, chunk if emitter end # Wait for container to finish compiling the slug container.wait # Kill the container emitter.emit :message, '-----> Stopping slug compilation container' if emitter begin container.stop end # Copy the tarred slug out of the container emitter.emit :message, "-----> Temporarily copying slug from container to #{temp_tar.path}" if emitter container.copy('/tmp/slug.tgz') { |chunk| temp_tar.write(chunk) } temp_tar.rewind # rewind the temp file for immediate reading # Decompress the tarred slug to our final destination slug_name = SecureRandom.uuid slug_destination = slug_path(slug_name) emitter.emit :message, "-----> Untarring slug to #{slug_destination}" if emitter tar_extract = Gem::Package::TarReader.new(temp_tar) slug_entry = tar_extract.find { |e| e.full_name == 'slug.tgz' } File.open(slug_destination, 'wb') do |file| File.ez_cp(slug_entry, file) end temp_tar.close rescue Exception => ex raise else slug_name ensure emitter.emit :message, "-----> Removing container" if emitter # Try to remove the container begin container.remove rescue raise end emitter.emit :message, "-----> Deleting temporary files" if emitter temp_tar.close temp_tar.unlink end end
deploy_app(name, slug, config, emitter = nil)
click to toggle source
# File lib/ezpaas/helpers/container_manager.rb, line 83 def deploy_app(name, slug, config, emitter = nil) emitter.emit :message, "-----> Creating temporary slug container to snapshot" if emitter # Load the slug into a temporary container to produce an image slug_labels = { 'com.tendigi.appname' => name, } slug_file = File.open(slug_path(slug), 'rb') slug_container = Docker::Container.create({'Image' => 'deis/slugrunner', 'OpenStdin' => true, 'StdinOnce' => true, 'Labels' => slug_labels}, connection) slug_container.start slug_container.attach(stdin: slug_file) do |_fd, chunk| # puts chunk end slug_image_name = "ezpass/#{name}" emitter.emit :message, "-----> Imaging container #{slug_container.id}" if emitter slug_image = slug_container.commit(repo: slug_image_name, 'Labels' => slug_labels) emitter.emit :message, "-----> Created slug image #{slug_image.id}" if emitter slug_container.remove(force: true) emitter.emit :message, "-----> Removing temporary slug container #{slug_container.id}" if emitter emitter.emit :message, "-----> Starting deployment..." if emitter # Start up instances using that image config.each do |process, count| # iterate over the desired number of instances for i in 0 ... count container_name = "#{name}-#{process}-#{i}" labels = { 'com.tendigi.appname' => name, 'com.tendigi.instance' => container_name, 'com.tendigi.slug' => slug, 'com.tendigi.process' => process } container = slug_image.run("start #{process}", { name: container_name, 'Labels' => labels, 'PublishAllPorts' => true }) emitter.emit :message, "-----> Deployed container #{i + 1} for process type `#{process}`: #{container.id}" if emitter end end end
http_destinations(name)
click to toggle source
# File lib/ezpaas/helpers/container_manager.rb, line 151 def http_destinations(name) containers = Docker::Container.all(filters: { label: [ "com.tendigi.appname=#{name}", "com.tendigi.process=web"] }.to_json) ports = {} for container in containers for port_info in (container.info['Ports'] || []) if port_info['PrivatePort'] == 5000 ports[container.id] = port_info['PublicPort'] end end end ports end
pull_images()
click to toggle source
# File lib/ezpaas/helpers/container_manager.rb, line 179 def pull_images images = [ 'deis/slugbuilder', 'deis/slugrunner' ] puts images.each do |name| pastel = Pastel.new puts 'Downloading latest image: ' + pastel.blue(name) Docker::Image.create({'fromImage' => name, 'tag' => 'latest'}, connection) do |chunk| fragments = chunk.split "\r\n" fragments.each do |fragment| data = JSON.parse(fragment) if id = data['id'] # puts "#{id}: #{data['status']}" #off for now else puts pastel.green(data['status'].rstrip) end end end puts end end
read_procfile(slug_name)
click to toggle source
# File lib/ezpaas/helpers/container_manager.rb, line 167 def read_procfile(slug_name) tar_extract = Gem::Package::TarReader.new(Zlib::GzipReader.open(slug_path(slug_name))) tar_extract.rewind # The extract has to be rewinded after every iteration tar_extract.each do |entry| if entry.full_name == './Procfile' && entry.file? return YAML.load(entry.read) end end ensure tar_extract.close end
undeploy_app(name, emitter = nil)
click to toggle source
# File lib/ezpaas/helpers/container_manager.rb, line 129 def undeploy_app(name, emitter = nil) emitter.emit :message, "-----> Un-deploying #{name}" if emitter containers = Docker::Container.all(all: true, filters: { label: [ "com.tendigi.appname=#{name}" ] }.to_json) containers.each do |c| emitter.emit :message, "-----> Removing container #{c.id}" if emitter c.remove(force: true) end emitter.emit :message, "-----> Deleting slug images for #{name}" if emitter images = Docker::Image.all(all: true, filters: { label: [ "com.tendigi.appname=#{name}" ] }.to_json) images.each do |i| emitter.emit :message, "-----> Removing image #{i.id}" if emitter i.remove end end
Private Instance Methods
ensure_paths()
click to toggle source
# File lib/ezpaas/helpers/container_manager.rb, line 221 def ensure_paths @slug_dir ||= File.join(EzPaaS::Helpers::Config.data_dir, 'slugs') FileUtils.mkdir_p @slug_dir end
slug_path(slug_name)
click to toggle source
# File lib/ezpaas/helpers/container_manager.rb, line 226 def slug_path(slug_name) File.join(slug_dir, slug_name + '.tgz') end