有一段时间我无法从我的 GitLab 实例运行 webhook。起初我认为这与 GitLab 升级 ~10.0 版本或一些 iptables 相关,但现在我认为它可能更像是 Ruby 以及如何调用 Shippable 端点(在 Ruby 中?)。
在失败的请求站点上,我可以看到以下信息:
- 失败的原因是
execution expired
- URL 是
https://[username:password]@api.shippable.com/projects/[project id]/newBuild
- 它由 Shippable 在启用项目时自动生成 - X-Gitlab-Event 类型是
Push Hook
- 还有带有请求正文的 JSON
首先,我测试了凋灵,我实际上可以从服务器连接 Shippable
curl --verbose -X POST -H "Content-Type: application/json" -H "X-Gitlab-Event: $event" --data "$json" $url
请求成功,这让我认为这不是 iptables 的问题(但是我检查了,没有,没有设置 iptables 规则)。
然后我尝试在内部重新创建该请求/opt/gitlab/embedded/bin/irb
:
require 'net/http'
require 'net/https'
uri = URI.parse(url)
username = uri.userinfo.split(':')[0]
password = uri.userinfo.split(':')[1]
req = Net::HTTP::Post.new(uri.path, {'Content-Type' =>'application/json', 'X-Gitlab-Event' => event})
req.basic_auth username, password
req.body = json
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
response = http.start { |http| http.request(req) }
然后它就像在 GitLab 中一样失败了:
Net::OpenTimeout: execution expired
from /opt/gitlab/embedded/lib/ruby/2.3.0/net/http.rb:880:in `initialize'
from /opt/gitlab/embedded/lib/ruby/2.3.0/net/http.rb:880:in `open'
from /opt/gitlab/embedded/lib/ruby/2.3.0/net/http.rb:880:in `block in connect'
from /opt/gitlab/embedded/lib/ruby/2.3.0/timeout.rb:101:in `timeout'
from /opt/gitlab/embedded/lib/ruby/2.3.0/net/http.rb:878:in `connect'
from /opt/gitlab/embedded/lib/ruby/2.3.0/net/http.rb:863:in `do_start'
from /opt/gitlab/embedded/lib/ruby/2.3.0/net/http.rb:852:in `start'
from (irb):142
from embedded/bin/irb:11:in `<main>'
有趣的是,类似的事情发生在我的本地机器上:curl 成功,而 Ruby 抛出。
此外,我检查了它不应该是基本身份验证、SSL 或 POST 的问题 - 我成功地从我的服务器的 irb 在 Bitbucket 上发布了片段,就像我测试 Shippable webhook 端点一样。我什至用几乎相同的请求格式在我的模拟服务器上发布了 Shippable 请求。
在这一点上,我很好奇这种行为的原因可能是什么以及如何进一步调试它。我发现在所有失败案例中唯一不变的两个因素是目标(Shippable URI)和客户端(Ruby 的 Net::HTTP)。你还建议我检查什么?