Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitaly-ruby « bin « ruby - gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c0f17b1e5d1431eb7707947f6059de930a749ffa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env ruby

# Gitaly always spawns this executable with LANG=en_US.UTF-8. In case the
# system doesn't have this local, Ruby will fall back to the C locale and as a
# result use ASCII encoding. As this breaks reading external commands printing
# non-ASCII characters, we need to force the external encoding to UTF-8 here.
Encoding.default_external = Encoding::UTF_8

require 'fileutils'

require 'grpc'
require 'gitlab-labkit'
require 'rugged'

require_relative '../lib/gitaly_server.rb'
require_relative '../lib/gitaly_server/sentry_interceptor.rb'
require_relative '../lib/gitaly_server/exception_sanitizer_interceptor.rb'
require_relative '../lib/gitaly_server/rugged_interceptor.rb'

SHUTDOWN_TIMEOUT = 600

def main
  abort "Usage: #{$0} PPID /path/to/socket" if ARGV.length != 2
  ppid, socket_path = ARGV

  ppid_i = ppid.to_i
  abort "invalid PPID: #{ppid.inspect}" unless ppid_i > 0

  FileUtils.rm_f(socket_path)
  socket_dir = File.dirname(socket_path)
  FileUtils.mkdir_p(socket_dir)
  File.chmod(0700, socket_dir)

  set_rugged_search_path
  load_distributed_tracing

  load_tracing

  s = GRPC::RpcServer.new(
    poll_period: SHUTDOWN_TIMEOUT,
    interceptors: build_server_interceptor_chain
  )
  port = 'unix:' + socket_path
  s.add_http2_port(port, :this_port_is_insecure)
  GRPC.logger.info("... running insecurely on #{port}")

  GRPC.logger.warn("Using gitaly-proto #{Gitaly::VERSION}")
  GitalyServer.register_handlers(s)

  signal_thread = Thread.new do
    sleep
  end

  %w[TERM INT].each do |signal|
    trap(signal) { signal_thread.kill }
  end

  start_parent_watcher(ppid_i, signal_thread)

  run_thread = Thread.new do
    s.run
    signal_thread.kill
  end

  signal_thread.join
  s.stop
  run_thread.join
end

def set_rugged_search_path
  search_path = Gitlab::Config::Git.new.rugged_git_config_search_path

  return unless search_path

  Rugged::Settings['search_path_system'] = search_path
  Rugged::Settings['search_path_global'] = '/dev/null'
  Rugged::Settings['search_path_xdg'] = '/dev/null'
end

def load_distributed_tracing
  return unless Labkit::Tracing.enabled?

  tracer = Labkit::Tracing::Factory.create_tracer("gitaly-ruby", Labkit::Tracing.connection_string)
  OpenTracing.global_tracer = tracer if tracer
end

def load_tracing
  config = Gitlab::Config::Gitaly.new

  if config.rbtrace_enabled?
    GRPC.logger.info("... loading rbtrace")
    require 'rbtrace'
  end

  # rubocop:disable Style/GuardClause
  if config.objspace_trace_enabled?
    GRPC.logger.info("... loading ObjectSpace allocation tracking")
    require 'objspace'
    ObjectSpace.trace_object_allocations_start
  end
  # rubocop:enable Style/GuardClause
end

def start_parent_watcher(original_ppid, signal_thread)
  Thread.new do
    loop do
      if Process.ppid != original_ppid
        # Our original parent is gone. Self-terminate.
        signal_thread.kill
        break
      end

      sleep 1
    end
  end
end

def build_server_interceptor_chain
  chain = []
  chain << Labkit::Correlation::GRPC::ServerInterceptor.new

  json_logger = build_json_logger
  chain << json_logger if json_logger

  chain << GitalyServer::SentryInterceptor.new
  chain << Labkit::Tracing::GRPC::ServerInterceptor.new if Labkit::Tracing.enabled?
  chain << GitalyServer::ExceptionSanitizerInterceptor.new
  chain << GitalyServer::RuggedInterceptor.new

  chain
end

def build_json_logger
  output = File.open(json_log_file, 'a')
  Labkit::Logging::GRPC::ServerInterceptor.new(output, { type: 'gitaly-ruby' })
rescue IOError, Errno::EACCES => e
  GRPC.logger.warn "Unable to write to log file: #{e}"
  nil
end

def json_log_file
  if Gitlab.config.logging.dir.present?
    File.join(Gitlab.config.logging.dir, 'gitaly_ruby_json.log')
  else
    '/dev/null'
  end
end

GRPC_LOGGER = Logger.new(STDOUT)
GRPC_LOGGER.level = 'WARN'
GRPC_LOGGER.progname = 'GRPC'
GRPC_LOGGER.formatter = proc do |severity, _datetime, _progname, msg|
  "GRPC-RUBY: #{severity}: #{msg}\n"
end

module GRPC
  def self.logger
    GRPC_LOGGER
  end
end

main