« AWS CodeBuildに入門失敗した話 | メイン | UDP双方向通信を実装しやすくなったソラコムBeam »

2016年12月 7日 (水)

CodeBuildでgo言語のプロジェクトをビルドする際の注意事項

こんにちは。エンジニアの島袋です。

前回に引き続き、AWS CodeBuildの話になります。

CodeBuildでgo言語のプロジェクトをビルドする場合のハマりポイントに気づいたので、そちらを紹介します。

要点から先に言うと、以下です。

  • CodeBuildは/tmp配下にリポジトリをチェックアウトするため、ビルド対象がGOPATH配下にない
  • GOPATH配下にないとvendoringが有効にならないため、go build時に「パッケージが見つからない」と言われる

go buildがコケる??

前回のエントリではbuildspec.ymlのphase名をtypoしたせいでドハマリしてたんですが、その後typoを修正し、再度ビルドを実行すると、今度はgo buildでコケました。

エラーメッセージには「cannot find package〜」と表示されています。

依存しているパッケージが見つからないということですが、そんなはずはありません。

installフェイズでglideを使い、依存パッケージは全てvendorディレクトリの中にダウンロード済みです。

では何が駄目だったのでしょうか?

ビルド対象のプロジェクトがGOPATH配下になかったため、vendoringが有効になっていなかった

GOPATHとvendoringについて簡単に説明しておくと、GOPATHはgo言語を利用する際に設定が必要になる環境変数で、ユーザが任意のパスを指定する必要があります。

go言語でbuildコマンドを叩くと、buildに必要な依存パッケージをGOPATH/src配下から走査します。

(go get "パッケージ名" とコマンドを叩くと、GOPATH/src配下にパッケージをダウンロードできます)

ところが、この方法ではプロジェクト毎に利用するパッケージのバージョンを管理することができません。

(go getコマンドは常に最新版を取得します)

そこで追加された機能がvendoringです。

vendoringは有効な状態では、GOPATH/src配下を走査する前に、プロジェクトのルートディレクトリ直下のvendorディレクトリからパッケージを走査します。

上述のglideはvendorディレクトリ内に依存パッケージをダウンロードするパッケージマネージャです。

(rubyにおけるbundlerのようなものですね)

そんな便利なvendoringなんですが、ビルド対象のプロジェクトディレクトリをGOPATH/src配下に配置していないと有効になりません。

ところが、CodeBuildはビルド対象として指定したリポジトリを"/tmp/src257031055/src"といった感じで/tmp配下にチェックアウトしてしまうんですね。

当該ディレクトリ内のvendorディレクトリ内に依存パッケージをダウンロードし、go buildコマンドを叩いても、vendoringが有効になっていないため、GOPATH/src配下した走査してくれず、「cannot find package〜」と表示されてしまうわけです。

筆者含め、go言語利用者はGOPATH/src配下にディレクトリを作ってコードを書き始めるのが半ば常識化しているため、vendoringが無効になっていることに気づくのに時間を要しました。

回避策

とりあえずのワークアラウンドなんですが、以下のようにしました。

...省略...
  pre_build:
    commands:
      - glide install
      - mkdir -p $GOPATH/src/github.com/stk132/tsg
      - mv * $GOPATH/src/github.com/stk132/tsg/.
  build:
    commands:
      - cd $GOPATH/src/github.com/stk132/tsg && go build

はい。pre_buildフェイズでGOPATH/src配下にディレクトリを切って、CodeBuildがチェックアウトしてきたリポジトリの中身を全てコピーしています。

(これで当該ディレクトリの中ではvendoringが有効になります。)

そしてbuildフェイズでは当該ディレクトリに移動して、go buildを実行します。

(cdコマンドとgo buildをチェインしているのは、別の行にわけて実行すると、元のワーキングディレクトリに戻っているためです。多分Dockerfileのビルド時と同じ挙動??)

これ、もうちょっとスマートな解決方法ないですかね。。。。?

GOPATH=$GOPATH:pwd

とかして、ワーキングディレクトリをGOPATHに追加する方法も考えたんですけど、それだとビルド対象プロジェクト内のサブパッケージが走査できなくなるんですよね。

終わりに

よくよく考えると、jenkins等も同様の問題をはらんでいる気がするのですが、もしかしてgo言語のプロジェクトのCIを回している人にとっては今回のようなのは常識だったりするのでしょうか?

筆者は専らローカルで利用するCLIコマンドばかり作っているため、ビルドもローカルマシン上で行なっていたため、まんまとハマってしまいました。

コメント

コメントを投稿

採用情報

株式会社フレクトでは、事業拡大のため、
・Salesforce/Force.comのアプリケーション開発
・HerokuやAWSなどのクラウドプラットフォーム上での
Webアプリケーション開発
エンジニア、マネージャーを募集中です。

未経験でも、これからクラウドをやってみたい方、
是非ご応募下さい。

フレクト採用ページへ

会社紹介

株式会社フレクトは、
認定コンサルタント
認定上級デベロッパー
認定デベロッパー
が在籍している、セールスフォースパートナーです。
また、heroku partnersにも登録されています。
herokuパートナー
株式会社フレクトのSalesforce/Force.com
導入支援サービス
弊社の認定プロフェッショナルが支援致します。
・Visualforce/Apexによるアプリ開発
・Salesforceと連携するWebアプリ開発
も承っております。
セールスフォースご検討の際は、
お気軽にお問合せください。

2024年4月

  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        
ブログ powered by TypePad