Edited at

[drone.io] drone-serverのデバッグ

image.png

IIJ 2018 TECHアドベントカレンダー 12/17(月)の記事です】

IIJではGithub Enterpriseと連携するCIサーバーとしてdroneを利用していますが(IIJ Engineers Blog - IIJのサービス開発を支えるGithub Enterpriseとdrone.io)、droneの知名度はまだTravis CIやCircleCIほどではなく、エラーメッセージをググっても出てこないことがあります。こんな時にはdrone-serverを直接デバッグするとすぐ解決することがあります。デバッグを始めるまでちょっとしたノウハウが必要だったので本記事で紹介したいと思います。

drone-serverはUbuntuのデスクトップPCで動かしてデバッグすることを想定します。(多分macOSでも以下の手順で動くと思います。Windowsは /var/lib/drone/ などのパスを変える必要があると思います。)


droneのバージョン

2018/12/14現在droneの最新版は1.0.0-rc.2となっていますが、ソースコードはまだ公開されていません。公開されている最新版は0.8.10となっているため、このバージョンを使うことにします。ドキュメントはこちらです。

// docker inspect drone/drone:1.0.0-rc.2 を見ると、drone 1.0.0はプライベートレポジトリ https://github.com/bradrydzewski/drone-ee (あるいはそのフォーク元)で開発されているようです。


セットアップ

image.png

参考:

デスクトップPCで動かすためngrokを使います。

ngrokを使う際はセキュリティに十分気を付けて下さい。特にGitHub Enterpriseには繋がないで下さい。URLが分かればレポジトリ一覧を閲覧することができてしまいます。

ngrok http 9999:

image.png

http://localhost:4040 を出しておくとトラブルシューティングに役立つかもしれません。

https://github.com/settings/applications/new でOAuth applicationを登録します。

image.png

以下の docker-compose.yamldocker-compose up を実行してdrone-serverを起動してみます。

// httpsだとSSL handshakeが失敗したのでhttpにしています


docker-compose.yaml

version: '2'

services:
drone-server:
image: drone/drone:0.8
ports:
- 9999:8000
- 9000
- 2345:2345
volumes:
- ./:/var/lib/drone/
restart: always
environment:
- DRONE_OPEN=true
- DRONE_HOST=https://27be75f8.ngrok.io
- DRONE_GITHUB=true
- DRONE_GITHUB_CLIENT=07cf285492f97c12f701
- DRONE_GITHUB_SECRET=11a318b4XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- DRONE_SECRET=foobar
- DRONE_DEBUG=true
privileged: true

drone-agent:
image: drone/agent:0.8
command: agent
restart: always
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DRONE_SERVER=drone-server:9000
- DRONE_SECRET=foobar


drone-serverの ports:2345:2345, privileged: true は後に出てくるdlvのために必要です。

http://27be75f8.ngrok.io にアクセスするとGitHubの認証ページにリダイレクトさるので "Authorize " をクリックします。

image.png

image.png

GitHubからdronetestのような適当なレポジトリを作って、droneでACTIVATEしてから以下の .drone.yml をpushします。


drone.yml

pipeline:

build:
image: alpine
commands:
- ls

image.png

無事にテストが実行されました。


トラブルシューティング

上手く行かない場合環境をリセットすると良いかもしれません。


drone-serverデバッグ用docker image作成

image.png

cd work/

env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go get -v github.com/drone/drone/cmd/drone-server
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go get -v -u github.com/derekparker/delve/cmd/dlv
file $GOPATH/bin/drone-server # on macOS: $GOPATH/bin/linux_amd64/drone-server
file $GOPATH/bin/dlv # on macOS: $GOPATH/bin/linux_amd64/dlv
# => /home/wsh/go/bin/dlv: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped

# on linux, without CGO_ENABLED=0, dlv will be dynamically linked:
# /home/wsh/go/bin/dlv: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=f414998edff629d1700948bb15644cbd6985aa73, with debug_info, not stripped

vim Dockerfile
cp $GOPATH/bin/drone-server $GOPATH/bin/dlv ./
docker build -t dronedebug .

# drone-server: image: drone/drone:0.8 を
# drone-server: image: dronedebug に書き換え
vim docker-compose.yml

docker-compose up

# 別ターミナルで docker-compose exec app bash

Dockerfile の内容:

FROM drone/drone:0.8

EXPOSE 8000 9000 80 443 2345

COPY dlv /bin/
COPY drone-server /bin/

ENTRYPOINT ["/bin/dlv", "exec", "--headless", "--listen=:2345", "/bin/drone-server"]


drone-serverのデバッグ

docker-compose up を実行するとdlv serverがポート2345で待ち受けます。

$ docker-compose up

Recreating drone_drone-server_1_79abe9cfaada ... done
Recreating drone_drone-agent_1_ff203d9ce2d0 ... done
Attaching to drone_drone-server_1_79abe9cfaada, drone_drone-agent_1_ff203d9ce2d0
drone-agent_1_ff203d9ce2d0 | {"time":"2018-12-18T10:59:49Z","level":"debug","message":"request next execution"}
drone-server_1_79abe9cfaada | API server listening at: [::]:2345
drone-agent_1_ff203d9ce2d0 | INFO: 2018/12/18 10:59:49 grpc: addrConn.resetTransport failed to create client transport: connection error: desc = "transport: Error while dialing dial tcp 172.22.0.2:9000: getsockopt: connection refused"; Reconnecting to {drone-server:9000 <nil>}

ホストで dlv connect localhost:2345 を実行するとリモートデバッグが開始されます。

(dlv) b main.main

Breakpoint 1 set at 0xa3ecd3 for main.main() /home/wsh/go/src/github.com/drone/drone/cmd/drone-server/main.go:27
(dlv) c
> main.main() /home/wsh/go/src/github.com/drone/drone/cmd/drone-server/main.go:27 (hits goroutine(1):1 total:1) (PC: 0xa3ecd3)
Warning: debugging optimized function
22:
23: _ "github.com/joho/godotenv/autoload"
24: "github.com/urfave/cli"
25: )
26:
=> 27: func main() {
28: app := cli.NewApp()
29: app.Name = "drone-server"
30: app.Version = version.Version.String()
31: app.Usage = "drone server"
32: app.Action = server
(dlv) n
> main.main() /home/wsh/go/src/github.com/drone/drone/cmd/drone-server/main.go:28 (PC: 0xa3ece1)
Warning: debugging optimized function
23: _ "github.com/joho/godotenv/autoload"
24: "github.com/urfave/cli"
25: )
26:
27: func main() {
=> 28: app := cli.NewApp()
29: app.Name = "drone-server"
30: app.Version = version.Version.String()
31: app.Usage = "drone server"
32: app.Action = server
33: app.Flags = flags

冒頭の画像ではGoLandを使ってリモートデバッグしています。


おわりに

droneはdockerコンテナ上で動作する上にソースコードホスティングサービスとの連携もあるため手順は煩雑でしたが、ネイティブプログラムと同じようにdelveによるデバッグを行うことができました。

本記事の手順で検証用droneサーバーのリモートデバッグも可能になると思います。


ライセンス

クリエイティブ・コモンズ・ライセンス
この 作品 は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。

関連するソフトウェアの公式ドキュメントのメンテナの方へ:この記事の内容を公式ドキュメントに記載して頂ける場合、この記事にコメントして頂くか、twitter @wata_ash にご連絡下さい。