Class | BoxGrinder::ElasticHostsPlugin |
In: |
lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb
lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb |
Parent: | BasePlugin |
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 96 96: def api_url(path) 97: "#{@plugin_config['ssl'] ? 'https' : 'http'}://#{CGI.escape(@plugin_config['username'])}:#{@plugin_config['password']}@#{@plugin_config['endpoint']}#{path}" 98: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 96 96: def api_url(path) 97: "#{@plugin_config['ssl'] ? 'https' : 'http'}://#{CGI.escape(@plugin_config['username'])}:#{@plugin_config['password']}@#{@plugin_config['endpoint']}#{path}" 98: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 132 132: def compress(data) 133: @log.trace "Compressing #{data.size / 1024} kB chunk of data..." 134: 135: io = StringIO.new 136: 137: writer = Zlib::GzipWriter.new(io, Zlib::DEFAULT_COMPRESSION, Zlib::FINISH) 138: writer.write(data) 139: writer.close 140: 141: @log.trace "Data compressed to #{io.size / 1024} kB." 142: 143: io.string 144: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 132 132: def compress(data) 133: @log.trace "Compressing #{data.size / 1024} kB chunk of data..." 134: 135: io = StringIO.new 136: 137: writer = Zlib::GzipWriter.new(io, Zlib::DEFAULT_COMPRESSION, Zlib::FINISH) 138: writer.write(data) 139: writer.close 140: 141: @log.trace "Data compressed to #{io.size / 1024} kB." 142: 143: io.string 144: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 72 72: def create_remote_disk 73: size = disk_size 74: 75: @log.info "Creating new #{size} GB disk..." 76: 77: 78: body = hash_to_request( 79: 'size' => size * 1024 *1024 * 1024, 80: 'name' => @plugin_config['drive_name'] 81: ) 82: 83: begin 84: ret = response_to_hash(RestClient.post(api_url('/drives/create'), body)) 85: 86: 87: @log.info "Disk created with UUID: #{ret['drive']}." 88: rescue => e 89: @log.error e.info 90: raise PluginError, "An error occured while creating the drive, #{e.message}. See logs for more info." 91: end 92: 93: ret['drive'] 94: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 72 72: def create_remote_disk 73: size = disk_size 74: 75: @log.info "Creating new #{size} GB disk..." 76: 77: 78: body = hash_to_request( 79: 'size' => size * 1024 *1024 * 1024, 80: 'name' => @plugin_config['drive_name'] 81: ) 82: 83: begin 84: ret = response_to_hash(RestClient.post(api_url('/drives/create'), body)) 85: 86: 87: @log.info "Disk created with UUID: #{ret['drive']}." 88: rescue => e 89: @log.error e.info 90: raise PluginError, "An error occured while creating the drive, #{e.message}. See logs for more info." 91: end 92: 93: ret['drive'] 94: end
Creates the server for previously uploaded disk
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 182 182: def create_server 183: @log.info "Creating new server..." 184: 185: memory = ((is_cloudsigma? and @appliance_config.hardware.memory < 512) ? 512 : @appliance_config.hardware.memory) 186: 187: body = hash_to_request( 188: 'name' => "#{@appliance_config.name}-#{@appliance_config.version}.#{@appliance_config.release}", 189: 'cpu' => @appliance_config.hardware.cpus * 1000, # MHz 190: 'smp' => 'auto', 191: 'mem' => memory, 192: 'persistent' => 'true', # hack 193: 'ide:0:0' => @plugin_config['drive_uuid'], 194: 'boot' => 'ide:0:0', 195: 'nic:0:model' => 'e1000', 196: 'nic:0:dhcp' => 'auto', 197: 'vnc:ip' => 'auto', 198: 'vnc:password' => (0...8).map { (('a'..'z').to_a + ('A'..'Z').to_a)[rand(52)] }.join # 8 character VNC password 199: ) 200: 201: begin 202: path = is_cloudsigma? ? '/servers/create' : '/servers/create/stopped' 203: ret = response_to_hash(RestClient.post(api_url(path), body)) 204: 205: @log.info "Server was registered with '#{ret['name']}' name as '#{ret['server']}' UUID. Use web UI or API tools to start your server." 206: rescue => e 207: @log.error e.info 208: raise PluginError, "An error occured while creating the server, #{e.message}. See logs for more info." 209: end 210: end
Creates the server for previously uploaded disk
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 182 182: def create_server 183: @log.info "Creating new server..." 184: 185: memory = ((is_cloudsigma? and @appliance_config.hardware.memory < 512) ? 512 : @appliance_config.hardware.memory) 186: 187: body = hash_to_request( 188: 'name' => "#{@appliance_config.name}-#{@appliance_config.version}.#{@appliance_config.release}", 189: 'cpu' => @appliance_config.hardware.cpus * 1000, # MHz 190: 'smp' => 'auto', 191: 'mem' => memory, 192: 'persistent' => 'true', # hack 193: 'ide:0:0' => @plugin_config['drive_uuid'], 194: 'boot' => 'ide:0:0', 195: 'nic:0:model' => 'e1000', 196: 'nic:0:dhcp' => 'auto', 197: 'vnc:ip' => 'auto', 198: 'vnc:password' => (0...8).map { (('a'..'z').to_a + ('A'..'Z').to_a)[rand(52)] }.join # 8 character VNC password 199: ) 200: 201: begin 202: path = is_cloudsigma? ? '/servers/create' : '/servers/create/stopped' 203: ret = response_to_hash(RestClient.post(api_url(path), body)) 204: 205: @log.info "Server was registered with '#{ret['name']}' name as '#{ret['server']}' UUID. Use web UI or API tools to start your server." 206: rescue => e 207: @log.error e.info 208: raise PluginError, "An error occured while creating the server, #{e.message}. See logs for more info." 209: end 210: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 46 46: def disk_size 47: size = 0 48: @appliance_config.hardware.partitions.each_value { |partition| size += partition['size'] } 49: size 50: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 46 46: def disk_size 47: size = 0 48: @appliance_config.hardware.partitions.each_value { |partition| size += partition['size'] } 49: size 50: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 41 41: def execute 42: upload 43: create_server 44: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 41 41: def execute 42: upload 43: create_server 44: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 52 52: def hash_to_request(h) 53: body = "" 54: 55: h.each do |k, v| 56: body << "#{k} #{v.to_s}\n" 57: end 58: 59: body 60: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 52 52: def hash_to_request(h) 53: body = "" 54: 55: h.each do |k, v| 56: body << "#{k} #{v.to_s}\n" 57: end 58: 59: body 60: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 177 177: def is_cloudsigma? 178: !@plugin_config['endpoint'].match(/cloudsigma\.com$/).nil? 179: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 177 177: def is_cloudsigma? 178: !@plugin_config['endpoint'].match(/cloudsigma\.com$/).nil? 179: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 62 62: def response_to_hash(r) 63: h = {} 64: 65: r.each_line do |l| 66: h[$1] = $2 if l =~ /(\w+) (.*)/ 67: end 68: 69: h 70: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 62 62: def response_to_hash(r) 63: h = {} 64: 65: r.each_line do |l| 66: h[$1] = $2 if l =~ /(\w+) (.*)/ 67: end 68: 69: h 70: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 100 100: def upload 101: @log.info "Uploading appliance..." 102: 103: # Create the disk with specific size or use already existing 104: @plugin_config['drive_uuid'] = create_remote_disk unless @plugin_config['drive_uuid'] 105: 106: upload_chunks 107: 108: @log.info "Appliance uploaded." 109: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 100 100: def upload 101: @log.info "Uploading appliance..." 102: 103: # Create the disk with specific size or use already existing 104: @plugin_config['drive_uuid'] = create_remote_disk unless @plugin_config['drive_uuid'] 105: 106: upload_chunks 107: 108: @log.info "Appliance uploaded." 109: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 146 146: def upload_chunk(data, part) 147: try = 1 148: 149: url = api_url("/drives/#{@plugin_config['drive_uuid']}/write/#{@step * part}") 150: 151: begin 152: @log.info "Uploading part #{part+1}..." 153: 154: headers = {:content_type => "application/octet-stream"} 155: headers['Content-Encoding'] = 'gzip' unless is_cloudsigma? 156: 157: RestClient.post url, 158: data, 159: headers 160: 161: @log.info "Part #{part+1} uploaded." 162: rescue => e 163: @log.warn "An error occured while uploading #{part} chunk, #{e.message}" 164: try += 1 165: 166: unless try > @plugin_config['retry'] 167: # Let's sleep for specified amount of time 168: sleep @plugin_config['wait'] 169: retry 170: else 171: @log.error e.info 172: raise PluginError, "Couldn't upload appliance, #{e.message}." 173: end 174: end 175: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 146 146: def upload_chunk(data, part) 147: try = 1 148: 149: url = api_url("/drives/#{@plugin_config['drive_uuid']}/write/#{@step * part}") 150: 151: begin 152: @log.info "Uploading part #{part+1}..." 153: 154: headers = {:content_type => "application/octet-stream"} 155: headers['Content-Encoding'] = 'gzip' unless is_cloudsigma? 156: 157: RestClient.post url, 158: data, 159: headers 160: 161: @log.info "Part #{part+1} uploaded." 162: rescue => e 163: @log.warn "An error occured while uploading #{part} chunk, #{e.message}" 164: try += 1 165: 166: unless try > @plugin_config['retry'] 167: # Let's sleep for specified amount of time 168: sleep @plugin_config['wait'] 169: retry 170: else 171: @log.error e.info 172: raise PluginError, "Couldn't upload appliance, #{e.message}." 173: end 174: end 175: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 111 111: def upload_chunks 112: @step = @plugin_config['chunk'] * 1024 * 1024 # in bytes 113: part = @plugin_config['start_part'] 114: 115: @log.info "Uploading disk in #{disk_size * 1024 / @plugin_config['chunk']} parts." 116: 117: File.open(@previous_deliverables.disk, 'rb') do |f| 118: while !f.eof? 119: f.seek(part * @step, File::SEEK_SET) 120: 121: data = f.read(@step) 122: data = compress(data) unless is_cloudsigma? 123: upload_chunk(data, part) 124: 125: part += 1 126: end 127: end 128: 129: @log.info "Appliance #{@appliance_config.name} uploaded to drive with UUID #{@plugin_config['drive_uuid']}." 130: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 111 111: def upload_chunks 112: @step = @plugin_config['chunk'] * 1024 * 1024 # in bytes 113: part = @plugin_config['start_part'] 114: 115: @log.info "Uploading disk in #{disk_size * 1024 / @plugin_config['chunk']} parts." 116: 117: File.open(@previous_deliverables.disk, 'rb') do |f| 118: while !f.eof? 119: f.seek(part * @step, File::SEEK_SET) 120: 121: data = f.read(@step) 122: data = compress(data) unless is_cloudsigma? 123: upload_chunk(data, part) 124: 125: part += 1 126: end 127: end 128: 129: @log.info "Appliance #{@appliance_config.name} uploaded to drive with UUID #{@plugin_config['drive_uuid']}." 130: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 29 29: def validate 30: set_default_config_value('chunk', 64) # chunk size in MB 31: set_default_config_value('start_part', 0) # part number to start uploading 32: set_default_config_value('wait', 5) # wait time before retrying upload 33: set_default_config_value('retry', 3) # number of retries 34: set_default_config_value('ssl', false) # use SSL? 35: set_default_config_value('drive_name', @appliance_config.name) 36: 37: validate_plugin_config(['endpoint', 'username', 'password'], 'http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#ElasticHosts_Delivery_Plugin') 38: raise PluginValidationError, "You can use ElasticHosts plugin with base appliances (appliances created with operating system plugins) only, see http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#ElasticHosts_Delivery_Plugin." unless @previous_plugin_info[:type] == :os 39: end
# File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 29 29: def validate 30: set_default_config_value('chunk', 64) # chunk size in MB 31: set_default_config_value('start_part', 0) # part number to start uploading 32: set_default_config_value('wait', 5) # wait time before retrying upload 33: set_default_config_value('retry', 3) # number of retries 34: set_default_config_value('ssl', false) # use SSL? 35: set_default_config_value('drive_name', @appliance_config.name) 36: 37: validate_plugin_config(['endpoint', 'username', 'password'], 'http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#ElasticHosts_Delivery_Plugin') 38: raise PluginValidationError, "You can use ElasticHosts plugin with base appliances (appliances created with operating system plugins) only, see http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#ElasticHosts_Delivery_Plugin." unless @previous_plugin_info[:type] == :os 39: end