1 SCRIPT_PATH = File.dirname(File.expand_path(__FILE__))
8 INSTALLED_DPKGS = `dpkg -l | awk '{print $2}'`.split("\n")
9 # # NOTE: INSTALLED_DPKGS does not work quite as expected
12 def self.puts(data='')
16 postfix = ".#{Time.now.strftime("%Y%m%d_%H%M%S")}"
17 @log_file = File.new("#{SCRIPT_PATH}/log/install.log#{postfix}",
18 File::CREAT|File::TRUNC|File::WRONLY)
21 @log_file << data << "\n"
30 def Install.`(cmd) # ` emacs fix
33 i, o, e = Open3.popen3(cmd)
35 # Gather STDOUT first!
36 output = o.entries.join
46 WHOAMI = `whoami`.strip
58 def initialize(initial_value)
63 return "\n---> Step #@s"
67 print_step = NextStep.new(last_step_in_bash)
69 def Install.expected_src_compression(url)
70 if url =~ /^.*\/(.*)(\.tgz|\.tar\.gz|\.zip|\.tar\.bz2)$/
79 raise "Unknown file extension for #{$&.inspect}"
83 raise "Invalid: #@rubygems_src_url"
87 def Install.expected_src_dir(url)
88 if url =~ /^.*\/(.*)(\.tgz|\.tar\.gz|\.zip|\.tar\.bz2)$/
89 return "#@sources_dir/#{$1}"
91 raise "Invalid: #{url}"
95 def Install.download_open_source(url)
96 if File.exists?(File.expand_path(expected_src_dir(url)))
99 compression = expected_src_compression(url)
100 `wget -O- #{url} | tar -C #@sources_dir --#{compression} -xvf -`
104 def Install.apt_install(package)
105 ## PROBLEM: dpkg show as if the package is still there if
106 ## there it's marked as C (conflicting)
108 #if INSTALLED_PACKAGES.include?(package)
111 `apt-get install #{package} --assume-yes --no-remove`
115 def Install.check_mysql_password(pw)
116 i, o, e = Open3.popen3("mysqladmin --password=\"#{pw}\" -u root password \"#{pw}\"")
120 return true if e.entries.join('').empty?
125 def Install.set_mysql_password(new_pw)
126 #This will only set the password if the current root password is empty.
127 i, o, e = Open3.popen3("mysqladmin -u root password \"#{new_pw}\"")
131 errs = e.entries.join("\n")
132 return true if errs.empty?
137 def Install.get_config_mysql_password
138 File.open("#{SCRIPT_PATH}/config/database.yml").each do |line|
139 if line =~ /^[ ]*password:[ ]*([^\s]*)/
146 def Install.gem_install(package, arguments)
147 if INSTALLED_GEMS.include?(package)
150 `gem install #{package} #{arguments} --include-dependencies --remote`
154 puts print_step.next!
155 # Installing emacs with ruby-mode and a spell-checker
156 # because otherwise some Mwamko developers will have a
157 # had time maintaining this server without their
160 apt_install('emacs21-nox')
161 apt_install('ruby1.8-elisp')
162 apt_install('ispell')
165 puts print_step.next!
166 apt_install('mysql-client')
167 apt_install('mysql-server')
170 puts print_step.next!
172 @sources_dir = File.expand_path("#{SCRIPT_PATH}/../mwamko_dependencies")
173 `mkdir --parents #@sources_dir`
174 `chown -R --no-dereference --reference=#{SCRIPT_PATH}/.. #@sources_dir`
177 "http://rubyforge.org/frs/download.php/17190/rubygems-0.9.2.tgz"
180 "http://www.lighttpd.net/assets/2007/1/29/lighttpd-1.4.13.tar.gz"
183 "http://download.openvz.org/utils/vzctl/3.0.16/src/vzctl-3.0.16.tar.bz2"
186 "http://download.openvz.org/utils/vzquota/3.0.9/src/vzquota-3.0.9.tar.bz2"
188 puts print_step.next!
189 download_open_source(@rubygems_src_url)
192 puts print_step.next!
193 if File.exists?('/usr/bin/gem')
196 `cd #{expected_src_dir(@rubygems_src_url)}; ruby setup.rb`
200 puts print_step.next!
201 puts "Installing Lighttpd dependencies ..."
204 apt_install('build-essential')
205 apt_install('openssl')
206 apt_install('libssl-dev')
207 apt_install('zlib1g-dev')
208 apt_install('libpcre3-dev')
209 apt_install('libpcre3')
210 # lighttpd 1.5.0 will require libglibmm-2.4-dev
214 apt_install('libfcgi-dev')
215 apt_install('libfcgi-ruby1.8')
217 puts print_step.next!
218 download_open_source(@lighttpd_src_url)
220 puts print_step.next!
221 if File.exists?('/usr/local/sbin/lighttpd')
225 "./configure --with-openssl --with-openssl-libs=/usr/lib"
226 cmd = "cd #{expected_src_dir(@lighttpd_src_url)}; #{lighttpd_config}"
228 cmd += "; make install"
232 puts print_step.next!
233 `mkdir --parents /var/www/html`
236 puts print_step.next!
237 puts "Coping Rails MySQL configuration file"
239 traditional_db_config_path = "#{SCRIPT_PATH}/config/database.yml"
240 db_config_template = "#{SCRIPT_PATH}/config/database.template"
244 cmd = "cat #{SCRIPT_PATH}/config/available_ip_addresses.range.template > " +
245 "/etc/mwamko/available_ip_addresses.range.rb"
248 `cp #{SCRIPT_PATH}/config/dns.settings.template /etc/mwamko/dns.settings.rb`
249 `touch /etc/mwamko/allowed_emails.list`
252 unless File.exists? '/etc/mwamko/database.yml'
253 cmd = "cp #{db_config_template} /etc/mwamko/database.yml"
257 `chmod -R a+Xr /etc/mwamko`
259 cmd = "unlink #{traditional_db_config_path}"
262 cmd = "ln -s /etc/mwamko/database.yml #{traditional_db_config_path}"
266 "chown --no-dereference --reference=#{SCRIPT_PATH}/.. " +
267 traditional_db_config_path
271 puts print_step.next!
272 puts "Setting-up MySQL"
274 rails_config_file = traditional_db_config_path
276 if not check_mysql_password(get_config_mysql_password) and not get_config_mysql_password != ''
277 puts "Incorrect password in #{traditional_db_config_path}"
281 if not check_mysql_password('')
282 if get_config_mysql_password == ''
284 MySQL has a password for root.
285 You must put this password in #{traditional_db_config_path}
290 #The root password is blank
292 require 'lib/password_gen'
293 new_password = PasswordGen.generate_pronounceable(16)
295 puts 'setting mysql root password to ' + new_password
296 result = set_mysql_password(new_password)
298 raise "failed to set mysql password" unless result
301 Open3.popen3("sed 's/\\(password:\\).*$/\\1 #{new_password}/'" +
302 " < #{rails_config_file}")
304 # Gather STDOUT first!
305 db_config_temporary =
306 "#{rails_config_file}.tmp.#{Time.now.to_i}"
308 f = File.open(db_config_temporary,
309 File::CREAT|File::TRUNC|File::WRONLY)
315 errors = e.entries.join
316 raise "Got unexpected STDERR: #{errors}" if errors != ''
318 `cat #{db_config_temporary} > #{rails_config_file}`
319 `rm #{db_config_temporary}`
322 ['mwamko_production', 'mwamko_test'].each do |db_name|
324 Open3.popen3(["mysqladmin create #{db_name}",
325 "-u root --password=#{new_password}"].join(' '))
326 # Gather STDOUT first!
329 errors = e.entries.join
331 raise "Error when creating database: #{errors}"
339 puts print_step.next!
340 puts "Installing the mysql rubygem dependencies..."
342 apt_install('ruby1.8-dev')
343 apt_install('libmysqlclient15-dev')
347 `gem list | grep -v "^ " | awk '{print $1}'`.split("\n")
349 INSTALLED_GEMS.delete("")
350 INSTALLED_GEMS.delete_at(0)
352 puts print_step.next!
353 puts "Installing Rails..."
355 `wget --directory-prefix=#{@sources_dir} \
356 http://wiki.mwamko.cs.ucr.edu/download/rails-1.2.3-gems.tar.bz2`
357 `tar --directory #{@sources_dir} -jxf #{@sources_dir}/*tar.bz2`
358 `gem install #{@sources_dir}/rails-1.2.3-gems/*\.gem`
360 puts print_step.next!
361 puts "Installing the mysql rubygem..."
362 gem_install "mysql", "--version 2.7"
367 puts print_step.next!
368 `cd #{SCRIPT_PATH}; rake db:migrate RAILS_ENV=production`
371 puts print_step.next!
372 puts 'Installing dependencies for BackgroundRb...'
374 gem_install "daemons", ''
375 gem_install "slave", ''
378 puts print_step.next!
379 unless `uname -r` =~ /ovz/
380 puts "WARNING: You do not seem to be running under an OpenVZ kernel."
381 puts " I was expecting to see 'ovz' in the kernel-release name."
382 puts " Mwamko will not be able to operate without OpenVZ."
386 puts "OpenVZ kernel detection ... PASSED"
390 puts print_step.next!
391 download_open_source(@vzctl_src_url)
393 puts print_step.next!
394 if File.exists?('/usr/local/sbin/vzctl')
399 `cd #{expected_src_dir(@vzctl_src_url)}; #{config}; make`
400 `make install -C #{expected_src_dir(@vzctl_src_url)}`
402 ['arpsend'].each do |n|
403 `ln -s /usr{/local,}/sbin/#{n}`
408 puts print_step.next!
409 download_open_source(@vzquota_src_url)
411 puts print_step.next!
412 if File.exists?('/usr/sbin/vzqouta')
415 src_path = expected_src_dir(@vzquota_src_url)
416 `make install -C #{src_path}`
418 ['vzquota', 'vzdqdump', 'vzdqload', 'vzdqcheck'].each do |n|
419 `ln -s /usr{,/local}/sbin/#{n}`
425 puts print_step.next!
426 puts "Setting-up the mwamko user"
428 puts print_step.next!
434 `useradd --create-home --gid mwamko mwamko`
438 # TODO: Stop it from leaving a whole bunch of new lines
439 puts "Removing all lines with %mwamko from /ect/sudoers"
440 `su -c "sed 's/.*%mwamko.*//' < /etc/sudoers > /etc/sudoers.mwamko.tmp"`
441 `cp /etc/sudoers.mwamko.tmp /etc/sudoers`
442 `rm /etc/sudoers.mwamko.tmp`
444 puts "Granting some sudoers permissions to the mwamko group"
445 `su -c "echo %mwamko ALL=\\(ALL\\) NOPASSWD: /usr/local/sbin/lighttpd >> /etc/sudoers"`
447 `su -c "echo %mwamko ALL=\\(ALL\\) NOPASSWD: /usr/local/sbin/vzctl >> /etc/sudoers"`
449 `su -c "echo %mwamko ALL=\\(ALL\\) NOPASSWD: /usr/local/sbin/vzlist >> /etc/sudoers"`
451 `su -c "echo %mwamko ALL=\\(ALL\\) NOPASSWD: /bin/mv >> /etc/sudoers"`
452 `su -c "echo %mwamko ALL=\\(ALL\\) NOPASSWD: /bin/cat >> /etc/sudoers"`
456 puts print_step.next!
457 puts "NOTE: If the system is restarted then this will be lost."
458 puts "This should be in a system startup script"
467 `ip link set venet0 up`
468 `ip addr add 0.0.0.0/0 dev venet0`
469 `sysctl -w net.ipv4.conf.venet0.send_redirects=0`
472 puts print_step.next!
473 puts "Cleaning up any previously started Mwamko services"
477 brb_pid = `ps -A -o pid,command | awk '/backgroundrb$/ {print $1}'`
478 brb_pid.each do |pid|
479 `kill #{brb_pid.to_i}`
483 puts print_step.next!
484 `./lib/tasks/install_openvz/sysctl_setup`
486 puts print_step.next!
487 `cp -pdr ../mwamko ~mwamko/`
488 `chown -R mwamko:mwamko ~mwamko/mwamko`
489 `su mwamko -c "~/mwamko/script/server start_after_install production"`