RustでAWS lambda functionの関数を作れなかった話
最近、Rustを勉強しているので、勉強がてら簡単なLambda Functionを作ったら、うまく動作させることが出来ずに終わった話
※ 惜しいところまではいったと思うので、参考になればと思い、記録に残す
ローカル環境
- Ubuntu 17.10
- Apex version 1.0.0-rc2
- rustc 1.23.0 (766bd11c8 2018-01-01)
Apex
AWS Lambda function を簡単に作れて、コマンドラインでデプロイ出来るアプリケーション
2018/02/18現在以下の言語サポートをしている
作ったもの
好きなキーワードを設定しておけば、Twitterで検索して、自動でいいねをしてくれるツール
機能自体は動きます(mainのrust_apex::run:
を外して、環境変数を設定すればOK)
デプロイまででハマった点
クロスコンパイル版(rust musl)
Apexでrustを利用するためには、クロスコンパイルしなければいけない(デプロイ時に以下のようなエラーが発生)
$ apex deploy lambda_auto_likes ⨯ Error: function lambda_auto_likes: build hook: Compiling lambda_auto_likes v0.1.0 (file:///home/snicmakino/projects/apex/tools/functions/lambda_auto_likes) error[E0463]: can't find crate for `std` | = note: the `x86_64-unknown-linux-musl` target may not be installed error: aborting due to previous error error: Could not compile `lambda_auto_likes`. To learn more, run the command again with --verbose.
以下のコマンドで、Apexで利用するためのクロスコンパイル版をインストールできます
$ rustup target add x86_64-unknown-linux-musl
OpenSSLをソースからインストール
Apexでrustを利用する際に、rust-opensslが依存関係にあるが
これをクロスコンパイル版で利用するためには、OenSSLをソースからインストールする必要がある
やらずにデプロイした時のエラーは以下の通り
$ apex deploy lambda_auto_likes ・・・ Compiling openssl-sys v0.9.24 error: failed to run custom build command for `openssl-sys v0.9.24` process didn't exit successfully: `/home/snicmakino/projects/apex/lambda_auto_likes/functions/lambda_auto_likes/target/release/build/openssl-sys-5ee2bfe045b42a7a/build-script-build` (exit code: 101) --- stdout cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_LIB_DIR cargo:rerun-if-env-changed=OPENSSL_LIB_DIR cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_INCLUDE_DIR cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR cargo:rerun-if-env-changed=X86_64_UNKNOWN_LINUX_MUSL_OPENSSL_DIR cargo:rerun-if-env-changed=OPENSSL_DIR run pkg_config fail: "Cross compilation detected. Use PKG_CONFIG_ALLOW_CROSS=1 to override" --- stderr thread 'main' panicked at ' Could not find directory of OpenSSL installation, and this `-sys` crate cannot proceed without this knowledge. If OpenSSL is installed and this crate had trouble finding it, you can set the `OPENSSL_DIR` environment variable for the compilation process. If you're in a situation where you think the directory *should* be found automatically, please open a bug at https://github.com/sfackler/rust-openssl and include information about your system as well as this message. $HOST = x86_64-unknown-linux-gnu $TARGET = x86_64-unknown-linux-musl openssl-sys = 0.9.24 ', /home/snicmakino/.cargo/registry/src/github.com-1ecc6299db9ec823/openssl-sys-0.9.24/build.rs:210:4 note: Run with `RUST_BACKTRACE=1` for a backtrace. warning: build failed, waiting for other jobs to finish... error: build failed
以下の手順でソースからOpenSSLをインストールを行う
curl -O https://www.openssl.org/source/openssl-1.1.0g.tar.gz tar xf openssl-1.1.0g.tar.gz cd openssl-1.1.0g ./Configure --prefix=/usr/local/openssl --openssldir=/usr/local/openssl linux-x86_64 -fPIC make -j$(nproc) sudo make install
Apexを利用する際に、環境変数でソース版OpenSSLの利用を指定する
export OPENSSL_DIR=/usr/local/openssl
やったぜ!!
デプロイ出来るようになった
$ apex deploy • creating function env= function=lambda_auto_likes • created alias current env= function=lambda_auto_likes version=1 • function created env= function=lambda_auto_likes name=lambda_auto_likes_lambda_auto_likes version=1
動作しない問題(未解決)
Lambdaのログを見たら、どうやら動いていない模様
手元でクロスコンパイルして動かしてみると、以下のようなエラーが発生
$ cargo run --target=x86_64-unknown-linux-musl --release Compiling lambda_auto_likes v0.1.0 (file:///home/snicmakino/projects/apex/tools/functions/lambda_auto_likes) Finished release [optimized] target(s) in 10.72 secs Running `target/x86_64-unknown-linux-musl/release/lambda_auto_likes` error: could not execute process `target/x86_64-unknown-linux-musl/release/lambda_auto_likes` (never executed)
作られたバイナリを実行しようとしてもうまく動かない
$ ./target/x86_64-unknown-linux-musl/release/lambda_auto_likes bash: ./target/x86_64-unknown-linux-musl/release/lambda_auto_likes: そのようなファイルやディレクトリはありません
まとめ
自分が作ったプログラムはクロスコンパイルすると動作させれないし、この現象は今の実力だと原因が全くわからないので解決できていないが、RustでApexデプロイをする手順は、他の人もハマる可能性があるので、とりあえず残す
ここまできて一旦終わらせるのは正直悔しいけど、このツール自体はPythonで書き直す予定
苦し紛れのツイートはこちら
やっぱりプログラミング言語は手段なので、目的に合ったものを選ぶのが良い。となると、rustは何を目的にしたときの手段として最適なのだろうか
— snicmakino (@snicmakino) 2018年2月18日