Class: VBOX::CmdLineAPI

Inherits:
Object
  • Object
show all
Defined in:
lib/vbox/cmdlineapi.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ CmdLineAPI

Returns a new instance of CmdLineAPI.



14
15
16
17
18
# File 'lib/vbox/cmdlineapi.rb', line 14

def initialize options={}
  @options = options
  @options[:verbose] = VBOX.verbosity
  @options[:verbose] ||= 2 if @options[:dry_run] && @options[:verbose] < 2
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



12
13
14
# File 'lib/vbox/cmdlineapi.rb', line 12

def options
  @options
end

Instance Method Details

#_clone(old_vm_name, params) ⇒ Object



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/vbox/cmdlineapi.rb', line 261

def _clone old_vm_name, params
  args = {}
  if new_vm_name = params[:name] || _gen_vm_name(old_vm_name)
    args[:name] = new_vm_name
  end

  snapshot = @clone_use_snapshot ||= case params[:snapshot].to_s
    when 'new', 'take', 'make'
      take_snapshot(old_vm_name, new_vm_name ? {:name => "for #{new_vm_name}"} : {})
    when 'last'
      get_snapshots(old_vm_name).last
    else
      raise "no :snapshot param"
    end
  unless snapshot
    raise "failed to get snapshot"
  end

  args[:options]  = :link
  args[:register] = ''
  args[:snapshot] = snapshot.uuid

  vboxmanage :clonevm, old_vm_name, args
  return false unless success?
  get_vm_info(old_vm_name).each do |k,v|
    if k =~ /^macaddress/
      old_mac = v.downcase
      puts "[.] old #{k}=#{old_mac}"
      old_automac = _name2macpart(old_vm_name)
      if old_automac && old_mac[-old_automac.size..-1] == old_automac
        new_automac = _name2macpart(new_vm_name)
        new_mac = old_mac[0,old_mac.size-new_automac.size] + new_automac
        puts "[.] new #{k}=#{new_mac}"
        modify new_vm_name, k => new_mac
      end
    end
  end
  new_vm_name
end

#_gen_vm_name(parent_name) ⇒ Object

d0 -> d1, d2, d3 d1 -> d1.1, d1.2, d1.3 d1.1 -> d1.1.1, d1.1.2, d1.1.3 xx -> xx.1, xx.2, xx.3



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 'lib/vbox/cmdlineapi.rb', line 198

def _gen_vm_name parent_name
  # try to guess new name
  names = list_vms.map(&:name)
  numbers = parent_name.scan /\d+/
  if numbers.any?
    lastnum = numbers.last
    if lastnum.to_i == 0
      # d0 -> d1, d2, d3
      newnum = lastnum.to_i + 1
      while true
        newname = parent_name.dup
        newname[parent_name.rindex(lastnum),lastnum.size] = newnum.to_s
        return newname unless names.include?(newname)
        newnum += 1
      end
    else
      # d1   -> d1.1, d1.2, d1.3
      # d1.1 -> d1.1.1, d1.1.2, d1.1.3
      newnum = 1
      while true
        newname = "#{parent_name}.#{newnum}"
        return newname unless names.include?(newname)
        newnum += 1
      end
    end
  else
    # xx -> xx.1, xx.2, xx.3
    newnum = 1
    while true
      newname = "#{parent_name}.#{newnum}"
      return newname unless names.include?(newname)
      newnum += 1
    end
  end
  nil
end

#_name2macpart(name) ⇒ Object



241
242
243
244
# File 'lib/vbox/cmdlineapi.rb', line 241

def _name2macpart name
  r = name.scan(/\d+/).map{ |x| "%02x" % x }.join
  r == '' ? nil : r
end

#_naturalize(s) ⇒ Object



110
111
112
# File 'lib/vbox/cmdlineapi.rb', line 110

def _naturalize s
  s.scan(/[^\d]+|\d+/).collect { |f| f.match(/\d+/) ? f.to_i : f }
end

#clone(old_vm_name, params = {}) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/vbox/cmdlineapi.rb', line 246

def clone old_vm_name, params = {}
  @clone_use_snapshot = nil
  params = @options.merge(params)
  n = params[:clones] || 1
  if n > 1
    # return array of clones
    n.times.map{ _clone(old_vm_name, params) }
  elsif n == 1
    # return one clone
    _clone(old_vm_name, params)
  else
    raise "invalid count of clones = #{n.inspect}"
  end
end

#createvm(vm) ⇒ Object



102
103
104
105
106
# File 'lib/vbox/cmdlineapi.rb', line 102

def createvm vm
options = { :name => vm.name, :register => '' }
options[:uuid] = vm.uuid if vm.uuid
a = vboxmanage :createvm, options
success?    end

#delete(name) ⇒ Object Also known as: destroy



307
308
309
# File 'lib/vbox/cmdlineapi.rb', line 307

def delete name
  vboxmanage :unregistervm, name, "--delete"
end

#get_snapshots(_name) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/vbox/cmdlineapi.rb', line 173

def get_snapshots _name
  r = []
  name = uuid = nil
  vboxmanage(:snapshot, _name, 'list', '--machinereadable').each_line do |line|
    k,v = line.strip.split('=',2)
    next unless v
    v = qstrip(v)
    case k
    when /SnapshotName/
      name = v
    when /SnapshotUUID/
      uuid = v
    end
    if name && uuid
      r << Snapshot.new(name, uuid)
      name = uuid = nil
    end
  end
  r
end

#get_vm_details(vm_or_name_or_uuid) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/vbox/cmdlineapi.rb', line 82

def get_vm_details vm_or_name_or_uuid
  name_or_uuid = case vm_or_name_or_uuid
    when String
      vm = VM.new
      vm_or_name_or_uuid
    when VM
      vm = vm_or_name_or_uuid
      vm.uuid || vm.name
    end

  h = {}
  data = quiet{ vboxmanage :showvminfo, name_or_uuid, "--machinereadable" }
  data.each_line do |line|
    k,v = line.split('=',2)
    next unless v
    h[qstrip(k)] = qstrip(v)
  end
  h.empty? ? nil : h
end

#get_vm_info(name) ⇒ Object



142
143
144
145
146
147
148
149
# File 'lib/vbox/cmdlineapi.rb', line 142

def get_vm_info name
  h = {}
  vboxmanage(:showvminfo, name, "--machinereadable").each_line do |line|
    k,v = line.split('=',2)
    h[qstrip(k)] = qstrip(v)
  end
  h
end

#list_vms(params = {}) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/vbox/cmdlineapi.rb', line 114

def list_vms params = {}
  vms = []
  vboxmanage(:list, :vms).each_line do |line|
    if line[UUID_RE]
      vm = VM.new
      vm.uuid = $&
      vm.name = qstrip(line.gsub($&, ''))
      vms << vm
    end
  end
  if params[:include_state]
    # second pass
    h = Hash[*vms.map{ |vm| [vm.uuid, vm] }.flatten]
    uuid = nil # declare variable for inner loop
    vboxmanage(:list, :runningvms).each_line do |line|
      h[uuid].state = :running if (uuid=line[UUID_RE]) && h[uuid]
    end
  end
  vms.sort_by{ |vm| _naturalize(vm.name) }
end

#modify(vm, vars) ⇒ Object



301
302
303
304
305
# File 'lib/vbox/cmdlineapi.rb', line 301

def modify vm, vars
  id = vm.is_a?(VM) ? (vm.uuid || vm.name) : vm.to_s
  vboxmanage :modifyvm, id, vars
  success?
end

#start(name, options = {}) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/vbox/cmdlineapi.rb', line 159

def start name, options = {}
  headless = @options[:headless]
  headless =  options[:headless] if options.key?(:headless)

  if ENV['DISPLAY'] && !headless
    vboxmanage :startvm, name
  else
    puts "[.] $DISPLAY is not set, assuming --headless".gray unless headless
    @options[:headless] = true
    vboxmanage :startvm, name, :type => :headless
  end
end

#take_snapshot(vm_name, params = {}) ⇒ Object



235
236
237
238
239
# File 'lib/vbox/cmdlineapi.rb', line 235

def take_snapshot vm_name, params = {}
  vboxmanage "snapshot", vm_name, "take", params[:name] || "noname"
  exit 1 unless success?
  get_snapshots(vm_name).last
end