require 'highline' require 'tempfile' require 'ember' require 'etc' class Installer # ---------------------------------------- # Template variables # ---------------------------------------- attr_reader :database_hostname, :database_port, :database_name, :sites_root, :ruby_path, :web_port, :dns_port, :user, :group, :public_directory def default_sites_root if `uname -a` =~ /Darwin/ File.expand_path('~/Sites') else '/var/www' end end def default_ruby_path if Config.ruby =~ /rubies\/(.*)\/bin/ `rvm wrapper #{$1} yodel` `which yodel_ruby`.strip else Config.ruby end end def assign_default_user_and_group pwnam = Etc.getpwnam(Etc.getlogin) @user = pwnam.uid @group = pwnam.gid end def default_group end def initialize # assign default values; not all values have associated questions # presented to the user depen @database_hostname = 'localhost' @database_port = 27017 @database_name = 'yodel' @web_port = 80 @dns_port = 2828 @public_directory = '/var/www' @sites_root = default_sites_root @ruby_path = default_ruby_path assign_default_user_and_group end # ---------------------------------------- # Helpers # ---------------------------------------- def system_path @system_path ||= File.join(File.dirname(__FILE__), '..', '..', '..', 'system') end def report(verb, noun) @h.say "<%= color('#{verb}', GREEN) %>\t#{noun}" end def escape_quotes(str) str.gsub("'", "\\\\'") end def install(file, permissions='0644', file_name=nil) if file_name dest_path = File.join('/', File.dirname(file), file_name) else dest_path = File.join('/', file) end source_path = File.join(system_path, file) temp_file = Tempfile.new('yodel') report('installing', dest_path) # render the file template temp_file.write Ember::Template.new(IO.read(source_path), {source_file: source_path}).render(binding) temp_file.close # create parent directories, copy the rendered file and set permissions `sudo mkdir -p #{File.dirname(dest_path)}` `sudo cp #{temp_file.path} #{dest_path}` `sudo chmod #{permissions} #{dest_path}` # delete the temp file used for rendering temp_file.unlink end # ---------------------------------------- # Q & A # ---------------------------------------- def install_system_files @h = h = HighLine.new h.say "\n<%= color('Welcome to Yodel', BOLD) %>\n\n" # environment h.say "<%= color('Environment', BOLD) %>" h.say "Yodel can run in development (local) mode or as a production server. Press" h.say "enter to setup Yodel in development mode, or enter 'production' to setup" h.say "a production server." @environment = h.ask("Environment: ") do |q| q.default = 'development' q.in = %w{development production} q.responses[:ask_on_error] = :question end # local sites directory h.say "\n<%= color('1/3', RED) %> <%= color('Sites Directory', BOLD) %>" h.say "Yodel stores each of your sites in a single directory. You may place this directory" h.say "anywhere, but all sites created by Yodel must be accessible from it. Press enter to" h.say "accept the default directory, or enter a new path." @sites_root = h.ask("Sites directory: ") do |q| q.default = @sites_root q.responses[:ask_on_error] = :question end @sites_root = escape_quotes(@sites_root) # web server port if @environment == 'development' h.say "\n<%= color('2/3', RED) %> <%= color('Local Server', BOLD) %>" h.say "By default the yodel server will run on port 80, meaning you can access yodel" h.say "sites by visiting . If you already have Apache or" h.say "another web server running on this port, enter a different port (such as 8080)" @web_port = h.ask("Use port: ", Integer) do |q| q.default = @web_port q.responses[:ask_on_error] = :question end else h.say "\n<%= color('2/3', RED) %> <%= color('Public Directory', BOLD) %>" h.say "Yodel symlinks the public directory of sites served by the production server" h.say "to a directory visible to the fronting web server. The domain of a site is" h.say "used as the link name, meaning /var/www/domain.com could e.g link to" h.say "/var/git/ID/public. This makes serving public assets from a fronting server" h.say "possible by rewriting the request path to include the domain of the request." @public_directory = h.ask("Public directory: ") do |q| q.default = @public_directory q.responses[:ask_on_error] = :question end @public_directory = escape_quotes(@public_directory) end h.say "\n<%= color('3/3', RED) %> <%= color('Installing files', BOLD) %>" h.say "Yodel will now install the necessary system files. You may be asked to enter" h.say "your local user password.\n\n" h.say "-----------------------------------------------------------------------------\n\n" # install system files if `uname -a` =~ /Darwin/ install_mac_files else install_linux_files end # start yodel for environment installation report('starting', 'yodel') require '../../yodel' Yodel.config.extensions_folder = $extensions_folder if $extensions_folder Yodel.load_extensions # install an environment support site report('installing', "#{@environment} environment support site") site = Site.new site.name = "yodel" site.domains = ['yodel', 'localhost', '127.0.0.1'] extension = Yodel.extensions["yodel_#{@environment}_environment"] puts "Installation environment (#{@environment}) not found" and exit(1) if extension.nil? site.root_directory = extension.lib_dir site.save Migration.run_migrations(site) h.say "\n-----------------------------------------------------------------------------" h.say "\n<%= color('Installation complete', BOLD) %>" h.say "Visit http://yodel#{":#{@web_port}" if @web_port != 80}/ to setup accounts you have on a remote Yodel server." h.say "You can create a new site by visiting and" h.say "following the instructions\n\n" end # ---------------------------------------- # OS X # ---------------------------------------- def install_mac_files install 'etc/resolver/yodel' install 'Library/LaunchDaemons/com.yodelcms.dns.plist' install 'Library/LaunchDaemons/com.yodelcms.server.plist' install 'usr/local/bin/yodel_command_runner', '0777' install 'var/log/yodel.log', '0666' case @environment when 'development' install 'usr/local/etc/yodel/development_settings.rb', '0644', 'settings.rb' when 'production' install 'usr/local/etc/yodel/production_settings.rb', '0644', 'settings.rb' end report('starting', 'dns server') if `sudo launchctl list` =~ /\d+.+com.yodelcms.dns$/ `sudo launchctl unload /Library/LaunchDaemons/com.yodelcms.dns.plist` end `sudo launchctl load /Library/LaunchDaemons/com.yodelcms.dns.plist` report('starting', 'web server') if `sudo launchctl list` =~ /\d+.+com.yodelcms.server$/ `sudo launchctl unload /Library/LaunchDaemons/com.yodelcms.server.plist` end `sudo launchctl load /Library/LaunchDaemons/com.yodelcms.server.plist` end # ---------------------------------------- # Linux # ---------------------------------------- def install_linux_files install 'usr/local/bin/yodel_command_runner', '0777' install 'var/log/yodel.log', '0666' case @environment when 'development' install 'usr/local/etc/yodel/development_settings.rb', '0644', 'settings.rb' when 'production' install 'usr/local/etc/yodel/production_settings.rb', '0644', 'settings.rb' end end end