File gitorious-setup-1st-time of Package gitorious

#!/usr/bin/env ruby

# == Synopsis
#
# hello: greets user, demonstrates command line parsing
#
#== Usage
#
# scrpt [OPTION] ... DIR
#
# -h, --help:
#    show help
#
# -d, --dry-run
#    do not modify config files
#
# -g dir, --gitorious dir
#    set gitorious base dir
#    default ( /srv/www/gitorious )
# -r dir, --repositories
#    set git repositories base dir
#    default ( /srv/git )
# -m, --mysql
#    setup mysql, default off
#
require 'rubygems'
require 'logger'
require 'sha1'
require 'yaml'
require 'socket'
require 'pp'
require 'diff/lcs'
require 'tempfile'

require 'getoptlong'
require 'rdoc/usage'

log = Logger.new(STDOUT)
log.level = Logger::WARN

opts = GetoptLong.new(
  [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
  [ '--dry-run', '-d', GetoptLong::NO_ARGUMENT ],
  [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
  [ '--gitorious', '-g', GetoptLong::REQUIRED_ARGUMENT ],
  [ '--repositories', '-r', GetoptLong::REQUIRED_ARGUMENT ],
  [ '--mysql', '-m', GetoptLong::NO_ARGUMENT ]
)

dry_run = false
gitorious_dir = "/srv/www/gitorious"
repositories = "/srv/git"
setup_mysql = false

opts.each do |opt, arg|
  case opt
  when '--help'
    RDoc::usage
  when '--dry-run'
    dry_run = true
  when '--gitorious'
    raise "#{arg} does not exist" if not File.directory?(arg)
    gitorious_dir = arg.to_s
  when '--repositories'
    raise "#{arg} does not exist" if not File.directory?(arg)
    repositories = arg.to_s
  when '--mysql'
    setup_mysql = true
  when '--verbose'
    log.level = Logger::INFO
  end
end

# basic gitorious setup
Dir.chdir(gitorious_dir) do
  config = YAML.load_file('config/gitorious.yml')

  target = Tempfile.new('gitorious')

  config['production'] = {} if not config.has_key?('production')

  hostname = Socket.gethostbyname(Socket.gethostname).first
  log.info "Setting hostname to #{hostname}"
  if not config['production'].has_key?('gitorious_hostname')
    config['production']['gitorious_hostname'] = hostname
  end

  if not config['production'].has_key?('cookie_secret') or 
    config['production']['cookie_secret'] == "ssssht"
    srand
    seed = "--#{rand(10000)}--#{Time.now}--"
    secret = Digest::SHA1.hexdigest(seed)
    config['production']['cookie_secret'] = secret    
    log.info "Secret set to #{secret}"
  end

  target.write(config.to_yaml(:SortKeys	=> true))
  target.close
  log.info "write config/gitorious.yml"
  File.mv(target.path, 'config/gitorious.yml') if not dry_run

  log.info "Configuring ultrasphinx"
  system("RAILS_ENV=production rake ultrasphinx:configure") if not dry_run
end

# database setup
Dir.chdir(gitorious_dir) do
  if setup_mysql
    require 'mysql'
    log.info "mysql setup..."
    begin
      # connect to the MySQL server and see if we can
      # connect as root and no passwd
      my = Mysql::new("localhost", "root")
      # it works, create a database.yml file and change the
      # mysql password
      config = YAML.load_file('config/database.yml')
      target = Tempfile.new('gitorious-database')

      srand
      seed = "--#{rand(10000)}--#{Time.now}--"
      # create a 5 characters password
      secret = Digest::SHA1.hexdigest(seed)[0,6]
      log.info "create mysql password..."      

      config.delete('production')
      config['production'] = {}
      config['production']['adapter'] = 'mysql'
      config['production']['database'] = 'gitorious_production'
      config['production']['username'] = 'gitorious'
      config['production']['password'] = secret
      config['production']['host'] = 'localhost'
      config['production']['encoding'] = 'utf8'

      target.write(config.to_yaml(:SortKeys	=> true))
      target.close

      log.info "set mysql password..."
      my.query("create user gitorious@localhost identified by '#{secret}'")
      my.query("grant all privileges on gitorious_production.* to gitorious")

      log.info "write config/database.yml"
      File.mv(target.path, 'config/database.yml') if not dry_run
    rescue
      log.error "Can't connect to mysql as root w/no pwd, no database setup done"
    end 

    log.info "Preparing and migrating database"
    system("RAILS_ENV=production rake db:create") if not dry_run
    system("RAILS_ENV=production rake db:migrate") if not dry_run
    
    log.info "Prepare ultrasphinx"
    system("RAILS_ENV=production rake ultrasphinx:prepare") if not dry_run

    log.info "Index ultrasphinx"
    system("RAILS_ENV=production rake ultrasphinx:index") if not dry_run
    
  else
    log.info "mysql setup skipped..."
  end
end

Dir.chdir(repositories) do
  sshconf = File.join(repositories, '.ssh')
  if not File.directory?(sshconf)
    log.info "Create #{sshconf}"
    Dir.mkdir(sshconf) if not dry_run
  end
  keys = File.join(sshconf, 'authorized_keys')
  log.info "Create #{keys}"
  FileUtils.touch(keys) if not dry_run
end