tenderloin 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/config/default.rb +3 -0
- data/lib/tenderloin/actions/box/add.rb +1 -0
- data/lib/tenderloin/actions/box/convert.rb +42 -0
- data/lib/tenderloin/actions/vm/provision.rb +12 -0
- data/lib/tenderloin/actions/vm/shared_folders.rb +10 -2
- data/lib/tenderloin/actions/vm/up.rb +2 -0
- data/lib/tenderloin/commands.rb +1 -1
- data/lib/tenderloin/config.rb +5 -1
- data/lib/tenderloin/env.rb +6 -3
- data/lib/tenderloin/ovftool.rb +21 -0
- data/lib/tenderloin/ssh.rb +31 -10
- data/templates/Tenderfile +10 -2
- metadata +3 -1
data/config/default.rb
CHANGED
@@ -6,6 +6,8 @@ Tenderloin::Config.run do |config|
|
|
6
6
|
|
7
7
|
config.ssh.username = "tenderloin"
|
8
8
|
config.ssh.password = "tenderloin"
|
9
|
+
config.ssh.key = nil
|
10
|
+
config.ssh.port = 22
|
9
11
|
# config.ssh.host = "localhost"
|
10
12
|
config.ssh.max_tries = 10
|
11
13
|
config.ssh.timeout = 30
|
@@ -18,6 +20,7 @@ Tenderloin::Config.run do |config|
|
|
18
20
|
|
19
21
|
config.provisioning.script = nil
|
20
22
|
config.provisioning.command = nil
|
23
|
+
config.provisioning.rsync = []
|
21
24
|
|
22
25
|
config.shared_folders.enabled = true
|
23
26
|
config.shared_folders.folders = []
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Tenderloin
|
2
|
+
module Actions
|
3
|
+
module Box
|
4
|
+
# If the box is vagrant format, it converts it to something suitible for tenderloin
|
5
|
+
class Convert < Base
|
6
|
+
|
7
|
+
def execute!
|
8
|
+
if !Dir[@runner.directory + '/Tenderfile'].empty?
|
9
|
+
# We can do nothing - pretenderized
|
10
|
+
logger.info "Tenderloin box provided"
|
11
|
+
elsif !Dir[@runner.directory + '/Vagrantfile'].empty?
|
12
|
+
# Need to import from Vagrant. Convert the ovf to vmx using OVFtool, then write a base tenderfile
|
13
|
+
logger.info "Vagrant box provided, converting"
|
14
|
+
convert_ovf
|
15
|
+
write_tenderfile
|
16
|
+
logger.info "Vagrant box converted. It has a basic Tenderfile, you may want to customize this if needed"
|
17
|
+
logger.info "This file can be found in #{@runner.directory}"
|
18
|
+
else
|
19
|
+
raise "Invalid box - No Tenderfile or Vagrantfile"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def convert_ovf
|
24
|
+
ovf = File.join(@runner.directory, 'box.ovf')
|
25
|
+
vmx = File.join(@runner.directory, 'vmwarebox.vmx')
|
26
|
+
OVFTool.ovf2vmx(ovf, vmx, :lax => true)
|
27
|
+
FileUtils.rm_rf(@runner.directory)
|
28
|
+
FileUtils.mv(@runner.directory + ".vmwarevm", @runner.directory)
|
29
|
+
end
|
30
|
+
|
31
|
+
def write_tenderfile
|
32
|
+
tenderfile = <<EOF
|
33
|
+
Tenderloin::Config.run do |config|
|
34
|
+
config.vm.box_vmx = "vmwarebox.vmx"
|
35
|
+
end
|
36
|
+
EOF
|
37
|
+
File.open(File.join(@runner.directory, 'Tenderfile'), 'w') {|f| f.write(tenderfile) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -3,10 +3,22 @@ module Tenderloin
|
|
3
3
|
module VM
|
4
4
|
class Provision < Base
|
5
5
|
def execute!
|
6
|
+
run_rsync if Tenderloin.config.provisioning.rsync
|
6
7
|
setup_script if Tenderloin.config.provisioning.script
|
7
8
|
run_command if Tenderloin.config.provisioning.command
|
8
9
|
end
|
9
10
|
|
11
|
+
def run_rsync
|
12
|
+
logger.info "Running rsync..."
|
13
|
+
Tenderloin.config.provisioning.rsync.each do |rsync|
|
14
|
+
src, dst = *rsync
|
15
|
+
SSH.execute(@runner.fusion_vm.ip) do |ssh|
|
16
|
+
ssh.exec!("mkdir -p #{dst}")
|
17
|
+
end
|
18
|
+
logger.info SSH.rsync(@runner.fusion_vm.ip, File.expand_path(src), File.expand_path(dst))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
10
22
|
def setup_script
|
11
23
|
logger.info "Uploading provisioning script..."
|
12
24
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
1
3
|
module Tenderloin
|
2
4
|
module Actions
|
3
5
|
module VM
|
@@ -29,8 +31,14 @@ module Tenderloin
|
|
29
31
|
logger.info "Creating shared folders metadata..."
|
30
32
|
|
31
33
|
shared_folders.each do |name, hostpath, guestpath|
|
32
|
-
|
33
|
-
|
34
|
+
begin
|
35
|
+
status = Timeout::timeout(10) {
|
36
|
+
@runner.fusion_vm.share_folder(name, File.expand_path(hostpath))
|
37
|
+
@runner.fusion_vm.enable_shared_folders
|
38
|
+
}
|
39
|
+
rescue Timeout::Error
|
40
|
+
logger.warn "Sharing folder #{name} timed out"
|
41
|
+
end
|
34
42
|
end
|
35
43
|
|
36
44
|
logger.info "Linking shared folders..."
|
@@ -16,6 +16,7 @@ msg
|
|
16
16
|
|
17
17
|
# Up is a "meta-action" so it really just queues up a bunch
|
18
18
|
# of other actions in its place:
|
19
|
+
Tenderloin::Box.add(Tenderloin.config.vm.box, Tenderloin.config.vm.box_url) unless Tenderloin::Env.box
|
19
20
|
steps = [Import, SharedFolders, Boot]
|
20
21
|
steps << Provision if Tenderloin.config.provisioning.enabled
|
21
22
|
steps.insert(0, MoveHardDrive) if Tenderloin.config.vm.hd_location
|
@@ -46,6 +47,7 @@ msg
|
|
46
47
|
data.delete "ethernet1.generatedAddress"
|
47
48
|
data.delete "ethernet0.generatedAddressOffset"
|
48
49
|
data.delete "ethernet1.generatedAddressOffset"
|
50
|
+
data.delete 'displayname'
|
49
51
|
data['displayName'] = "tenderloin-" + @runner.vm_id
|
50
52
|
end
|
51
53
|
end
|
data/lib/tenderloin/commands.rb
CHANGED
data/lib/tenderloin/config.rb
CHANGED
@@ -59,10 +59,13 @@ module Tenderloin
|
|
59
59
|
attr_accessor :host
|
60
60
|
attr_accessor :max_tries
|
61
61
|
attr_accessor :timeout
|
62
|
+
attr_accessor :key
|
63
|
+
attr_accessor :port
|
62
64
|
end
|
63
65
|
|
64
66
|
class VMConfig < Base
|
65
67
|
attr_accessor :box
|
68
|
+
attr_accessor :box_url
|
66
69
|
attr_accessor :box_vmx
|
67
70
|
attr_accessor :project_directory
|
68
71
|
attr_accessor :hd_location
|
@@ -99,8 +102,9 @@ module Tenderloin
|
|
99
102
|
class ProvisioningConfig
|
100
103
|
attr_accessor :script
|
101
104
|
attr_accessor :command
|
105
|
+
attr_accessor :rsync
|
102
106
|
def enabled
|
103
|
-
script || command
|
107
|
+
script || command || !rsync.empty?
|
104
108
|
end
|
105
109
|
end
|
106
110
|
|
data/lib/tenderloin/env.rb
CHANGED
@@ -11,11 +11,14 @@ module Tenderloin
|
|
11
11
|
extend Tenderloin::Util
|
12
12
|
|
13
13
|
class << self
|
14
|
-
def box
|
14
|
+
def box
|
15
|
+
load_box! unless @@box
|
16
|
+
@@box
|
17
|
+
end
|
15
18
|
def persisted_vm; @@persisted_vm; end
|
16
19
|
def root_path; @@root_path; end
|
17
20
|
def dotfile_path
|
18
|
-
File.join(root_path, $ROOTFILE_NAME + ".loinstate")
|
21
|
+
File.join(root_path, "." + $ROOTFILE_NAME + ".loinstate")
|
19
22
|
end
|
20
23
|
def home_path; File.expand_path(Tenderloin.config.tenderloin.home); end
|
21
24
|
def tmp_path; File.join(home_path, "tmp"); end
|
@@ -127,7 +130,7 @@ No base box was specified! A base box is required as a staring point
|
|
127
130
|
for every tenderloin virtual machine. Please specify one in your Tenderfile
|
128
131
|
using `config.vm.box`
|
129
132
|
msg
|
130
|
-
|
133
|
+
elsif !Tenderloin.config.vm.box_url
|
131
134
|
error_and_exit(<<-msg)
|
132
135
|
Specified box `#{Tenderloin.config.vm.box}` does not exist!
|
133
136
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Tenderloin
|
2
|
+
class OVFTool
|
3
|
+
TOOL = "/Applications/VMware\\ Fusion.app//Contents/Library/VMware\\ OVF\\ Tool/ovftool"
|
4
|
+
|
5
|
+
def self.run(cmd, opts = '')
|
6
|
+
res = `#{TOOL} #{opts} #{cmd}`
|
7
|
+
if $? == 0
|
8
|
+
return res
|
9
|
+
else
|
10
|
+
raise "Error running ovftool command #{cmd}: " + res
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.ovf2vmx(ovf, vmx, opts = {})
|
15
|
+
cmd_opts = []
|
16
|
+
cmd_opts << '--lax' if opts[:lax]
|
17
|
+
run("#{cmd_opts.join(' ')} #{ovf} #{vmx}")
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/tenderloin/ssh.rb
CHANGED
@@ -3,17 +3,16 @@ module Tenderloin
|
|
3
3
|
SCRIPT = File.join(File.dirname(__FILE__), '..', '..', 'script', 'tenderloin-ssh-expect.sh')
|
4
4
|
|
5
5
|
class << self
|
6
|
-
def connect(
|
7
|
-
options
|
8
|
-
|
9
|
-
|
6
|
+
def connect(ip)
|
7
|
+
if options.key
|
8
|
+
Kernel.exec "#{cmd_ssh_opts} #{options.username}@#{ip}"
|
9
|
+
else
|
10
|
+
Kernel.exec cmd_ssh_opts.strip
|
10
11
|
end
|
11
|
-
|
12
|
-
Kernel.exec "#{SCRIPT} #{options[:username]} #{options[:password]} #{options[:host]} #{port(opts)}".strip
|
13
12
|
end
|
14
13
|
|
15
14
|
def execute(ip)
|
16
|
-
Net::SSH.start(ip, Tenderloin.config[:ssh][:username],
|
15
|
+
Net::SSH.start(ip, Tenderloin.config[:ssh][:username], net_ssh_opts) do |ssh|
|
17
16
|
yield ssh
|
18
17
|
end
|
19
18
|
end
|
@@ -25,11 +24,16 @@ module Tenderloin
|
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
27
|
+
def rsync(ip,src,dst)
|
28
|
+
cmd = "rsync -avz --delete -e \"#{cmd_ssh_opts}\" #{src} #{options.username}@#{ip}:#{dst}"
|
29
|
+
`#{cmd}`
|
30
|
+
end
|
31
|
+
|
28
32
|
def up?(ip)
|
29
33
|
check_thread = Thread.new do
|
30
34
|
begin
|
31
35
|
Thread.current[:result] = false
|
32
|
-
Net::SSH.start(ip, Tenderloin.config.ssh.username,
|
36
|
+
Net::SSH.start(ip, Tenderloin.config.ssh.username, net_ssh_opts) do |ssh|
|
33
37
|
Thread.current[:result] = true
|
34
38
|
end
|
35
39
|
rescue Errno::ECONNREFUSED, Net::SSH::Disconnect
|
@@ -41,8 +45,25 @@ module Tenderloin
|
|
41
45
|
return check_thread[:result]
|
42
46
|
end
|
43
47
|
|
44
|
-
def
|
45
|
-
|
48
|
+
def options
|
49
|
+
Tenderloin.config.ssh
|
50
|
+
end
|
51
|
+
|
52
|
+
def cmd_ssh_opts
|
53
|
+
if options.key
|
54
|
+
"ssh -i #{options.key} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p #{options.port}"
|
55
|
+
else
|
56
|
+
"#{SCRIPT} #{options.username} #{options.password} #{options.host} #{options.port}".strip
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def net_ssh_opts
|
61
|
+
opts = {}
|
62
|
+
opts[:port] = Tenderloin.config.ssh.port
|
63
|
+
opts[:password] = Tenderloin.config.ssh.password
|
64
|
+
opts[:timeout] = Tenderloin.config.ssh.timeout
|
65
|
+
opts[:keys] = [Tenderloin.config[:ssh][:key]] if Tenderloin.config[:ssh][:key]
|
66
|
+
opts
|
46
67
|
end
|
47
68
|
end
|
48
69
|
end
|
data/templates/Tenderfile
CHANGED
@@ -5,19 +5,27 @@ Tenderloin::Config.run do |config|
|
|
5
5
|
|
6
6
|
# Every Tenderloin virtual environment requires a box to build off of.
|
7
7
|
config.vm.box = "base"
|
8
|
+
# You can optionally specify a path or URL to automatically retrieve it from
|
9
|
+
# config.vm.box_url = "http://download"
|
8
10
|
|
9
11
|
## SSH username and password defaults to 'tenderloin'. You can change this.
|
12
|
+
## If you provide a key, this will be used over the password
|
10
13
|
# config.ssh.username = 'youruser'
|
11
14
|
# config.ssh.password = 'yourpass'
|
15
|
+
# config.ssh.key = '~/.ssh/id_rsa'
|
12
16
|
|
13
|
-
## Provisioning can either provide a shell script, or a command to execute
|
17
|
+
## Provisioning can either provide a shell script, or a command to execute.
|
18
|
+
## You can also provide folders to rsync (over SSH)
|
14
19
|
# config.provisioning.script = <<EOF
|
15
20
|
# ls /usr
|
16
21
|
# EOF
|
17
22
|
# config.provisioning.command = "apt-get install -y ruby"
|
23
|
+
## This is destructive - it uses the --delete flag
|
24
|
+
# config.provisioning.rsync << ["src/", "dst"]
|
18
25
|
|
19
26
|
## Shared folders are enabled by default, and the project dir is always shared
|
20
27
|
## You can turn this off, or add additional folders
|
21
28
|
# config.shared_folders.enabled = false
|
22
|
-
# config.shared_folders.folders
|
29
|
+
# config.shared_folders.folders << ["my-files", "src", "/mnt/src"]
|
30
|
+
# config.shared_folders.folders << ["bin-files", "bin", "/mnt/bin"]
|
23
31
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tenderloin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -108,6 +108,7 @@ extra_rdoc_files:
|
|
108
108
|
files:
|
109
109
|
- lib/tenderloin/actions/base.rb
|
110
110
|
- lib/tenderloin/actions/box/add.rb
|
111
|
+
- lib/tenderloin/actions/box/convert.rb
|
111
112
|
- lib/tenderloin/actions/box/destroy.rb
|
112
113
|
- lib/tenderloin/actions/box/download.rb
|
113
114
|
- lib/tenderloin/actions/box/unpackage.rb
|
@@ -132,6 +133,7 @@ files:
|
|
132
133
|
- lib/tenderloin/downloaders/http.rb
|
133
134
|
- lib/tenderloin/env.rb
|
134
135
|
- lib/tenderloin/fusion_vm.rb
|
136
|
+
- lib/tenderloin/ovftool.rb
|
135
137
|
- lib/tenderloin/ssh.rb
|
136
138
|
- lib/tenderloin/util.rb
|
137
139
|
- lib/tenderloin/vm.rb
|