forked from gurgeous/teleport
/
main.rb
153 lines (135 loc) · 3.76 KB
/
main.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
require "optparse"
module Teleport
# The main class for the teleport command line.
class Main
include Constants
include Util
TAR = "#{DIR}.tgz"
def initialize(cmd = :teleport)
cli(cmd)
case @options[:cmd]
when :teleport
$stderr = $stdout
teleport
when :install
$stderr = $stdout
install
when :infer
infer
end
end
# Parse ARGV.
def cli(cmd)
@options = { }
@options[:cmd] = cmd
@options[:file] = "Telfile"
opt = OptionParser.new do |o|
o.banner = "Usage: teleport <hostname>"
o.on("-f", "--file FILE", "use this file instead of Telfile") do |f|
@options[:file] = f
end
o.on("-i", "--infer", "infer a new Telfile from YOUR machine") do |f|
@options[:cmd] = :infer
end
o.on_tail("-h", "--help", "print this help text") do
puts opt
exit(0)
end
end
begin
opt.parse!
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
puts $!
puts opt
exit(1)
end
if @options[:cmd] == :teleport
# print this error message early, to give the user a hint
# instead of complaining about command line arguments
if ARGV.length != 1
puts opt
exit(1)
end
@options[:host] = ARGV.shift
end
end
# Read Telfile
def read_config
if !File.exists?(@options[:file])
fatal("Sadly, I can't find #{@options[:file]} here. Please create one.")
end
@config = Config.new(@options[:file])
end
# Assemble the the tgz before we teleport to the host
def assemble_tgz
banner "Assembling #{TAR}..."
rm_and_mkdir(DIR)
# gem
run("cp", ["-r", "#{File.dirname(__FILE__)}/../../lib", GEM])
# Telfile, if necessary
if @options[:file] != "Telfile"
run("cp", [@options[:file], "Telfile"])
end
# data
run("cp", ["-r", ".", DATA])
# config.sh
File.open("#{DIR}/config", "w") do |f|
f.puts("CONFIG_HOST='#{@options[:host]}'")
f.puts("CONFIG_RUBY='#{@config.ruby}'")
f.puts("CONFIG_RUBYGEMS='#{RUBYGEMS}'")
end
# keys
ssh_key = "#{ENV["HOME"]}/.ssh/#{PUBKEY}"
if File.exists?(ssh_key)
run("cp", [ssh_key, DIR])
end
Dir.chdir(File.dirname(DIR)) do
run("tar", ["cfpz", TAR, File.basename(DIR)])
end
end
# Copy the tgz to the host, then run there.
def ssh_tgz
begin
banner "scp #{TAR} to #{@options[:host]}:#{TAR}..."
args = []
args += @config.ssh_options if @config.ssh_options
args << TAR
args << "#{@options[:host]}:#{TAR}"
run("scp", args)
cmd = [
"cd /tmp",
"(sudo -n echo gub > /dev/null 2> /dev/null || (echo `whoami` could not sudo. && exit 1))",
"sudo rm -rf #{DIR}",
"sudo tar xfpz #{TAR}",
"sudo #{DIR}/gem/teleport/run.sh"
]
banner "ssh to #{@options[:host]} and run..."
args = []
args += @config.ssh_options if @config.ssh_options
args << @options[:host]
args << cmd.join(" && ")
run("ssh", args)
rescue RunError
fatal("Failed!")
end
banner "Success!"
end
# Teleport to the host.
def teleport
read_config
assemble_tgz
ssh_tgz
end
# We're running on the host - install!
def install
Dir.chdir(DATA) do
read_config
end
Install.new(@config)
end
# try to infer a new Telfile based on the current machine
def infer
Infer.new
end
end
end