Class: CreateVMCommand

Inherits:
BaseCommand show all
Defined in:
bin/esx

Instance Method Summary collapse

Instance Method Details

#download!(source_url, destination_file) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'bin/esx', line 245

def download!(source_url, destination_file)
  dst = File.open(destination_file, 'w')
  proxy_uri = URI.parse(ENV["http_proxy"] || "")
  uri = URI.parse(source_url)
  http = Net::HTTP.new(uri.host, uri.port, proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)

  if uri.scheme == "https"
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  end

  res = http.start do |h|
    h.request_get(uri.request_uri) do |response|
      total = response.content_length
      progress = 0
      segment_count = 0

      response.read_body do |segment|
        # Report the progress out
        progress += segment.length
        segment_count += 1

        # Progress reporting is limited to every 25 segments just so
        # we're not constantly updating
        if segment_count % 25 == 0
          report_progress(progress, total)
          segment_count = 0
        end
        # Store the segment
        dst.write(segment)
      end
    end
  end

  raise Exception.new("HTTP Error #{res}") if res.class != Net::HTTPOK
ensure
  dst.close
end

#executeObject



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'bin/esx', line 168

def execute
  begin
    host = ESX::Host.connect address, user, password
  rescue Exception => e
    $stderr.puts "Can't connect to the host #{address}."
    if debug?
      $stderr.puts e.message
    end
    exit 1
  end
  if disk_size and disk_file
    $stderr.puts "Both --disk-file and --disk-size specified. --disk-size will be ignored."
  end
  downloaded_file = nil
  if disk_file.nil?
    # if --disk-file nil? create the VM without disk
    vm = host.create_vm :vm_name => name, 
                        :datastore => datastore, :disk_type => :flat, :memory => memory,
                        :disk_size => disk_size,
                        :guest_id => guest_id, :nics => [{:mac_address => mac_address, :network => vm_network}]
  else
    df = disk_file.dup
    if df.strip.chomp =~ /^http/
      begin
        downloaded_file = disk_file.dup
        tmpfile = "#{tmpdir}/#{Time.now.to_i}.esx"
        puts "Downloading file... (#{tmpfile})"
        download! downloaded_file, tmpfile
        puts
        df = tmpfile
      rescue Exception => e
        FileUtils.rm_f(tmpfile) 
        $stderr.puts "Error downloading file from #{downloaded_file}."
        $stderr.puts e.message if debug?
        exit 1
      end
    end
    raise Exception.new("Invalid disk file") if not File.exist?(df)
    if not name
      $stderr.puts "Invalid VM name."
      $stderr.puts "Use --name option to specify the VM name"
      exit 1
    end
    host.remote_command "mkdir /vmfs/volumes/#{datastore}/#{name}"

    begin
      host.import_disk df, "/vmfs/volumes/#{datastore}/#{name}/#{name}.vmdk"
    rescue Exception => e
      $stderr.puts "Error uploading file to /vmfs/volumes/#{datastore}/#{name}/#{name}.vmdk"
      $stderr.puts e.message if debug?
      exit 1
    end

    if not downloaded_file.nil?
      puts "Deleting tmp file #{df}" if debug?
      FileUtils.rm_f(df) 
    end
    vm = host.create_vm :vm_name => name, 
                        :disk_file => "#{name}/#{name}.vmdk", 
                        :datastore => datastore, :disk_type => :flat, :memory => memory,
                        :guest_id => guest_id, :nics => [{mac_address => mac_address, :network => vm_network}]
  end
  if poweron?
    vm.power_on
  end
end

#report_progress(progress, total, show_parts = true) ⇒ Object



235
236
237
238
239
240
241
242
243
# File 'bin/esx', line 235

def report_progress(progress, total, show_parts=true)
  line_reset = "\r\e[0K" 
  percent = (progress.to_f / total.to_f) * 100
  line = "Progress: #{percent.to_i}%"
  line << " (#{progress} / #{total})" if show_parts
  line = "#{line_reset}#{line}"
  $stdout.sync = true
  $stdout.print line
end