Class BoxGrinder::ElasticHostsPlugin
In: lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb
lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb
Parent: BasePlugin

Methods

Public Instance methods

[Source]

    # 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

[Source]

    # 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

[Source]

     # 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

[Source]

     # 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

[Source]

    # 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

[Source]

    # 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

[Source]

     # 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 occurred while creating the server, #{e.message}. See logs for more info."
209:       end
210:     end

Creates the server for previously uploaded disk

[Source]

     # 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 occurred while creating the server, #{e.message}. See logs for more info."
209:       end
210:     end

[Source]

    # 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

[Source]

    # 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

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 41
41:     def execute
42:       upload
43:       create_server
44:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 41
41:     def execute
42:       upload
43:       create_server
44:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 52
52:     def hash_to_request(h)
53:       body = ""
54: 
55:       h.sort.each do |k, v|
56:         body << "#{k} #{v.to_s}\n"
57:       end
58: 
59:       body
60:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 52
52:     def hash_to_request(h)
53:       body = ""
54: 
55:       h.sort.each do |k, v|
56:         body << "#{k} #{v.to_s}\n"
57:       end
58: 
59:       body
60:     end

[Source]

     # 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

[Source]

     # 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

[Source]

    # 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

[Source]

    # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

    # 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

[Source]

    # 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

[Validate]