Class: Linecook::Commands::VirtualBoxCommand

Inherits:
Linecook::Command show all
Includes:
Linecook::CommandUtils
Defined in:
lib/linecook/commands/virtual_box_command.rb

Direct Known Subclasses

Snapshot, Ssh, Start, State, Stop

Constant Summary collapse

HOST_REGEXP =

Matches a host declaration in a ssh config file. After the match:

$1:: The host name
     (ex: 'Host name' => 'name')
$2:: The vm name (if present)
     (ex: 'Host name # [vm_name]' => 'vm_name')
/^\s*Host\s+([^\s#]+)(?:\s*#\s*\[(.*?)\])?/

Instance Method Summary collapse

Methods included from Linecook::CommandUtils

#sh, #sh!

Methods inherited from Linecook::Command

#call, help, #initialize, parse, #process, signature

Constructor Details

This class inherits a constructor from Linecook::Command

Instance Method Details

#discardstate(vm_name) ⇒ Object



113
114
115
# File 'lib/linecook/commands/virtual_box_command.rb', line 113

def discardstate(vm_name)
  sh! "VBoxManage discardstate #{vm_name}"
end

#each_host(hosts = []) ⇒ Object



65
66
67
68
69
70
71
72
73
74
# File 'lib/linecook/commands/virtual_box_command.rb', line 65

def each_host(hosts=[])
  if hosts.empty?
    hosts = host_list.collect {|host, vm_name| host }
    hosts.delete('*')
  end

  hosts.uniq.each do |host|
    yield(host)
  end
end

#each_vm_name(vm_names = []) ⇒ Object



76
77
78
79
80
81
82
83
84
85
# File 'lib/linecook/commands/virtual_box_command.rb', line 76

def each_vm_name(vm_names=[])
  if vm_names.empty?
    vm_names = host_list.collect {|host, vm_name| vm_name }
    vm_names.delete('*')
  end

  vm_names.uniq.each do |vm_name|
    yield(vm_name)
  end
end

#host_listObject



53
54
55
# File 'lib/linecook/commands/virtual_box_command.rb', line 53

def host_list
  @host_list ||= load_hosts(ssh_config_file)
end

#host_mapObject



57
58
59
# File 'lib/linecook/commands/virtual_box_command.rb', line 57

def host_map
  @host_map ||= Hash[*host_list.flatten]
end

#load_hosts(ssh_config_file) ⇒ Object

Returns a hash of (host, vm_name) pairs as declared in a ssh config file. Basically this means parsing out the name in each config like:

Host name

Normally the vm_name is the same as the host name, but an alternate can be specified as a comment in the form:

Host name # [vm_name]


33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/linecook/commands/virtual_box_command.rb', line 33

def load_hosts(ssh_config_file)
  hosts = []

  File.open(ssh_config_file) do |io|
    io.each_line do |line|
      next unless line =~ HOST_REGEXP
      next if $2 && $2.strip.empty?
      hosts << [$1, $2 || $1]
    end
  end

  hosts
end

#resolve_vm_names(hosts) ⇒ Object



61
62
63
# File 'lib/linecook/commands/virtual_box_command.rb', line 61

def resolve_vm_names(hosts)
  names ? hosts : hosts.collect {|host| host_map[host] || host }
end

#restore(vm_name, snapshot) ⇒ Object



109
110
111
# File 'lib/linecook/commands/virtual_box_command.rb', line 109

def restore(vm_name, snapshot)
  sh! "VBoxManage -q snapshot #{vm_name} restore #{snapshot.upcase}"
end

#running?(vm_name) ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/linecook/commands/virtual_box_command.rb', line 97

def running?(vm_name)
  `VBoxManage -q list runningvms`.include?(vm_name)
end

#share(vm_name, name, local_dir, remote_dir) ⇒ Object



117
118
119
120
121
122
123
124
125
# File 'lib/linecook/commands/virtual_box_command.rb', line 117

def share(vm_name, name, local_dir, remote_dir)
  share_dir = "#{local_dir}/#{vm_name}"
  FileUtils.mkdir_p(share_dir) unless File.exists?(share_dir)

  ssh vm_name, "sudo umount '#{remote_dir}' > /dev/null 2>&1"
  sh "VBoxManage sharedfolder remove '#{vm_name}' --name '#{name}' --transient > /dev/null 2>&1"
  sh! "VBoxManage sharedfolder add '#{vm_name}' --name '#{name}' --hostpath '#{share_dir}' --transient"
  ssh! vm_name, "sudo mount -t vboxsf -o uid=1000,gid=100 '#{name}' '#{remote_dir}'"
end

#ssh(host, cmd) ⇒ Object



87
88
89
# File 'lib/linecook/commands/virtual_box_command.rb', line 87

def ssh(host, cmd)
  sh "ssh -q -F '#{ssh_config_file}' '#{host}' -- #{cmd}"
end

#ssh!(host, cmd) ⇒ Object



91
92
93
94
95
# File 'lib/linecook/commands/virtual_box_command.rb', line 91

def ssh!(host, cmd)
  unless ssh(host, cmd)
    raise CommandError, "non-zero exit status: #{$?.exitstatus}"
  end
end

#ssh_config_file=(ssh_config_file) ⇒ Object



47
48
49
50
51
# File 'lib/linecook/commands/virtual_box_command.rb', line 47

def ssh_config_file=(ssh_config_file)
  @ssh_config_file = ssh_config_file
  @host_list = nil
  @host_map  = nil
end

#start(vm_name, type = 'headless') ⇒ Object



101
102
103
# File 'lib/linecook/commands/virtual_box_command.rb', line 101

def start(vm_name, type='headless')
  sh! "VBoxManage -q startvm #{vm_name} --type #{type}"
end

#start_ssh_socket(vm_name) ⇒ Object



127
128
129
# File 'lib/linecook/commands/virtual_box_command.rb', line 127

def start_ssh_socket(vm_name)
  sh "ssh -MNf -F '#{ssh_config_file}' '#{vm_name}' >/dev/null 2>&1 </dev/null"
end

#stop(vm_name) ⇒ Object



105
106
107
# File 'lib/linecook/commands/virtual_box_command.rb', line 105

def stop(vm_name)
  sh! "VBoxManage -q controlvm #{vm_name} poweroff"
end