helloworlds

not a noun, it's a verb

【AWS】シンプルなリリースプロセス自動化 ( Github + CodePipeline, CodeBuild, Elastic Beanstalk )

今回はAWSを使用したシンプルなリリースプロセスの自動化について考えてみます。

リリースプロセスとは、開発から本番サーバーまであげていく(= リリース)ことをここでは指します。 また、たーっくさんのノウハウがあるので、この記事ではあくまでも一部。 やり方、状況1つでけっこうな構成が考えられるので、そこはググってみて下さい。 また、この記事ではAWSコンソールの画像は載せないので、ご自身のAWSコンソールで確認しながら用語など確認してみて下さい。 今回の記事では、本番というかステージサーバーまでというイメージになりますが、一旦構成できてしまえば、本番も簡単ですので、一読頂けたら幸いです。

f:id:o21o21:20180803144307p:plain

まず、Code3兄弟

AWS界隈では、よくCode三兄弟なんて呼ばれているサービスがあります。

そのサービスとは、

  • CodeCommit
  • CodeDeploy
  • CodePipeline

この3つのことです。

DynamoDBやS3は知ってるけど、この3つは使ったことないという方も多数いるのではないでしょうか。 自分の会社でもし使用しているのであれば、是非構築した人にどうしてこの構成にしたのかなど聞いてみると面白いかもしれません! もしかすると、苦悩など聞けるかもしれません。。。w

また、上記のサービスと合わせて、Jenkinsというツールを使用されている方も多いのでは? けっこう記事も多くありますしね。

ただ、私としてはAWS内のサービスでまかなえたらと思います。 理由は、ただ面倒くさいから....w

この3兄弟についてはざっくりこんなかんじです。

CodeCommitは、AWS版Git。 CodeDeployは、EC2へのファイル配置とスクリプト実行を自動で、プラスで環境毎で管理しやすいよ。 CodePipelineは、アプリのビルドやテストのフローを管理・自動化してくれるよー。

みたいなかんじです。

あれ?タイトルのCodeBuildは?

こちらは2016年のre:Inventにて、発表されたサービスのようです。 もう2年くらい経っているので、今ではCode4兄弟になっているようですww

一旦、Codeなんちゃらと言われるサービスは、リリースまでの手助けをしてくれるものとしてざっくり覚えておけばよさそうですね。

(※ コード書くとかほんとに全てAWSで収めたい場合、CodeStarと呼ばれるサービスもあります。参考 )

CodeBuildもざっくり言うと、フルマネージド型ビルドサービス。(自分でビルドサーバーを管理しなくていい)

うんうん。まあ、一旦公式のドキュメントを以下に。

そして今回は、タイトルにもある通り、

Github + CodePipeline + CodeBuild + Elastic Beanstalk

でかるく流れを追いつつ構成を考えてみます。

前置き

いきなり各サービスを作成していってもいいのですが、面倒なことになりかねないので一旦前知識として!

開発環境について

主にWebアプリだと仮定して、開発だとローカルに仮想環境を構築されている方多いと思います。 CentOSだとかDockerとかですかね? ここではDockerということにします。

ローカルでバグ修正なり、開発を終えると大体先輩やらのコードレビューが入ります。

何でコードを管理しているかによりますが、ここではGithubにします。 大体ブランチを切ってプルリク出してmasterにマージします。

まず、ここで把握しておきたいのは、CodePipelineをキックするのはどのブランチになるかということです。

ここでもう、どんなかんじはフローになるのかを見てみます。

いったん構成図をみてみる

f:id:o21o21:20180803113621p:plain

これさえ見たらもうわかるかと思います。 CodePipelineが管理する管轄は、この3つのサービスです。 (上の構成図では、Githubは点線の外ですが基本的には、CodePipelineを作成する際に、認証接続が必要になります。)

ここでもう一度言います! あくまで、シンプルな構成図です! ビルドしてからのテストや、承認アクション、Slackに通知したりなどなどいくらでもできるのですが、まずは基本ということで、シンプルでいきますw このシンプルな構成ができれば、あとのカスタマイズは楽になるかと思います。

Docker Imageを確認してから....

さて元に戻って...

開発でDockerを使用しているならば、必ずDockerfileなるものを管理していると思います。 そのDockerfileを元にdocker buildなどなどしているはずです。

ローカルでdocker imagesで今どんなイメージ使用しているか確認します。 何故確認するかというと、実はもう1つAWSのサービスを使うためです。

CodeBuildで必要になってきます。 現在のCodeBuildでは、ビルドをする環境イメージがUbuntuしか選択できないのです。 なので、せっかくDockerで開発しているならばそのままDockerイメージを選択してそのままテストできた方がいいですよね。

なので、Dockerfileの内容をきちんと確認しておきます。 そしたら新しく使用するサービスは、ECR (Elastic Container Registry)というサービスです。 簡単に、AWSのDockerレジストリサービスのことです。

Docker Imageを管理しておくことができます。

ということで、まずDocker ImageをECRで管理します。

ECRへプッシュ

特に難しいことはなく、コマンドを打てばECRにイメージが登録できます。

基本的にAWSコンソールの方で先にリポジトリを作成します。 作成が完了すると、コマンドの例が出てくるのでそれを順を追って叩いていけば問題ないです。

1つ、aws cliを使用できるように自分設定しなければなりません!

最終的に以下のようなコマンドを打ち終わると登録完了できたと思います。

$ docker push 506445657567.dkr.ecr.ap-northeast-1.amazonaws.com/docker-image-name:version

ちゃんとヴァージョンを指定してあげましょう! もし間違えても完全新規なら特に影響する範囲がないので、間違えたら削除すればいいや程度で叩いてみても大丈夫でしょう。

ECRを加えることで、以下のような構成図になります。

f:id:o21o21:20180803120908p:plain

ようやく、流れを確認 !w

まず、今回の記事の場合だと以下の手順で構成し始めるといいかもしれません。

  1. 開発環境を確認する (Dockerまわり、Githubブランチまわりなど)
  2. ECRにDocker Imageを管理させる
  3. CodeBuildでプロジェクトを作成する
  4. ElasticBeanstalkでアプリと環境(最低1つ)を作成する
  5. CodePipelineでそれぞれのサービスを紐づけしていく
  6. それぞれ動作するか確認〜

どんな環境でどんなサービスなのかによっても左右されますが、ちょっと詰まりやすいのは、 CodeBuildが正常にいくかなのかな〜と思います。

あと、ElasticBeanstalk(以下EB)で先に現状のプロジェクトをEBの各言語のルールに沿ってそのままzip化して、 そのまま手動で挙げてみて、とりあえず正常に動作するか確認してもいいかもしれません。

そしたら、簡単にはなりますがいくつかサービスの詳細を書いていこーかと思います。

CodeBuildについて

記事の前半にある前知識で、Githubの指定したブランチに対して、CodePipelineがキックされて成功なら、次にCodeBuildに流れていくことが大体わかったかと思います。

CodeBuildのプロジェクトを作成するにあたって重要な項目は以下。

  • ソース:ビルドの対象 > ソースプロバイダ
  • 環境: ビルド方法 > カスタムイメージタイプ(Docker)
  • buildspec 名
  • サービスロール
  • VPC (環境によりけり)
  • 詳細設定全般(特に環境変数かな?)

大体想像できるかと思いますが、buildspecが見慣れないかんじがします。 これは、ビルドを仕様をYAML形式で指定できるものになります。

AWS CodeBuild のビルド仕様に関するリファレンス - AWS CodeBuild

主に以下のようなかんじで記述していきます。 術全ての項目が必須というわけではないので、必要なところだけ記入してプロジェクトのプロジェクト直下に配置します。

version: 0.2

env:
    variables:
        key: "value" #環境変数指定
    parameter-strore:
        key: "value" # Systems Managerから取得し、値は暗号化できる

phases:
    install:  # パッケージインストール
        commands:
             - command
    pre_build: # ビルド前処理
        commands:
             - command
    build:  # ビルドテスト
        commands:
             - command
    post_build:  # アーカイブ化(zipなど), ECRへのプッシュ
        commands:
             - command
artifacts:
    files:  # S3へアップするファイルを指定
        - location

node.jsならnpm installとか、PHPならcomposer.phar installをここに書いておけば大丈夫です。

と、同時に、前にDockerfileを確認と言っていましたが、CodeBuildではECRに登録したDockerイメージを使用します。 ちゃんとbuildspec.ymlと合わせて、CodeBuildでもDockerイメージが使用できるように調整しましょう! テストコードもここでコマンドを叩いてテストできるので、1度はとりあえずビルドかけてみるがいいでしょう。

CodeBuildのログ

ログですが、ビルドするとAWSコンソールでビルド履歴が確認できます。 そこの各項目の詳細を開くと、出力:ログからCloudWatchに飛ぶので確認できます。 どこのコマンドでコケているんだ〜とかチェックできます。

Elastic Beanstalk

EBには、大きくアプリとその環境という枠組みを作成することになります。 例えば、1つアプリ作成して、環境を複数作成し、Blue/Greenデプロイ構成を作成することができます。

環境をステージングと本番に分けてもいいですね。

EBの場合はけっこう設定する項目があります。

  • 環境枠の選択 (Web環境 or Worker環境)
  • 基本設定 > プラットフォーム
  • 基本設定 > アプリケーションコード
  • さらにオプションを設定 > ソフトウェア / インスタンス / 容量 / ロードバランサー / ローリング更新とデプロイ / セキュリティ / モニタリング / 通知 / ネットワーク / データベース / タグ

ほんとは全て気にしないといけないのですが、特に気にしたのが、ネットワークロードバランサー(ALB)ですかね〜。

EBだとデフォルトで、Classic Load Balancer (CLB)になってしまいます。なので、ALBに変更します。 CLBではWAFを使用できませんが、ALBは使用できたりします。 ネットワークは、あれです、会社のルール的なやつです...w

上記を設定し、プラットフォームを使用したい言語に合わせてzip化してとりあえず手動であげれば動きます。 ※ 設定内容は環境作成後、変更は可能ですがインスタンスが新規で作成されたりするので、できれば最初の段階で設定値は運用するにあたっての設定にしといた方が後々楽かと思います。 インスタンスのセキュリティグループの追加でも環境の再構築が始まりました。

とまあ、とりあえずこんなもんかなというEBが作成できてしまえば、設定の保存ができるのでいくらでも環境の作成&削除が可能です。 あんまりこだわっても仕方ないのでね。。w 開発する段階で徐々に調整していくのがいいかもしれません。

.ebextensions

EBには、.ebextensionsというその環境のAWSリソースをカスタマイズできる機能(設定ファイル)を持つことができます。 プロジェクトに.ebextensionsというフォルダを作成し、その中にxxxx.configというファイルをYAMLJSON形式で書いて、置いておけばいいです。 .configという拡張子で認識するので、ファイル名は任意で複数置くこともできます。 また、JSONで記述可能ですが、公式ではYAML形式を推奨しているようです。

CodeBuildでも設定ファイルあるのに、EBでもか.... と思ってしました。

例としてこんなかんじかけます。(パッケージ入れたり環境変数設定したり立ち上げ時のサーバーにファイル生成したり...)

packages:
    yum:
         パッケージ名[]

commands:
    01-xxxxx-command:
        command: なんかコマンド
    02-xxxxx-command:
        command: なんかコマンド
        test: なんかコマンド

files:
    "/path/to/you/want/create/file.sh" :
        mode: ""
        owner: root
        group: root
        content: |
            ファイルの内容

EBのTips

1つ私が詰まって1日費やした箇所があります。 EBの仕組みとして、覚えておかないといけなかったっぽい。。

.ebextensionsをもちろん使用していたのですが、ログを確認するとどうもその記述が悪くあるコマンドでこけていた。。。 エラー内容もよくみるものだし、内容は把握していたのに何故かうまくいかない。。

結論としては、.ebextensionsで記述したコマンドが実行される場所に鍵がありました。

EBがの.ebextensionsが実行される場所は、/var/app/ondeckというディレクトリがワーキングディレクトリになっています。 コマンドが正常に全て完了すると、ondeckディレクトリはなくなって、currentディレクトリにプロジェクトがコピーされ、デプロイの完了になります。

おーーなるほどーーと思い、コマンドを修正したら見事EBのヘルスがOkになりました。。w

ここまで

大体山場を抑えたら、あとはCodePipelineで各サービスを紐づけしていくのみです。 特に難しい操作はありません。ポチポチしていけば、大丈夫です。

Githubの指定したブランチにpushされた時に、CodePipelineが発火します。 AWSのコンソールの進捗状況をみていると、今どこで処理されているのかが確認できます。

まとめ

今回はシンプルな自動化のフローを考えました。 この他、承認フローとして、Lambdaをかませて、Slackのあるチャンネルに通知 > Slack上で任意のユーザーの承認を得る > ステージングに変更を適用などできます。またビルド後のテストのフローもビルド先を増やせば複数できるのかな?

ほんとに色んな方法があるので、いろいろ試してみたいものです! ただ、他サービスを入れてしまうと運用コストが高くなってしまうので、できるだけシンプルに簡単にを意識したいと改めて思いました。

以上

【AWS】Amazon Linux 2だよ〜

今回は少し内容が薄めです...

既にITに精通している方であればご存知だと思います。

去年の冬にAmazonが公式から発表されました。

Amazon Linux 2がきましたーーー!!!

Amazon Linux 2 のご紹介

これが問題とあんる会社は多いのではないでしょうか? 問題というか、ヴァージョンの移行にコミットしなければならず、現状行っている作業が中断なんてことも...??

こういうときにエンジニア不足している会社だと大変ですね。。。

1つ例を挙げてみます。

Elastic Beanstalk

Elastic Beanstalkを使用している方は多いかと思います。 また、開発ではDockerを使用していて、例えばこんな風にDockerfileに記述している。

FROM amazonlinux:latest
・
・
・
・

いつも通りにローカル環境を整えていて、

「あれ? なんか動かないぞ。。。」

なんてこと、あると思います!

これは、 latest と記述しているので、最新のAmazon Linuxヴァージョンを取得しにいっているので、

要はAmazon Linux 2になっているのですね!

FROM amazonlinux:1

こんなかんじでヴァージョンの指定しないと、前と同じ環境は作成されません。

DockerのコンテナイメージもAmazon Linux2を提供しています。

いい面もあります。

Dockerを使用しているなら、Amazon Linux2を試すこともできますね。 言語のバージョンも合わせてアップデートするなら今のうちかもしれません。。。

また、こちらの記事にAmazon Linuxとの違いがうまくまとまっている記事があります。

Amazon Linux 2 の登場と、Amazon Linux との違い、移行方法などをQ&Aから抜粋したメモ

Amazon Linux2とAmazon Linuxの違いについて(メモ)

Amazon Linux自体はこちらのヴァージョンを最後としています。

利用可能になりました – Amazon Linux AMI 2017.09 | Amazon Web Services ブログ

今のヴァージョンの最終的なサポート期間は、 セキュリティアップデートはAmazon Linux 2の最終LTSビルドが発表されてから2年間提供されます。

あっという間というかんじですね..

ひとまず、何か新規プロジェクトを構成するならAmazon Linux2ですね!!

以上.

【npm】configパッケージについて

よくnode.jsで開発しているとconfigパッケージを使用して、 環境別の設定値を切り分けることが多いと思います。

DBの接続情報であったり、APIとかも環境によってわけて使う時などに便利です。

www.npmjs.com

使い方も簡単ですよね!

$ npm install config

あとは、/config というディレクトリを作成して、 環境名のファイルを作成するだけで、コード内で config.get('xxxx.yyyy') みたいに書くだけで値を参照できます。

nodeのプロジェクトをやっていてこのconfigは便利なのですが、 よくdefault.jsonとdevelopment.jsonはどちらが優先されるの? とか、上書きされるの?とか忘れてしまいます。。。

なので、今回はちゃんと確認してみた!という記事になります。

node_moduleの中身を確認!

ということで、configの中身を確認してみました。 (すぐできるのに今まで怠っていました。。。)

version : "^1.30.0"

node_modules/config/lib/config.js

ここに記載されていました。

Application configurations are stored in files within the config directory of your application. The default configuration file is loaded, followed by files specific to the deployment type (development, testing, staging, production, etc.).

訳すと、

アプリケーション構成は、アプリケーションのconfigディレクトリ内のファイルに格納される。デフォルト設定ファイルが読み込まれ、続いて 特定の種類にファイル(development, testing, staging, productionなど)に固有のファイルによって異なる。

なるほど、ってことは、 「さきにdefault.jsonが読み込まれる」ってことだ。

なので、default.json → development.json みたいな順番で、 仮に同じ値(ネスト構成が同じ)があれば、上書きになるってことだ。

あー、すっきりしましたw

以上

【VR】仮想店舗(Virtual Store)!? Oculus Goで考える #1

これまで過去の記事で、Oculus Goの開発環境(Unity)などを整えていきました。 Oculusのアセットをインポートして、コントローラーを追加し移動できるようにするところまで進めたかと思います。

今回の記事は考察よりの内容です!

o21o21.hatenablog.jp

以前から個人的に色んな方のVRのコンテンツを少々拝見させてもらっていました。

Oculus Goでまず試したい!おすすめアプリ・ゲーム特選 | Mogura VR - 国内外のVR/AR/MR最新情報

すごいですよね~! VRChatとかVRの中で映画をみんなで観る鑑賞会とかが開かれていたり!

私は参加したことない(参加するのが怖いのでお誘いお待ちしておりますw)ので気になることがあるのですが、 充電とかフレームレートとか...

まあそんなことを思っていても、開発していかないと知見がたまらないので、

仮想店舗 (Virtual Store)」を開発してみようと思います!

ECサイトあるからええやん!というご意見はさておき、 なんとなくわくわくするので個人的に開発してみようかな~。

Unity Asset Store

私は日頃Unity使わないので、初めてちゃんとあさってみたのですが、すごい沢山アセットがあるんだな~、 と今更ながら思いました。

assetstore.unity.com

一番驚いたのが、こちら! WillHuangさんという方が作成したもの。

assetstore.unity.com

もう、すっごい綺麗ですね。。!! 購入はしていませんが、このアセットはOculusに対応しているとのこと。 (グラボを積んでいるPCでないといけないみたいです!)

$50か~、このクオリティなら十分に納得ができる。

が、ちょっと高いな~。

と、思っていたところ値段もクオリティもお手頃なアセットを発見した。

assetstore.unity.com

これも十分綺麗ですね! $16くらい。これなら購入してもよさそうだと思って購入。

ちょっと購入前に気になったのが、棚に並んでいる商品。

サンプル動画を観る限り、けっこう色んな種類の商品オブジェクトがあるみたい。 VRでこの店舗に訪れて商品に近づくと、商品にオブジェクトに文字が書いてあるが、 それがどうやって映るんだろう、なんて考えました。

購入はクレカで即購入できちゃいます!

Unityにインポート

f:id:o21o21:20180622110916p:plain

「おお!一気にそれらしい!」

是非店内を歩きたいということで、ビルド!!

f:id:o21o21:20180622123815p:plain

「やったー!!歩けた!!」

「あれ?でも....」

実機で見るとわかるのですが、オブジェクトがけっこうかくついている。。。 フレームレートの問題なのか?

Oculus Goのリフレッシュレートは、60Hz72Hzでコンテンツにより変化するらしい。 なるほどー。

原因がまだわからないけど、おそらくそこらへんに問題がありそうです。 もしわかる方いあたら是非連絡お待ちしております。!

店舗が暗い問題

最初アセットをインポートしてビルドしたとき、店舗が暗かったのです。 これはどうもLightingの問題だったようです。

メニューWindow > Lighting > Settings

Realtime LightingのAuto Generateチェックボックス外して

Generate Lightingに設定&押下でOK!

まとめ

次は、商品が取れて、商品単体でポップアップみたいに確認できるようにしようかな! そのあと、サーバーとの通信方法を考えよう!

今回は考察ということで、仮想店舗について考えました。

現状、ECサイトのみで店舗がない会社とか、VRで仮想店舗なんかあると面白そうだよね! 求められるというより、ワクワクを追っていきます!!

以上

過去記事>>

o21o21.hatenablog.jp

o21o21.hatenablog.jp

【Go】go-ethereumを使用して簡易ブロックエクスプローラーを構築!

先日、etherscanのようなブロックチェーンに記録された取引情報などを確認できるようなシステムをローカルに構築する勉強会に参加してきました。

etherscan自体は、こちらにあります。

Ethereum (ETH) BlockChain Explorer

俗にエクスプローラと呼ばれる仮想通貨の領域で使用されるシステムです。

私は今のところいくつか仮想通貨を所有していますが、ほぼ放置しています...w たしか、2017年、年末くらいがすごい盛り上がっていましたよね〜 ブロックチェーンという技術に興味はありますが、仮想通貨自体まだそんなに本腰を入れて模索していません。

ですが、ブロックチェーンの技術的な面であったり、それに付随してくるシステムには関心があるといったところです。

まだまだ、国内では仮想通貨に関する本はありますが、ブロックチェーン技術についてはなかなか(最新の書籍は)ないですよね。

今回は、etherscanシステムの簡易バージョン、 基、ローカル環境で動作するブロックエクスプローラを構築させます。

では準備から取り掛かっていきましょう。

環境 : macOS

準備

まず、構築で絶対必要なのが、GoGeth (, Git)です。

Golangのインストールやプロジェクト構成については、過去記事があるので そちらを参考にしてみて下さい!

o21o21.hatenablog.jp

そして、Gethなのですが、Go Ethereumの略でEthereumが提供しているクライアントソフトです。

golangで開発されていて、Ethereumをコマンドラインで操作する目的のソフトというかんじ。

github.com

このGethをインストールするのは簡単です。

$ brew tap ethereum/ethereum
$ brew install ethereum

インストールが完了したら、確認してみます。(helpオプション)

$ geth --h


NAME:
   geth - the go-ethereum command line interface

   Copyright 2013-2018 The go-ethereum Authors

USAGE:
   geth [options] command [command options] [arguments...]
   
VERSION:
   1.8.10-stable
   
COMMANDS:
   account           Manage accounts
   attach            Start an interactive JavaScript environment (connect to node)
   bug               opens a window to report a bug on the geth repo
・
・
・
・

こんなかんじでヘルプ内容がどっしり出力されたらOKです。

本来であれば既にGethがインストールできているので、色々コマンドを実行できるのですが、 今回はさらに環境を整えます。

ちなみに以下のような手順書もあるので、ここからは合わせて参考にするといいかもしれません。

まずは Ethereum に触れてみる · Ethereum入門

Gethをインストールする · Ethereum入門

ブロックエクスプローラーを構築

さて、ここからは以下のリポジトリを使用します。

GitHub - curvegrid/toy-block-explorer: A blockchain explorer written in Go to learn about building server-side applications that work with the Ethereum blockchain.

このGoコードで、自分のブラウザでEthereumの情報が確認できるようにします。

基本的にREADMEを実行していけば大丈夫なのですが、 順番を間違えたりして詰まるとモチベーションが落ちるので(www) ここでは上から順におってみていきます。

1. リポジトリをおとしてくる

まず、toy-block-explorerリポジトリをおとしてきます。 おとしてくるくるときは、zipでもgit cloneでも構いませんが、 step-finalブランチを指定して下さい。

まず、任意のディレクトリに移動してクローンします。

$ git clone https://github.com/curvegrid/toy-block-explorer.git

クローンが完了すると、toy-block-explorerというディレクトリが確認できるかと思いますので、移動し以下を実行します。

$ cd toy-block-explorer
$ git submodule init
$ git submodule update --recursive

.gitmodulesファイルが存在するかと思います。 こちらのファイルを元に、git submoduleをしましたので、 toy-block-explorer/geth/配下にeasy-geth-dev-modeというリポジトリを生成しました。

easy-geth-dev-mode自体のリポジトリは、こちらにあります。

今は無事にコマンドが実行できたらOKです。

現状はこんな構成になっているかと思います。

toy-block-explorer/
├── LICENSE
├── README.md
├── build.sh
├── erc20.go
├── geth
│   ├── easy-geth-dev-mode
│   └── sample-chaindata
├── main.go
├── screenshot.png
├── templates
│   ├── footer.tmpl
│   └── header.tmpl
├── toy-block-explorer
└── www
    ├── css
    ├── images
    ├── index.html
    └── js

2. サンプルデータを作成

仮想通貨をある程度知り尽くしていたらいいのですが、いきなり本番のデータを扱うのは怖すぎるので(この記事では本番のデータ操作については割愛)、 ローカルで動作させるためのデータを作成します。

プロジェクトルートで以下を実行します。

$ cp -R geth/sample-chaindata geth/easy-geth-dev-mode/chaindata

3. Gethを起動させる

先程、git submoduleしてきたeasy-geth-dev-modeディレクトリに移動します。

easy-geth-dev-mode/
├── README.md
├── attach43.sh
├── chaindata
│   ├── geth
│   ├── history
│   ├── keystore
│   ├── log
│   └── sample-chaindata
├── js
│   ├── base-geth-snippets.js
│   ├── start-rpc.js
│   └── useful-geth-snippets.js
├── launch43.sh
├── net43
│   ├── README.md
│   ├── attach43.sh
│   ├── chaindata
│   ├── js
│   ├── launch43.sh
│   └── stop43.sh
└── stop43.sh

そしてlaunch43.sh を実行します。

$ cd geth/easy-geth-dev-mode
$ ./launch43.sh --ipcdisable --startrpc

launch43.shでgethコマンドを実行しています。 データが格納されているディレクトリを指定し、dev modeで、データをjsに渡すようにオプションが付与されています。

起動できると以下のようになるかと思います。

$ ./launch43.sh --ipcdisable --startrpc


== Disabling IPC
== Enabling RPC
== Attaching via RPC
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.10-stable/darwin-amd64/go1.10.2
coinbase: 0x5e4d047cd9173fd13c220a0bf756c7e25c00f587
at block: 3 (Sat, 09 Jun 2018 15:41:28 JST)
 datadir: /Users/user-name/path/to/toy-block-explorer/geth/easy-geth-dev-mode/chaindata
 modules: admin:1.0 debug:1.0 eth:1.0 net:1.0 personal:1.0 rpc:1.0 web3:1.0

> 
> 
> 

これでGethが起動できました。 このGethを停止する場合は、./stop43.shを実行しましょう。

一旦、ブラウザで確認できるまで起動させたままで構いません。

また、何度か試していると、

geth net43 testnet appears to be running or zombie pid file remains at './chaindata/log/geth.pid'
Try running 'stop43.sh' to make it exit.

このようなメッセージが出力されるかと思います。 同様にstop43.shを実行してから再度起動を試すといいかもしれません。

3-1. トラブルシューティング

  • Gethが実行できない

けっこう起動できない方がいたようです。 まずgethが起動しているのか、プロセスから調べてみます。

$ ps -ef | grep geth

数件gethでヒットしていたら起動はできているかもしれません。

  • それでも起動がうまくいかない
$ geth --dev --datadir ./chaindata --rpc console

rpc : gethのRPCサーバとしてのAPIを有効化

4.

ここまでGethを起動できたので、すでにgethのコンソールからコマンドを実行できる状態ではあります。 ですが、まだブラウザでは何も確認できないので、portを開けて確認できるようにしましょう。

コマンドライン(ターミナル)の新しいウィンドウなりタブを開いて、 toy-block-explorerのプロジェクトルートに移動します。 ここにbuild.shというファイルがあるかと思います。 こちらを実行します。

$ ./build.sh

build.shの中では、go-ethereumgo getで取得し、 アプリtoy-block-explorerをbuildさせています。

無事ビルドできたら、toy-block-explorerを実行します。

$ ./toy-block-explorer

2018/06/09 16:04:10 Connecting to Ethereum node at http://localhost:8545
2018/06/09 16:04:10 Web server started on :8080
2018/06/09 16:04:16 Request from [::1]:64800: /
2018/06/09 16:04:17 Request from [::1]:64800: /

起動させ、ブラウザを開いて確認します。

http://localhost:8080/

確認できましたか?

f:id:o21o21:20180620185220p:plain

これでローカル環境に簡易版ブロックエクスプローラーを構築できました!

あとは、gethのコマンドで色々とコマンドを試すことができます。

main.goの内部が面白い

toy-block-explorerのプロジェクトルートにあるmain.goを見てみましょう。

コード上部にGetBlockchainInfoがあるかと思います。 他にも、データをweb3(Ethereum JavaScript API)を使用して受け渡していたり...

たくさん勉強になることが多そうです。 シェルが用意されているので、ほとんど自分で考えることがありませんが、 よーく構造を理解していくと面白い分野なので(特に今回扱ったリポジトリなんかは) 一度ローカルに落としてみて、時間をかけて理解してみてもいいかもしれませんね!

以上.

【VR】Oculus Go Unityでコントローラーを追加し移動してみる

さて、前回は、Unityのプロジェクトを作成しました。

o21o21.hatenablog.jp

続いてOculus Goに付属しているコントローラー(Replacement Controller)をUnityへimportしてみます。 そして、一人称で動けるようにします。

f:id:o21o21:20180612161059p:plain

アセットのインポート

アセットのインポートを最小限に済ませたい方は、UnityのAsset Storeから直接アセットをインポートしましょう。 まとめてUtilitiesをインポートしたい方は、こちらからダウンロード。 ダウンロードしたら、UnityのメニューAssets > Import Package > Custom *Package ... からダウンロードして解凍したファイルをインポートします。

以下、Asset Storeからの手順。 UnityのAsset StoreOculus Integrationというアセットがあります。

  1. UnityのAsset Storeにアクセス
  2. 検索フォームに"Oculus Integration"とタイプ f:id:o21o21:20180611222450p:plain
  3. "DOWNLOAD"を押下(無料です!) f:id:o21o21:20180611222723p:plain
  4. ダウンロードが完了したら、"Import"を押下
  5. ポップアップウィンドウが表示され、全てにチェックボックスが入っていることを確認し、"Import"。 f:id:o21o21:20180611223038p:plain
  6. versionの確認(Yes or No)
  7. Unityのrestartの確認(→ Yes)
  8. 再起動後、Asettsフォルダに存在を確認 f:id:o21o21:20180611223849p:plain

これでアセットのインポートを完了です!

OVRCameraRigを追加

インポートしてきたOculusフォルダを確認してみます。

Assets > Oculus > VR > Prefabs > OVRCameraRig

OVRCameraRigを、Hierarchyに追加します。 デフォルトのプロジェクトでは、Main Cameraがあると思います。 こちらは不要になるので、削除するか、Inspectorの方でチェックを外します。

f:id:o21o21:20180612121337p:plain

これでSceneからMain Cameraが消えたと思います。

OVRCameraRigの位置ですが、任意で大丈夫ですが、 私はUnityの三人称キャラ、Ethanをシーンに追加して目線を合わせてみました。 ※Ethanのインポートは、メニューAsetts > Import Package > Characters、全てをインポートすると、 Assets/Standard Assets/Characters/ThirdPersonCharacter/Prefabs/配下にEthanがいます。

Ethanの身長は、約168cmとされているようですが、ちゃんと調べるには自分で立方体を設置して測ってみるとよさそうですw

f:id:o21o21:20180612123347p:plain

コントローラーの設定

いよいよコントローラーの設定をしていきます。

1. コントローラーを追加

Oculus/VR/Prefabs/TrackedRemote.prefab

こちらをOVRCameraRigのLeftHandAnchorRightHandAnchorドラッグ&ドロップします。

f:id:o21o21:20180612123750p:plain

そうすると、以下のようにOculus Goのコントローラーが確認できるかと思います。

/RightHandAnchor/TrackedRemote/OculusGoControllerModel
/LeftHandAnchor/TrackedRemote/OculusGoControllerModel

f:id:o21o21:20180612124256p:plain

2. ポインタを設定する

何か操作をするときにどこをコントローラーが指しているか知る必要があります。

まず、Hierarchyで空のGameObjectを作成します。 Hierarchyのところで、右クリ > Create Emptyで作成します。 そして、名前を付けます(例: LaserPointer)

このオブジェクトにコードを追加したいので、任意の場所で Create > C# ScriptC#のファイルを作成します。 ファイル名は自分がわかればいいでしょう!

エディタを開いて、以下のコードを貼り付けます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LaserPointer : MonoBehaviour {

    // 右手
    [SerializeField]
    private Transform _RightHandAnchor;

    // 左手
    [SerializeField]
    private Transform _LeftHandAnchor;

    // 目の中心
    [SerializeField]
    private Transform _CenterEyeAnchor;

    // 距離
    [SerializeField]
    private float _MaxDistance = 100.0f;

    // LineRenderer
    [SerializeField]
    private LineRenderer _LaserPointerRenderer;

    // コントローラー
    private Transform Pointer
    {
        get
        {
            // 現在アクティブなコントローラーを取得
            var controller = OVRInput.GetActiveController();
            if (controller == OVRInput.Controller.RTrackedRemote)
            {
                return _RightHandAnchor;
            }
            else if (controller == OVRInput.Controller.LTrackedRemote)
            {
                return _LeftHandAnchor;
            }
            // どちらも取れなければ目の間からビームが出る
            return _CenterEyeAnchor;
        }
    }

    void Update()
    {
        // コントローラーを取得
        var pointer = Pointer;

        // コントローラーがない or LineRendererがなければ何もしない
        if (pointer == null || _LaserPointerRenderer == null)
        {
            return;
        }
        
        // コントローラー位置からRayを飛ばす
        Ray pointerRay = new Ray(pointer.position, pointer.forward);

        // レーザーの起点
        _LaserPointerRenderer.SetPosition(0, pointerRay.origin);

        RaycastHit hitInfo;
        if (Physics.Raycast(pointerRay, out hitInfo, _MaxDistance))
        {
            // Rayがヒットしたらそこまで
            _LaserPointerRenderer.SetPosition(1, hitInfo.point);
        }
        else
        {
            // Rayがヒットしなかったら向いている方向にMaxDistance伸ばす
            _LaserPointerRenderer.SetPosition(1, pointerRay.origin + pointerRay.direction * _MaxDistance);
        }
    }
}

なるほどー。こんな関数もあるんだー。勉強になります。

シーンにあるすべてのコライダーに対して、 origin の位置から direction の方向に maxDistance の距離だけレイを投じます。 Physics.Raycast - Unity スクリプトリファレンス

保存したら、さっき作成したLaserPointerゲームオブジェクトに配置させます。 ドラッグ&ドロップでも、InspectorのAdd Componentからでも追加できます。

f:id:o21o21:20180612130816p:plain

スクリプト中の変数の値をHierarchyのオブジェクト、

  • RightHandAnchor
  • LeftHandAnchor
  • CenterEyeAnchor

をそれぞれ設定します。

こちらもドラッグ&ドロップか、変数名の値の横の丸ぽちでも設定可能です。

f:id:o21o21:20180612131259p:plain

3. レーダーを設定する

Line Rendererというものを設定します。 LaserPointerゲームオブジェクトのAdd Componentを押下。 Searchフォームで、lineと入力すると、Line Rendererが選択できるかと思います。

このLine Rendererに設定をします。 沢山の項目がありますが、今は最小限にします。

  • Cast Shadows: Off
  • Materials>Element 0: Sprites-Default (丸ぽち押下し検索フォームに"Sprites"と入力)
  • Width: 任意 (0.003 ~ くらいからがいいかな?)
  • Color: 任意

値を設定したら、変数に設定します。

f:id:o21o21:20180612132652p:plain

これで完了です。

4. 実機で確認

ここまでできたら1度実機で確認してみます。

保存して、ビルドしましょう。

f:id:o21o21:20180612134105p:plain

おう!レーダー出てますね! これでまたコードを書いて、オブジェクトに対しての操作も考えられそうです!

前々回前回の記事を観覧して頂いているかたは、 PCへUSB接続し、クロームからアプリ(Vysor)を起動。Oculusのデバイス接続が確認できたら"View"でOculus Goの画面がPCで確認できるはずです。

f:id:o21o21:20180612134216p:plain

いったん休憩

ここまでコントローラーを追加し設定しました。 あとは、コントローラーでオブジェクトに対して処理を行うコードを追加したり、 今回作成したLine Rendererでレーザーの細かい設定をしたりして、修正できます。

docs.unity3d.com

docs.unity3d.com

ここまでこちらを参考にさせて頂きました。ありがとうございます。

さらに公式でも関数についてなど記載があります。(英語)

OVRInput

次は、一人称視点で動くことをやっていきます。

Playerを設定し、動いてみる

Oculus Goに付属しているOculus Go Controllerタッチパッドで 直感的に一人称で動けるようにしてみます。

OVRCameraRigにComponentを追加

  1. HierarchyでOVRCameraRigを選択
  2. Add Componentを押下
  3. 以下を加える
  4. Capsule Collider
  5. Rigidbody
  6. C#スクリプトを追加(名前は任意)

f:id:o21o21:20180612160208p:plain

作成したスクリプトに以下を追記。 (私は少し自分流にしましたが、コードは先人の方のを使わせて頂きます。Unity初心者なので、こんな関数もあるのかと勉強になります!)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Og_Player : MonoBehaviour
{

    Rigidbody m_Rigidbody;

    // Use this for initialization
    void Start()
    {
        // 自分のRigidbodyを取ってくる
        m_Rigidbody = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        float x = 0.0f;
        float z = 0.0f;
        Vector2 touchPadPt = OVRInput.Get(OVRInput.Axis2D.PrimaryTouchpad);

        //右方向
        if (touchPadPt.x > 0.5 && -0.5 < touchPadPt.y && touchPadPt.y < 0.5)
        {
            // 十字キーで首を左右に回す
            transform.Rotate(new Vector3(0.0f, 0.5f, 0.0f)); 
            x += 0.5f;
        }
        //左方向
        if (touchPadPt.x < -0.5 && -0.5 < touchPadPt.y && touchPadPt.y < 0.5)
        {
            // 十字キーで首を左右に回す
            transform.Rotate(new Vector3(0.0f, -0.5f, 0.0f));
            x -= 0.5f;
        }
        //上方向
        if (touchPadPt.y > 0.5 && -0.5 < touchPadPt.x && touchPadPt.x < 0.5)
        {
            z += 5.0f;
        }
        //下方向
        if (touchPadPt.y < -0.5 && -0.5 < touchPadPt.x && touchPadPt.x < 0.5)
        {
            z -= 5.0f;
        }

        m_Rigidbody.velocity = z * transform.forward + x * transform.right;
    }

}

docs.unity3d.com

実機で確認

再度ビルドを実行して、実機で確認します。

f:id:o21o21:20180612161259p:plain

移動してEthanに会ってみました!

少し感度というか、自分が操作に慣れてないから移動に手間取りました。。 なんかタッチパッドが少し小さいかな?と個人的には思いました。

まとめ

今回はコントローラーを追加して、自分視点でフィールドで移動できるようにしました。 UnityのAsset Storeでは無料のフィールドもあるようなので、活用できそうですね!

【Go】GoでQuine(クワイン)を考えてみる

とある記事でクワイン(quine)というものを知った。

けっこうプログラミングの世界では、遊び?というかやっている内にハマっちゃうらしくて少し触れてみました。

Quineとは?

Quineとは、 自身のソースコードと同じ文字列を出力させるものです。

言語はなんでもいいらしい。 最初は、「なんか頑張ればできそうだな」とか 思ってたんですが、以外とムズいことに気づきました。

Pythonと迷ったのですが、先人の記事が少しあったので 今回はgolangでやってみようかと思います。

手始めに考えたこと

とりあえずfmt.Printしてみる!ww まあ、それはすぐムズいことに気づく。それにわしはgolangのすごい慣れ親しんではまだいない。

以下糞コード。

package main

import "fmt"

func main() {
    fmt.Print("
                    package main

                    import "fmt"

                    func main() {
                        
                    }
                   ")
}

でもなんかfmt.Printのとこでreplaceかなんかやればできんじゃね?みたいに思った。

とりあえず色々出力

package main

import (
    "fmt"
  _  "github.com/davecgh/go-spew/spew"
)

func main() {
    hoge := "This is the test"
    fmt.Print(hoge)
}

> This is the test

うんうん、そりゃそのままだなwww

ちょっとvar_dump的なのないのか?と思ったので、 spewというパッケージを使用してみた!

github.com

spew.Dump(hoge)でgo run main.goを実行。

> (string) (len=16) "This is the test"

ほう。 ならこれはどうだ。

hoge := "This is the test.
               That is the test.
              "

>  newline in character literal
> syntax error: unexpected is at end of statement
> newline in character literal

おっと、エラー出た。 そうかダブルクォーテーションじゃ駄目だな〜。 ああ、ヒアドキュメントか。

ダブルクォーテーションを ` で囲む。

> (string) (len=61) "This is the test.\n             That is the test.\n  

正規表現を使って...

きた。\n があるじゃん。

package main

import (
    "fmt"
  _  "github.com/davecgh/go-spew/spew"
)

func main() {
    hoge := `package main
             
             import ( 
                 "fmt"
              _   "github.com/davecgh/go-spew/spew"
             )

     func main() {
        hoge := 
        fmt.Print(hoge[:175] + "\u0060" + hoge + "\u0060" + hoge[:175])
     }
`
    fmt.Print(hoge[:175] + "\u0060" + hoge + "\u0060" + hoge[175:])
}

正規表現についてはググればOK!

Unicode正規化

string型の文字列を分解してただそのまま出力するだけでした。

変数hogeのスライス位置を確かめるのがしんどすぎました。ちゃとスペースとかタブとか考えて記述しないとですね…

なかなか面白かったです。 goの勉強にもなったし! ただ、興味のない言語でやりたいとは思わない...w

以上.