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 26
26:     def after_init
27:       set_default_config_value('chunk', 64) # chunk size in MB
28:       set_default_config_value('start_part', 0) # part number to start uploading
29:       set_default_config_value('wait', 5) # wait time before retrying upload
30:       set_default_config_value('retry', 3) # number of retries
31:       set_default_config_value('ssl', false) # use SSL?
32:       set_default_config_value('drive_name', @appliance_config.name)
33:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 26
26:     def after_init
27:       set_default_config_value('chunk', 64) # chunk size in MB
28:       set_default_config_value('start_part', 0) # part number to start uploading
29:       set_default_config_value('wait', 5) # wait time before retrying upload
30:       set_default_config_value('retry', 3) # number of retries
31:       set_default_config_value('ssl', false) # use SSL?
32:       set_default_config_value('drive_name', @appliance_config.name)
33:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 94
94:     def api_url(path)
95:       "#{@plugin_config['ssl'] ? 'https' : 'http'}://#{CGI.escape(@plugin_config['username'])}:#{@plugin_config['password']}@#{@plugin_config['endpoint']}#{path}"
96:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 94
94:     def api_url(path)
95:       "#{@plugin_config['ssl'] ? 'https' : 'http'}://#{CGI.escape(@plugin_config['username'])}:#{@plugin_config['password']}@#{@plugin_config['endpoint']}#{path}"
96:     end

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 129
129:     def compress(data)
130:       @log.trace "Compressing #{data.size / 1024} kB chunk of data..."
131: 
132:       io = StringIO.new
133: 
134:       writer = Zlib::GzipWriter.new(io, Zlib::DEFAULT_COMPRESSION, Zlib::FINISH)
135:       writer.write(data)
136:       writer.close
137: 
138:       @log.trace "Data compressed to #{io.size / 1024} kB."
139: 
140:       io.string
141:     end

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 129
129:     def compress(data)
130:       @log.trace "Compressing #{data.size / 1024} kB chunk of data..."
131: 
132:       io = StringIO.new
133: 
134:       writer = Zlib::GzipWriter.new(io, Zlib::DEFAULT_COMPRESSION, Zlib::FINISH)
135:       writer.write(data)
136:       writer.close
137: 
138:       @log.trace "Data compressed to #{io.size / 1024} kB."
139: 
140:       io.string
141:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 70
70:     def create_remote_disk
71:       size = disk_size
72: 
73:       @log.info "Creating new #{size} GB disk..."
74: 
75: 
76:       body = hash_to_request(
77:           'size' => size * 1024 *1024 * 1024,
78:           'name' => @plugin_config['drive_name']
79:       )
80: 
81:       begin
82:         ret = response_to_hash(RestClient.post(api_url('/drives/create'), body))
83: 
84: 
85:         @log.info "Disk created with UUID: #{ret['drive']}."
86:       rescue => e
87:         @log.error e.info
88:         raise PluginError, "An error occured while creating the drive, #{e.message}. See logs for more info."
89:       end
90: 
91:       ret['drive']
92:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 70
70:     def create_remote_disk
71:       size = disk_size
72: 
73:       @log.info "Creating new #{size} GB disk..."
74: 
75: 
76:       body = hash_to_request(
77:           'size' => size * 1024 *1024 * 1024,
78:           'name' => @plugin_config['drive_name']
79:       )
80: 
81:       begin
82:         ret = response_to_hash(RestClient.post(api_url('/drives/create'), body))
83: 
84: 
85:         @log.info "Disk created with UUID: #{ret['drive']}."
86:       rescue => e
87:         @log.error e.info
88:         raise PluginError, "An error occured while creating the drive, #{e.message}. See logs for more info."
89:       end
90: 
91:       ret['drive']
92:     end

Creates the server for previously uploaded disk

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 177
177:     def create_server
178:       @log.info "Creating new server..."
179: 
180:       memory = ((is_cloudsigma? and @appliance_config.hardware.memory < 512) ? 512 : @appliance_config.hardware.memory)
181: 
182:       body = hash_to_request(
183:           'name' => "#{@appliance_config.name}-#{@appliance_config.version}.#{@appliance_config.release}",
184:           'cpu' => @appliance_config.hardware.cpus * 1000, # MHz
185:           'smp' => 'auto',
186:           'mem' => memory,
187:           'persistent' => 'true', # hack
188:           'ide:0:0' => @plugin_config['drive_uuid'],
189:           'boot' => 'ide:0:0',
190:           'nic:0:model' => 'e1000',
191:           'nic:0:dhcp' => 'auto',
192:           'vnc:ip' => 'auto',
193:           'vnc:password' => (0...8).map { (('a'..'z').to_a + ('A'..'Z').to_a)[rand(52)] }.join # 8 character VNC password
194:       )
195: 
196:       begin
197:         path = is_cloudsigma? ? '/servers/create' : '/servers/create/stopped'
198:         ret = response_to_hash(RestClient.post(api_url(path), body))
199: 
200:         @log.info "Server was registered with '#{ret['name']}' name as '#{ret['server']}' UUID. Use web UI or API tools to start your server."
201:       rescue => e
202:         @log.error e.info
203:         raise PluginError, "An error occured while creating the server, #{e.message}. See logs for more info."
204:       end
205:     end

Creates the server for previously uploaded disk

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 177
177:     def create_server
178:       @log.info "Creating new server..."
179: 
180:       memory = ((is_cloudsigma? and @appliance_config.hardware.memory < 512) ? 512 : @appliance_config.hardware.memory)
181: 
182:       body = hash_to_request(
183:           'name' => "#{@appliance_config.name}-#{@appliance_config.version}.#{@appliance_config.release}",
184:           'cpu' => @appliance_config.hardware.cpus * 1000, # MHz
185:           'smp' => 'auto',
186:           'mem' => memory,
187:           'persistent' => 'true', # hack
188:           'ide:0:0' => @plugin_config['drive_uuid'],
189:           'boot' => 'ide:0:0',
190:           'nic:0:model' => 'e1000',
191:           'nic:0:dhcp' => 'auto',
192:           'vnc:ip' => 'auto',
193:           'vnc:password' => (0...8).map { (('a'..'z').to_a + ('A'..'Z').to_a)[rand(52)] }.join # 8 character VNC password
194:       )
195: 
196:       begin
197:         path = is_cloudsigma? ? '/servers/create' : '/servers/create/stopped'
198:         ret = response_to_hash(RestClient.post(api_url(path), body))
199: 
200:         @log.info "Server was registered with '#{ret['name']}' name as '#{ret['server']}' UUID. Use web UI or API tools to start your server."
201:       rescue => e
202:         @log.error e.info
203:         raise PluginError, "An error occured while creating the server, #{e.message}. See logs for more info."
204:       end
205:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 44
44:     def disk_size
45:       size = 0
46:       @appliance_config.hardware.partitions.each_value { |partition| size += partition['size'] }
47:       size
48:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 44
44:     def disk_size
45:       size = 0
46:       @appliance_config.hardware.partitions.each_value { |partition| size += partition['size'] }
47:       size
48:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 35
35:     def execute(type = :elastichosts)
36:       validate_plugin_config(['endpoint', 'username', 'password'], 'http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#ElasticHosts_Delivery_Plugin')
37: 
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: 
40:       upload
41:       create_server
42:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 35
35:     def execute(type = :elastichosts)
36:       validate_plugin_config(['endpoint', 'username', 'password'], 'http://boxgrinder.org/tutorials/boxgrinder-build-plugins/#ElasticHosts_Delivery_Plugin')
37: 
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: 
40:       upload
41:       create_server
42:     end

[Source]

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

[Source]

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

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 172
172:     def is_cloudsigma?
173:       !@plugin_config['endpoint'].match(/cloudsigma\.com$/).nil?
174:     end

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 172
172:     def is_cloudsigma?
173:       !@plugin_config['endpoint'].match(/cloudsigma\.com$/).nil?
174:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 60
60:     def response_to_hash(r)
61:       h = {}
62: 
63:       r.each_line do |l|
64:         h[$1] = $2 if l =~ /(\w+) (.*)/
65:       end
66: 
67:       h
68:     end

[Source]

    # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 60
60:     def response_to_hash(r)
61:       h = {}
62: 
63:       r.each_line do |l|
64:         h[$1] = $2 if l =~ /(\w+) (.*)/
65:       end
66: 
67:       h
68:     end

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 98
 98:     def upload
 99:       @log.info "Uploading appliance..."
100: 
101:       # Create the disk with specific size or use already existing
102:       @plugin_config['drive_uuid'] = create_remote_disk unless @plugin_config['drive_uuid']
103: 
104:       upload_chunks
105: 
106:       @log.info "Appliance uploaded."
107:     end

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 98
 98:     def upload
 99:       @log.info "Uploading appliance..."
100: 
101:       # Create the disk with specific size or use already existing
102:       @plugin_config['drive_uuid'] = create_remote_disk unless @plugin_config['drive_uuid']
103: 
104:       upload_chunks
105: 
106:       @log.info "Appliance uploaded."
107:     end

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 143
143:     def upload_chunk(data, part)
144:       try = 1
145: 
146:       url = api_url("/drives/#{@plugin_config['drive_uuid']}/write/#{@step * part}")
147: 
148:       begin
149:         @log.info "Uploading part #{part+1}..."
150: 
151:         RestClient.post url,
152:                         data,
153:                         :content_type => "application/octet-stream",
154:                         'Content-Encoding' => 'gzip'
155: 
156:         @log.info "Part #{part+1} uploaded."
157:       rescue => e
158:         @log.warn "An error occured while uploading #{part} chunk, #{e.message}"
159:         try += 1
160: 
161:         unless try > @plugin_config['retry']
162:           # Let's sleep for specified amount of time
163:           sleep @plugin_config['wait']
164:           retry
165:         else
166:           @log.error e.info
167:           raise PluginError, "Couldn't upload appliance, #{e.message}."
168:         end
169:       end
170:     end

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 143
143:     def upload_chunk(data, part)
144:       try = 1
145: 
146:       url = api_url("/drives/#{@plugin_config['drive_uuid']}/write/#{@step * part}")
147: 
148:       begin
149:         @log.info "Uploading part #{part+1}..."
150: 
151:         RestClient.post url,
152:                         data,
153:                         :content_type => "application/octet-stream",
154:                         'Content-Encoding' => 'gzip'
155: 
156:         @log.info "Part #{part+1} uploaded."
157:       rescue => e
158:         @log.warn "An error occured while uploading #{part} chunk, #{e.message}"
159:         try += 1
160: 
161:         unless try > @plugin_config['retry']
162:           # Let's sleep for specified amount of time
163:           sleep @plugin_config['wait']
164:           retry
165:         else
166:           @log.error e.info
167:           raise PluginError, "Couldn't upload appliance, #{e.message}."
168:         end
169:       end
170:     end

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 109
109:     def upload_chunks
110:       @step = @plugin_config['chunk'] * 1024 * 1024 # in bytes
111:       part = @plugin_config['start_part']
112: 
113:       @log.info "Uploading disk in #{disk_size * 1024 / @plugin_config['chunk']} parts."
114: 
115:       File.open(@previous_deliverables.disk, 'rb') do |f|
116:         while !f.eof?
117:           f.seek(part * @step, File::SEEK_SET)
118: 
119:           data = compress(f.read(@step))
120:           upload_chunk(data, part)
121: 
122:           part += 1
123:         end
124:       end
125: 
126:       @log.info "Appliance #{@appliance_config.name} uploaded to drive with UUID #{@plugin_config['drive_uuid']}."
127:     end

[Source]

     # File lib/boxgrinder-build/plugins/delivery/elastichosts/elastichosts-plugin.rb, line 109
109:     def upload_chunks
110:       @step = @plugin_config['chunk'] * 1024 * 1024 # in bytes
111:       part = @plugin_config['start_part']
112: 
113:       @log.info "Uploading disk in #{disk_size * 1024 / @plugin_config['chunk']} parts."
114: 
115:       File.open(@previous_deliverables.disk, 'rb') do |f|
116:         while !f.eof?
117:           f.seek(part * @step, File::SEEK_SET)
118: 
119:           data = compress(f.read(@step))
120:           upload_chunk(data, part)
121: 
122:           part += 1
123:         end
124:       end
125: 
126:       @log.info "Appliance #{@appliance_config.name} uploaded to drive with UUID #{@plugin_config['drive_uuid']}."
127:     end

[Validate]