diff options
author | Johan Sørensen <johan@johansorensen.com> | 2008-04-16 00:54:43 +0200 |
---|---|---|
committer | Johan Sørensen <johan@johansorensen.com> | 2008-04-16 00:54:43 +0200 |
commit | 4ee78e5834e60a3fa4e2f10b0760a40f02cd1b31 (patch) | |
tree | ed9862a5c0975cf2935e9b3c7fb235f0b369a082 /script/git-daemon | |
parent | 6d7b1d1c9c1b4061770a2dbf8a8778beec737767 (diff) | |
download | gitorious-mainline-outdated-4ee78e5834e60a3fa4e2f10b0760a40f02cd1b31.zip gitorious-mainline-outdated-4ee78e5834e60a3fa4e2f10b0760a40f02cd1b31.tar.gz gitorious-mainline-outdated-4ee78e5834e60a3fa4e2f10b0760a40f02cd1b31.tar.bz2 |
made the ruby git-daemon support options and moved things around a bit on the class
Diffstat (limited to 'script/git-daemon')
-rwxr-xr-x | script/git-daemon | 226 |
1 files changed, 141 insertions, 85 deletions
diff --git a/script/git-daemon b/script/git-daemon index e17a4d8..a0e0ba0 100755 --- a/script/git-daemon +++ b/script/git-daemon @@ -4,11 +4,15 @@ require 'rubygems' require 'daemons' require 'geoip' require 'socket' +require "optparse" ENV["RAILS_ENV"] ||= "production" require File.dirname(__FILE__)+'/../config/environment' Rails.configuration.log_level = :info # Disable debug +ActiveRecord::Base.logger = nil +ActiveRecord::Base.allow_concurrency = true +ActiveRecord::Base.clear_active_connections! BASE_PATH = File.expand_path(GitoriousConfig['repository_base_path']) @@ -17,115 +21,167 @@ $children_reaped = 0 $children_active = 0 module Git - -class Daemon - include Daemonize - - def self.start - new - end - - def initialize - daemonize(File.join(RAILS_ROOT, "log", "git-daemon.log")) + class Daemon + include Daemonize - @geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat")) - trap "CLD" do - pid = Process.wait - $children_reaped += 1 - log(pid, "Disconnected. (status=#{$?.exitstatus})") - - $children_reaped = $children_active = 0 if $children_reaped == $children_active + SERVICE_REGEXP = /(\w{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze + + def initialize(options) + @options = options + @geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat")) end - port = 9418 - server = TCPServer.new('localhost', port) - service_regexp = /(\w{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze - while session = server.accept - $children_active += 1 - - if $children_active - $children_reaped > MAX_CHILDREN - log(Process.pid, "too many active children #{$children_active - $children_reaped}/#{MAX_CHILDREN}") - session.close - # we didn't actually do the fork, so decrease the count - $children_active -= 1 - next + def start + if @options[:daemonize] + daemonize(@options[:logfile]) end + @socket = TCPServer.new(@options[:host], @options[:port]) + log(Process.pid, "Listening on #{@options[:host]}:#{@options[:port]}...") + run + end - line = session.recv(1000) - timeout = 30 - if line =~ service_regexp - code = $1 - service = $2 - base_path = $3 - host = $4 - - path = "#{BASE_PATH}/#{base_path}" - if !File.join(File.expand_path(path)).index(BASE_PATH) == 0 || !File.directory?(path) - log(Process.pid, "Invalid path: #{base_path}") + def run + while session = @socket.accept + $children_active += 1 + + if $children_active - $children_reaped > MAX_CHILDREN + log(Process.pid, "too many active children #{$children_active - $children_reaped}/#{MAX_CHILDREN}") session.close $children_active -= 1 next end + + line = session.recv(1000) + timeout = 30 + if line =~ SERVICE_REGEXP + code = $1 + service = $2 + base_path = $3 + host = $4 - if !File.exist?(File.join(path, "git-daemon-export-ok")) - session.close - $children_active -= 1 - next - end + path = File.expand_path("#{BASE_PATH}/#{base_path}") + if !path.index(BASE_PATH) == 0 || !File.directory?(path) + log(Process.pid, "Invalid path: #{base_path}") + session.close + $children_active -= 1 + next + end + + if !File.exist?(File.join(path, "git-daemon-export-ok")) + session.close + $children_active -= 1 + next + end - Dir.chdir(path) do - cmd = "git-upload-pack --strict --timeout=#{timeout} ." + Dir.chdir(path) do + cmd = "git-upload-pack --strict --timeout=#{timeout} ." - fork do - repository = nil - begin - ActiveRecord::Base.allow_concurrency = true - repository = ::Repository.find_by_path(path) - rescue Exception - end - pid = Process.pid - ip_family, port, name, ip = session.peeraddr - log(pid, "Connection from #{ip} for #{path.inspect}") + fork do + repository = nil + + begin + repository = ::Repository.find_by_path(path) + rescue => e + log(Process.pid, "AR error: #{e.class.name} #{e.message}:\n #{e.backtrace.join("\n ")}") + end + + pid = Process.pid + ip_family, port, name, ip = session.peeraddr + log(pid, "Connection from #{ip} for #{path.inspect}") - $stdout.reopen(session) - $stdin.reopen(session) - session.close + $stdout.reopen(session) + $stdin.reopen(session) + session.close - if repository - if ip_family == "AF_INET6" - repository.cloned_from(ip) + if repository + if ip_family == "AF_INET6" + repository.cloned_from(ip) + else + localization = @geoip.country(ip) + repository.cloned_from(ip, localization[3], localization[5]) + end else - localization = @geoip.country(ip) - repository.cloned_from(ip, localization[3], localization[5]) + log(pid, "Cannot find repository: #{path}") end - else - log(pid, "Cannot find repository: #{path}") - end - exec(cmd) - $children_reaped += 1 - exit! + exec(cmd) + $children_reaped += 1 + exit! + end end + else + $stderr.puts "Invalid request: #{line}" + session.close + $children_active -= 1 + next end - else - $stderr.puts "Invalid request: #{line}" - session.close - $children_active -= 1 - next end end - end - def log(pid, msg) - $stderr.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} [#{pid}] #{msg}" + def handle_stop(signal) + log(Process.pid, "Received #{signal}, exiting..") + exit 0 + end + + def handle_cld + pid = Process.wait + $children_reaped += 1 + log(pid, "Disconnected. (status=#{$?.exitstatus})") + + if $children_reaped == $children_active + $children_reaped = 0 + $children_active = 0 + end + end + + def log(pid, msg) + $stderr.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} [#{pid}] #{msg}" + end + end end -end +options = { + :port => 9418, + :host => "localhost", + :logfile => File.join(RAILS_ROOT, "log", "git-daemon.log"), + :daemonize => false + +} -trap "SIGINT" do - $stderr.puts "Exiting..." - exit 0 -end +OptionParser.new do |opts| + opts.banner = "Usage: #{$0} start|stop [options]" + + opts.on("-p", "--port", Integer, "Port to listen on") do |o| + options[:port] = o + end + + opts.on("-h", "--host", "Host to listen on") do |o| + options[:host] = o + end + + opts.on("-l", "--logfile", "File to log to") do |o| + options[:logfile] = o + end + + opts.on("-d", "--daemonize", "Daemonize or run in foreground (default)") do |o| + options[:daemonize] = o + end + + # opts.on("-e", "--environment", "RAILS_ENV to use") do |o| + # options[:port] = o + # end +end.parse! + +#puts options.inspect + +@git_daemon = Git::Daemon.new(options) + +trap("SIGKILL") { @git_daemon.handle_stop("SIGKILL") } +trap("TERM") { @git_daemon.handle_stop("TERM") } +trap("SIGINT") { @git_daemon.handle_stop("SIGINT") } +trap("CLD") { @git_daemon.handle_cld } + +@git_daemon.start -Git::Daemon.start +#Git::Daemon.start |