-
Notifications
You must be signed in to change notification settings - Fork 0
/
install.rb
executable file
·277 lines (242 loc) · 8.76 KB
/
install.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
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
234
235
236
237
238
239
240
241
242
243
244
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
#!/usr/bin/env ruby
#A script for bootstrapping Concerto so the installation scripts can do their work
#Parameters:
#concerto_location
#concerto_hostname
#database_type
#used for platform-agnostic downloading of zip and tar files
require 'open-uri'
#used for platform-agnostic file copying
require 'fileutils'
#turn off SSL verification stuff due to Ruby bug (mostly a Windows issue)
require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
def main
parse_options()
if $database_type.nil? == false && Kernel.is_windows?
puts "Only SQLite Database autoconfiguration is available on Windows"
exit
end
#Check that package dependencies are installed. If not, try some other detection strategies
if command?("apt-get")
check_deb_pkg_depends()
else
check_general_depends()
end
#Retrieve Concerto source/tar/zip from Github
if command?("git")
puts "Cloning Git repository..."
system("git clone https://github.com/concerto/concerto.git #{$concerto_location}")
system("git checkout #{get_tag()}")
else
puts "Git executable not found -- downloading zip/tar file..."
#Zip files are a sensible default for Windows
if Kernel.is_windows?
windows_download()
else
#Virtually all *nix systems have tar
download_file("https://github.com/concerto/concerto/archive/#{get_tag()}.tar.gz", "/tmp/concerto.tar.gz")
system("tar -zxvf /tmp/concerto.tar.gz #{$concerto_location}")
end
end
Dir.chdir($concerto_location) do
#Install gems
puts "Installing Gems..."
unless command?("bundle")
puts "Bundler is not installed. Please install the bundler gem with gem install bundler"
exit
end
system("bundle install --path vendor/bundle")
end
#Create Apache VHost entry with interpolated values
vhost_entry = %{<VirtualHost *:80>
ServerName #{$concerto_hostname || "<SERVER HOSTNAME HERE>"}
DocumentRoot "#{$concerto_location}"
RailsEnv production
<Directory "#{$concerto_location}">
Order allow,deny
Allow from all
</Directory>
</VirtualHost>}
puts "Please add the following to your Apache configuration file and restart Apache...\n\n"
puts vhost_entry
end
def get_tag()
require 'net/https'
require 'uri'
require 'json'
uri = URI.parse('https://api.github.com/repos/concerto/concerto/git/refs/tags')
http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == "https" # enable SSL/TLS
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.ca_file = File.join("cacert.pem")
end
http.start {
http.request_get(uri.path) {|res|
@versions = Array.new
JSON.parse(res.body).each do |tag|
@versions << tag['ref'].gsub(/refs\/tags\//,'')
end
@versions.sort! {|x,y| y <=> x }
return @versions[0]
}
}
end
#Parse command line options with some Ruby magicks
def parse_options
require 'optparse'
OptionParser.new do |o|
o.on("-d database_type") { |d| $database_type = d }
o.on("-n concerto_hostname") { |n| $concerto_hostname = n }
o.on('-l concerto_location') { |location| $concerto_location = location }
o.on("-h", "--help", "Show this message") { puts o; exit }
o.parse!
end
#A sensible default for Concerto installation location
if $concerto_location.nil?
if Kernel.is_windows?
puts "Concerto is being installed to c:\concerto. To specify the location to deploy Concerto to, use the -l option"
$concerto_location = 'c:\concerto'
else
puts "Concerto is being installed to /var/www/concerto. To specify the location to deploy Concerto to, use the -l option"
$concerto_location = "/var/www/concerto"
end
end
end
#This is a *nix-only method for getting MySQL configured for Concerto
def mysql_config
#turn of terminal echo so the password isn't seen
`stty -echo`
print "Enter MySQL root password: "
password = gets.chomp
`stty echo`
puts ""
puts "A random password is now being generated for use in Concerto's database configuration"
random_password = generate_password(12)
query = "create database concerto;GRANT ALL ON concerto.* to concerto@'localhost' IDENTIFIED BY '#{random_password}';flush privileges;"
system("mysql -u root -p#{password} -e \"#{query}\"")
database_yml = %{development:
adapter: mysql2
database: concerto
username: concerto
password: #{random_password}
host: localhost
production:
adapter: mysql2
database: concerto
username: concerto
password: #{random_password}
host: localhost}
#write new YAML to database config file in concerto
File.open("#{$concerto_location}/config/database.yml", 'w') {|f| f.write(database_yml) }
end
def windows_download
#get the full path to the user's temp directory and chop off the newline
user_tempdir = `echo %TEMP%`.chomp
#download the Github zipball (and do some acrobatics b/c Github doesn't know how to package a zip)
download_file("https://github.com/concerto/concerto/archive/#{get_tag()}.zip", "#{user_tempdir}\\concerto.zip")
#Windows has no unzip executable - so let's download a a nice standalone one
download_file("http://stahlworks.com/dev/unzip.exe", "#{user_tempdir}\\unzip.exe")
#unzip the concerto archive from Github into the temp directory
system("%temp%\\unzip.exe %temp%\\concerto.zip -d %temp%\\concerto")
#Now the tricky part: github packs a folder appended with the commit id into the root of the zip
#-which makes unarchiving tricky on a non-Debian system (Debian provides the pathname param to deal with this)
#Move the only directory in temp/concerto to c:\concerto (or whatever location)
system("for /D %j in (%temp%\\concerto\\*) do move %j #{windows_path($concerto_location)}")
#Be neat - clean up all temp files and folders used
`del /q /s %temp%\\unzip.exe %temp%\\concerto.zip`
`rmdir /q /s %temp%\\concerto`
end
#Cross-platform way of finding an executable in the $PATH
#which('ruby') #=> /usr/bin/ruby
#Courtesy of Mislav Marohnic (via Stackoverflow)
def which(cmd)
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each { |ext|
exe = "#{path}/#{cmd}#{ext}"
return exe if File.executable? exe
}
end
return nil
end
#Check for existence of a command for use
def command?(command)
if which(command) != nil
return true
else
return false
end
end
#take a normal *nix path and return a properly escaped Windows one
def windows_path(nix_path)
nix_path.gsub('/', '\\')
end
def generate_password(len)
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
newpass = ""
1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
return newpass
end
def check_general_depends
unmet_depends = Array.new
unless command?("convert")
unmet_depends << "ImageMagick is not properly installed or is not in the PATH.\n"
end
if $database_type == "mysql"
unless command?("mysql")
unmet_depends << "MySQL Client is not properly installed or is not in the PATH.\n"
end
unless command?("mysqld")
unmet_depends << "MySQL daemon is not properly installed or is not in the PATH.\n"
end
end
#Warn the user about unmet dependencies
unless unmet_depends.empty?
unmet_depends.each {|d| print d}
end
end
def package?(package_name)
#grep through the output of dpkg -s to see if a package status is given. If so, we assume it's installed and working
if system("dpkg -s #{package_name} | grep Status") != true
return false
else
return true
end
end
def check_deb_pkg_depends
#Concerto imagemagick package dependencies
pkg_depends = ['imagemagick', 'librmagick-ruby', 'libmagickcore-dev', 'libmagickwand-dev']
#Add additional MySQL package requirements (if -d mysql is invoked)
if $database_type == "mysql"
pkg_depends << "mysql-server" << "mysql-client" << "libmysql-ruby1.9.1"
end
#all unmet dependencies will be pushed onto this array
unmet_depends = Array.new
pkg_depends.each do |package_name|
if package?(package_name) != true
unmet_depends << package_name
end
end
#Warn the user about unmet dependencies
unless unmet_depends.empty?
puts "Dependencies not met! Concerto requires the packages: #{unmet_depends.each {|d| print d, ", " } }"
end
end
# Returns true if we are running on a MS windows platform, false otherwise.
#Don't know where the mingw32 signature came along - but it's needed
def Kernel.is_windows?
processor, platform, *rest = RUBY_PLATFORM.split("-")
platform == 'mswin32' || platform == 'mingw32'
end
#download given file to specified destination using open-uri
def download_file(file_url, file_destination)
File.open(file_destination, "wb") do |saved_file|
# the following "open" is provided by open-uri
open(file_url) do |read_file|
saved_file.write(read_file.read)
end
end
end
main()