| |   |
| 4 | 4 | require 'daemons' |
| 5 | 5 | require 'geoip' |
| 6 | 6 | require 'socket' |
| 7 | require "optparse" |
| 7 | 8 | |
| 8 | 9 | ENV["RAILS_ENV"] ||= "production" |
| 9 | 10 | require File.dirname(__FILE__)+'/../config/environment' |
| 10 | 11 | |
| 11 | 12 | Rails.configuration.log_level = :info # Disable debug |
| 13 | ActiveRecord::Base.logger = nil |
| 14 | ActiveRecord::Base.allow_concurrency = true |
| 15 | ActiveRecord::Base.clear_active_connections! |
| 12 | 16 | |
| 13 | 17 | BASE_PATH = File.expand_path(GitoriousConfig['repository_base_path']) |
| 14 | 18 | |
| … | … | |
| 21 | 21 | $children_active = 0 |
| 22 | 22 | |
| 23 | 23 | module Git |
| 24 | | |
| 25 | | class Daemon |
| 26 | | include Daemonize |
| 27 | | |
| 28 | | def self.start |
| 29 | | new |
| 30 | | end |
| 31 | | |
| 32 | | def initialize |
| 33 | | daemonize(File.join(RAILS_ROOT, "log", "git-daemon.log")) |
| 24 | class Daemon |
| 25 | include Daemonize |
| 34 | 26 | |
| 35 | | @geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat")) |
| 36 | | trap "CLD" do |
| 37 | | pid = Process.wait |
| 38 | | $children_reaped += 1 |
| 39 | | log(pid, "Disconnected. (status=#{$?.exitstatus})") |
| 40 | | |
| 41 | | $children_reaped = $children_active = 0 if $children_reaped == $children_active |
| 27 | SERVICE_REGEXP = /(\w{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze |
| 28 | |
| 29 | def initialize(options) |
| 30 | @options = options |
| 31 | @geoip = GeoIP.new(File.join(RAILS_ROOT, "data", "GeoIP.dat")) |
| 42 | 32 | end |
| 43 | 33 | |
| 44 | | port = 9418 |
| 45 | | server = TCPServer.new('localhost', port) |
| 46 | | service_regexp = /(\w{4})(git-[\w-]+)\s(.+)\x0host=([\w\.\-]+)/.freeze |
| 47 | | while session = server.accept |
| 48 | | $children_active += 1 |
| 49 | | |
| 50 | | if $children_active - $children_reaped > MAX_CHILDREN |
| 51 | | log(Process.pid, "too many active children #{$children_active - $children_reaped}/#{MAX_CHILDREN}") |
| 52 | | session.close |
| 53 | | # we didn't actually do the fork, so decrease the count |
| 54 | | $children_active -= 1 |
| 55 | | next |
| 34 | def start |
| 35 | if @options[:daemonize] |
| 36 | daemonize(@options[:logfile]) |
| 56 | 37 | end |
| 38 | @socket = TCPServer.new(@options[:host], @options[:port]) |
| 39 | log(Process.pid, "Listening on #{@options[:host]}:#{@options[:port]}...") |
| 40 | run |
| 41 | end |
| 57 | 42 | |
| 58 | | line = session.recv(1000) |
| 59 | | timeout = 30 |
| 60 | | if line =~ service_regexp |
| 61 | | code = $1 |
| 62 | | service = $2 |
| 63 | | base_path = $3 |
| 64 | | host = $4 |
| 65 | | |
| 66 | | path = "#{BASE_PATH}/#{base_path}" |
| 67 | | if !File.join(File.expand_path(path)).index(BASE_PATH) == 0 || !File.directory?(path) |
| 68 | | log(Process.pid, "Invalid path: #{base_path}") |
| 43 | def run |
| 44 | while session = @socket.accept |
| 45 | $children_active += 1 |
| 46 | |
| 47 | if $children_active - $children_reaped > MAX_CHILDREN |
| 48 | log(Process.pid, "too many active children #{$children_active - $children_reaped}/#{MAX_CHILDREN}") |
| 69 | 49 | session.close |
| 70 | 50 | $children_active -= 1 |
| 71 | 51 | next |
| 72 | 52 | end |
| 53 | |
| 54 | line = session.recv(1000) |
| 55 | timeout = 30 |
| 56 | if line =~ SERVICE_REGEXP |
| 57 | code = $1 |
| 58 | service = $2 |
| 59 | base_path = $3 |
| 60 | host = $4 |
| 73 | 61 | |
| 74 | | if !File.exist?(File.join(path, "git-daemon-export-ok")) |
| 75 | | session.close |
| 76 | | $children_active -= 1 |
| 77 | | next |
| 78 | | end |
| 62 | path = File.expand_path("#{BASE_PATH}/#{base_path}") |
| 63 | if !path.index(BASE_PATH) == 0 || !File.directory?(path) |
| 64 | log(Process.pid, "Invalid path: #{base_path}") |
| 65 | session.close |
| 66 | $children_active -= 1 |
| 67 | next |
| 68 | end |
| 69 | |
| 70 | if !File.exist?(File.join(path, "git-daemon-export-ok")) |
| 71 | session.close |
| 72 | $children_active -= 1 |
| 73 | next |
| 74 | end |
| 79 | 75 | |
| 80 | | Dir.chdir(path) do |
| 81 | | cmd = "git-upload-pack --strict --timeout=#{timeout} ." |
| 76 | Dir.chdir(path) do |
| 77 | cmd = "git-upload-pack --strict --timeout=#{timeout} ." |
| 82 | 78 | |
| 83 | | fork do |
| 84 | | repository = nil |
| 85 | | begin |
| 86 | | ActiveRecord::Base.allow_concurrency = true |
| 87 | | repository = ::Repository.find_by_path(path) |
| 88 | | rescue Exception |
| 89 | | end |
| 90 | | pid = Process.pid |
| 91 | | ip_family, port, name, ip = session.peeraddr |
| 92 | | log(pid, "Connection from #{ip} for #{path.inspect}") |
| 79 | fork do |
| 80 | repository = nil |
| 81 | |
| 82 | begin |
| 83 | repository = ::Repository.find_by_path(path) |
| 84 | rescue => e |
| 85 | log(Process.pid, "AR error: #{e.class.name} #{e.message}:\n #{e.backtrace.join("\n ")}") |
| 86 | end |
| 87 | |
| 88 | pid = Process.pid |
| 89 | ip_family, port, name, ip = session.peeraddr |
| 90 | log(pid, "Connection from #{ip} for #{path.inspect}") |
| 93 | 91 | |
| 94 | | $stdout.reopen(session) |
| 95 | | $stdin.reopen(session) |
| 96 | | session.close |
| 92 | $stdout.reopen(session) |
| 93 | $stdin.reopen(session) |
| 94 | session.close |
| 97 | 95 | |
| 98 | | if repository |
| 99 | | if ip_family == "AF_INET6" |
| 100 | | repository.cloned_from(ip) |
| 96 | if repository |
| 97 | if ip_family == "AF_INET6" |
| 98 | repository.cloned_from(ip) |
| 99 | else |
| 100 | localization = @geoip.country(ip) |
| 101 | repository.cloned_from(ip, localization[3], localization[5]) |
| 102 | end |
| 101 | 103 | else |
| 102 | | localization = @geoip.country(ip) |
| 103 | | repository.cloned_from(ip, localization[3], localization[5]) |
| 104 | log(pid, "Cannot find repository: #{path}") |
| 104 | 105 | end |
| 105 | | else |
| 106 | | log(pid, "Cannot find repository: #{path}") |
| 107 | | end |
| 108 | 106 | |
| 109 | | exec(cmd) |
| 110 | | $children_reaped += 1 |
| 111 | | exit! |
| 107 | exec(cmd) |
| 108 | $children_reaped += 1 |
| 109 | exit! |
| 110 | end |
| 112 | 111 | end |
| 112 | else |
| 113 | $stderr.puts "Invalid request: #{line}" |
| 114 | session.close |
| 115 | $children_active -= 1 |
| 116 | next |
| 113 | 117 | end |
| 114 | | else |
| 115 | | $stderr.puts "Invalid request: #{line}" |
| 116 | | session.close |
| 117 | | $children_active -= 1 |
| 118 | | next |
| 119 | 118 | end |
| 120 | 119 | end |
| 121 | | end |
| 122 | 120 | |
| 123 | | def log(pid, msg) |
| 124 | | $stderr.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} [#{pid}] #{msg}" |
| 121 | def handle_stop(signal) |
| 122 | log(Process.pid, "Received #{signal}, exiting..") |
| 123 | exit 0 |
| 124 | end |
| 125 | |
| 126 | def handle_cld |
| 127 | pid = Process.wait |
| 128 | $children_reaped += 1 |
| 129 | log(pid, "Disconnected. (status=#{$?.exitstatus})") |
| 130 | |
| 131 | if $children_reaped == $children_active |
| 132 | $children_reaped = 0 |
| 133 | $children_active = 0 |
| 134 | end |
| 135 | end |
| 136 | |
| 137 | def log(pid, msg) |
| 138 | $stderr.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} [#{pid}] #{msg}" |
| 139 | end |
| 140 | |
| 125 | 141 | end |
| 126 | 142 | end |
| 127 | 143 | |
| 128 | | end |
| 144 | options = { |
| 145 | :port => 9418, |
| 146 | :host => "localhost", |
| 147 | :logfile => File.join(RAILS_ROOT, "log", "git-daemon.log"), |
| 148 | :daemonize => false |
| 149 | |
| 150 | } |
| 129 | 151 | |
| 130 | | trap "SIGINT" do |
| 131 | | $stderr.puts "Exiting..." |
| 132 | | exit 0 |
| 133 | | end |
| 152 | OptionParser.new do |opts| |
| 153 | opts.banner = "Usage: #{$0} start|stop [options]" |
| 154 | |
| 155 | opts.on("-p", "--port", Integer, "Port to listen on") do |o| |
| 156 | options[:port] = o |
| 157 | end |
| 158 | |
| 159 | opts.on("-h", "--host", "Host to listen on") do |o| |
| 160 | options[:host] = o |
| 161 | end |
| 162 | |
| 163 | opts.on("-l", "--logfile", "File to log to") do |o| |
| 164 | options[:logfile] = o |
| 165 | end |
| 166 | |
| 167 | opts.on("-d", "--daemonize", "Daemonize or run in foreground (default)") do |o| |
| 168 | options[:daemonize] = o |
| 169 | end |
| 170 | |
| 171 | # opts.on("-e", "--environment", "RAILS_ENV to use") do |o| |
| 172 | # options[:port] = o |
| 173 | # end |
| 174 | end.parse! |
| 175 | |
| 176 | #puts options.inspect |
| 177 | |
| 178 | @git_daemon = Git::Daemon.new(options) |
| 179 | |
| 180 | trap("SIGKILL") { @git_daemon.handle_stop("SIGKILL") } |
| 181 | trap("TERM") { @git_daemon.handle_stop("TERM") } |
| 182 | trap("SIGINT") { @git_daemon.handle_stop("SIGINT") } |
| 183 | trap("CLD") { @git_daemon.handle_cld } |
| 184 | |
| 185 | @git_daemon.start |
| 134 | 186 | |
| 135 | | Git::Daemon.start |
| 187 | #Git::Daemon.start |
| toggle raw diff |
--- 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 |