CentOS7にCartonを導入する

CentOS7 (7.3) にCartonをインストールするところでハマったのでメモを残す。

GitHub - perl-carton/carton: Bundler or pip freeze for Perl

cpanmコマンドまではインストール済み。Cartonをインストールするとcartonコマンドを使えるようになる。

CentOS7はvagrantのboxから起動したもの。

インストー

Digest::MD5が入っていないとインストール途中でコケたので、先に入れておく。

$ cpanm --sudo Digest::MD5
$ cpanm --sudo Carton

ハマった点

Cartonが依存しているPath::Tinyのテストがfailしてインストールに失敗していた。依存しているDigest::MD5が入ってなかったらしい。

t/00-report-prereqs.t ............. ok
t/basename.t ...................... ok
t/basic.t ......................... ok
t/children.t ...................... ok
t/chmod.t ......................... ok
Can't locate Digest/MD5.pm in @INC (@INC contains: t/lib /home/vagrant/.cpanm/work/1494991121.11260/Path-Tiny-0.104/blib/lib /home/vagrant/.cpanm/work/1494991121.11260/Path-Tiny-0.104/blib/arch /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/share/perl5/Digest.pm line 41.
# Tests were run but no plan was declared and done_testing() was not seen.
# Looks like your test exited with 2 just after 4.
t/digest.t ........................
Dubious, test returned 2 (wstat 512, 0x200)
All 4 subtests passed
t/exception.t ..................... ok
t/exports.t ....................... ok
t/filesystem.t .................... ok
t/input_output.t .................. ok
t/input_output_no_PU_UU.t ......... ok
t/input_output_no_UU.t ............ ok
t/locking.t ....................... ok
t/mkpath.t ........................ ok
t/mutable_tree_while_iterating.t .. ok
t/normalize.t ..................... ok
t/overloading.t ................... ok
t/parent.t ........................ ok
t/recurse.t ....................... ok
t/rel-abs.t ....................... ok
t/subsumes.t ...................... ok
t/symlinks.t ...................... ok
t/temp.t .......................... ok
t/visit.t ......................... ok
t/zz-atomic.t ..................... skipped: Test::MockRandom required for atomicity tests
t/zzz-spec.t ...................... ok

Test Summary Report
-------------------
t/digest.t                      (Wstat: 512 Tests: 4 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
Files=26, Tests=1696,  2 wallclock secs ( 0.16 usr  0.02 sys +  1.94 cusr  0.21 csys =  2.33 CPU)
Result: FAIL
Failed 1/26 test programs. 0/1696 subtests failed.
make: *** [test_dynamic] Error 255
-> FAIL Installing Path::Tiny failed. See /home/vagrant/.cpanm/work/1494991121.11260/build.log for details. Retry with --force to force install it.
-> FAIL Installing the dependencies failed: Module 'Path::Tiny' is not installed
-> FAIL Bailing out the installation for Carton-v1.0.28.
14 distributions installed

これでようやく依存管理できそう?

参考

CentOS7にcpanminusを導入する

CentOS7 (7.3) にcpanminusをインストールするところでハマったのでメモを残す。

GitHub - miyagawa/cpanminus: cpanminus - get, unpack, build and install modules from CPAN

cpanminusを導入するとcpanmコマンドを使えるようになる。

CentOS7はvagrantのboxから起動したもの。

インストー

perlコマンドが入ってないのでperlパッケージを事前にインストールする。

また、ビルド関連のツールも必要になるので、Development Toolsパッケージグループでまとめてインストールした。

$ sudo yum groupinstall "Development Tools"
$ sudo yum install perl perl-devel
$ curl -L https://cpanmin.us | perl - --sudo App::cpanminus

cpanmコマンドが有効になっていればok.

$ cpanm -V

ハマった点

  • perl-develパッケージが入っていないと、ExtUtils?が見つからなくて失敗した。
$ curl -L https://cpanmin.us | perl - --sudo App::cpanminus
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  298k  100  298k    0     0   145k      0  0:00:02  0:00:02 --:--:--  146k
--> Working on App::cpanminus
Fetching http://www.cpan.org/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.7043.tar.gz ... OK
==> Found dependencies: ExtUtils::MakeMaker
--> Working on ExtUtils::MakeMaker
Fetching http://www.cpan.org/authors/id/B/BI/BINGOS/ExtUtils-MakeMaker-7.24.tar.gz ... OK
Configuring ExtUtils-MakeMaker-7.24 ... OK
Can't locate ExtUtils/Manifest.pm in @INC (@INC contains: FatPacked::28003208=HASH(0x1ab4b88) /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at - line 132.

参考

Kerberos認証とPython

Windowsで認証にActiveDirectoryを使っている環境だと、シングルサインオン(SSO)などやるときにKerberos認証を使いたいこともあるだろうということで調べていました。

他の認証方法はNTLMがあるけど、非推奨のようなのでKerberosのほうを調べることに。

Kerberosのサーバー実装はOSSでもあるので、開発だとUbuntuだとkrb5-serverなどを使えばよいみたい。

Dockerで手軽に動かせるものを探したところ以下は良さそうだった。

GitHub - gcavalcante8808/docker-krb5-server: A Krb5Server Docker Image very easy and simple to use.

docker-krb5-serverを試す

READMEの通り。docker-composeで起動。

cd tmp
git clone https://github.com/gcavalcante8808/docker-krb5-server.git
cd docker-krb5-server
docker-compose up -d

adminのパスワードは環境変数で指定しない場合は、自動生成されてdockerのログに出力されている。

docker logs dockerkrb5server_kdc_1

クライアント側はkrb5-userをインストールしといて /etc/krb5.conf にREALMの設定をしておく。

[libdefaults]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
default_realm = EXAMPLE.COM

[realms]
EXAMPLE.COM = {
   kdc = localhost
   admin_server = localhost
}

kadminでプリンシパルを追加しとく。

$ kadmin admin/admin@EXAMPLE.com
Authenticating as principal admin/admin@EXAMPLE.COM with password.
Password for admin/admin@EXAMPLE.COM: adminのパスワードを入力
kadmin:  addprinc user01@EXAMPLE.COM
WARNING: no policy specified for user01@EXAMPLE.COM; defaulting to no policy
Enter password for principal "user01@EXAMPLE.COM":
Re-enter password for principal "user01@EXAMPLE.COM":
Principal "user01@EXAMPLE.COM" created.
kadmin:  q

PythonのKerberosモジュールを試す

AppleのcaldavのプロジェクトがPythonのKerberosモジュールを公開していて、PyPIに登録されている。

kerberos 1.2.5 : Python Package Index

Ubuntuだとlibkrb5-devが必要。

パスワードが正しいか試す最小限のコードであればこれぐらい。

import kerberos
user = "user01"
password = "p@ssw0rd"
kerberos.checkPassword(user, password, "localhost", "EXAMPLE.COM")

検証に失敗すると例外が発生する。

シングルサインオン対応のWebアプリ実装に使えそうなモジュール

前段にApacheを置いてもよいのであれば、ApacheモジュールでKerberos認証(mod_kerberosなど)を使って、X-Remote-Userヘッダをアプリケーション側で使う。

Python側でKerberos認証を処理するなら、前述のkerberosモジュールなどを使う。

ちょっと探してみたところ、WSGIミドルウェアだとwsgi-kerberosがよく出来てる感じだった。

GitHub - mkomitee/wsgi-kerberos: WSGI Kerberos Authentication Middleware

Djangoだとdjango-kerberosとdjango-auth-kerberosというのがあった。

django-auth-kerberosは認証バックエンド実装のみなので、シングルサインオンには使えない。

django-kerberosはViewの実装もあり、シングルサインオンにも対応しているが、ライセンスがAGPLなので利用する場合は気をつける必要がある。

wsgi-kerberosを使っとくのが無難かもしれない。

追記

  • SAMLのほうがよいのでは?という指摘頂いた。知識ないので調べてみる。
  • wsgi-kerberosはPython3だと動かない?かも。
  • kerberosのセットアップがシビアな感じがして、いろいろいじってると動かなくなって原因特定が大変な感じ。エラーメッセージだけではどうしようもない。

GoogleAppEngineとGoogleCloudPlatformの知識アップデート2017/05

3年ぐらいGoogleAppEngine (GAE)を使っていなかったのですが、GCPの無料枠も増えてるみたいだし久しぶりに触ってみようと思って調べていました。 以下、GAEとGCP周辺の知識のアップデートなメモ書き。

GoogleCloudPlatform (GCP)

cloud.google.com

  • Googleが各種コンピュータリソースを提供するサービスはGoogleCloudPlatformというくくりでまとめられた。
  • 管理コンソールから各種サービスを設定できる
    • 各種サービスを『プロジェクト』という単位で設定し、まとめるようになった
  • 各種サービスを利用する開発は、Cloud SDKを使う
    • gcloudコマンドが管理用のコマンド
    • 以前はGoogleAppEngineのSDKは個別で配布されいるものだったが、gcloudコマンドからコンポーネントをインストールする形になった
    • GAEへのデプロイもgcloudコマンドからできる
    • CloudStorageを操作するgsutilなどもインストールされる

CloudShell

https://cloud.google.com/shell/docs/?hl=jacloud.google.com

  • Webブラウザ上で、Linuxのシェルを利用できる。
    • GCPの管理コンソールからすぐに利用できる
  • 無料で使える
  • CloudSDKがインストールされているため、管理用端末として使うような感じ
  • 作成したファイルなどは残る(VMの停止/再開をしているっぽい?)

GoogleAppEngine

cloud.google.com

  • スタンダード環境とフレキシブル環境から選べる
    • スタンダード
      • 最初からあったもので、ミドルウェア等の追加インストールなどができない環境
      • スケーリングの設定のGUIは管理コンソールには無いようで、app.yamlから設定することになったみたい
      • 以前と同様であれば、インスタンスの再起動時にランタイム環境が更新される?
        • 以前はセキュリティアップデートが自動で反映されてるような感じ
          • たまにバグで動作がおかしくなることもありましたが…
    • フレキシブル
      • ランタイム環境をカスタマイズできるもの
        • 以前はManaged VMと呼ばれていたもの?
        • あらかじめ用意されたテンプレートもしくは、カスタムランタイムを使える
        • Dockerfileを使える
          • 要するにDocker環境で動くGAE
      • デプロイすると、Dockerイメージがビルドされ、ContainerRegistryに登録され、dockerdで起動される
        • スタンダードのほうがデプロイや起動は速い感じ
        • ContainerRegistryはCloudStorageを使うので、そちらで料金がかかる?
      • app.yamlで使える設定がスタンダードとは異なる
      • Dockerなので、インスタンスを再起動してもランタイム環境は更新されない?
        • 環境が保たれるのはよさそうだけど、セキュリティアップデートなどは再デプロイ(ビルド)が必要?
      • ContainerEngineへの移行ドキュメントがある
      • SSHでログインできる
      • スタンダードの機能がそのまま使えるわけではない
  • リージョン
    • us-central1、us-east1、europe-west1、asia-northeast1から選べる
      • asia-northeast1は東京。昔はUSしか無かったのでレイテンシかなり改善
  • Datastore
    • 昔はGAEに含まれるサービスだったが、独立して外部からもAPIを利用できるようになった
    • GAEからは以前と同様に使える
  • スケーリング
    • スタンダードとフレキシブルで設定項目に違いがある
      • スタンダード
        • 以前からあったもの
        • Automatic、Manual、Basicから選べる
        • Automaticだと、リクエストの処理待ち時間の上下幅を与えてスケーリングの目安としたり、不要ならインスタンスがシャットダウンされたりする
      • フレキシブル
        • 最低インスタンス数1
        • CPU使用率の目安を指定できる
        • アイドリング時に指定時間が経過したらシャットダウンするような設定にできる
    • スタンダードのほうが細かい単位でスケーリングするようなイメージ?
      • スタンダード環境はOSやミドルウェア層がチューニングされているのかも?

ツンパァードラグーン・VR

前置き

今月は案件が無くて時間があったので、VRについていろいろ調べて試していました。

来月も今のところ暇になりそうなので、案件のお話があれば是非お問い合わせください。

www.open-c.jp

以下、本題です。

きっかけ

HTC VIVEを試すために何かアプリケーションを作ってみよう、ということで、題材を考えていたところ、「そうだ、ツンパァードラグーンがあるじゃないか」という流れで作ってみることになりました。

jsdo.it jsdo.it

某クローズドなコミュニティで人気の作品です。オリジナルはJavaScriptワンライナーで作られていたものでした。

今回はコードは特に使わず、ゲーム内容だけ参考にしてVR対応ならどうすると面白いか?を考えつつUnityで作ってみることにしました。

作ったもの

github.com

ツンパァードラグーン・VRです(HTC VIVE専用)

f:id:nullpobug:20170427152006p:plain

移動範囲が制限されたエリア内に下着が降ってきてコントローラー(手)を伸ばしてキャッチするゲームです(ヒドい)

f:id:nullpobug:20170427152005p:plain

上ばっかり見ているとドラゴンに体当りされてダメージを受けます。ライフが0になるとゲームオーバーです。

f:id:nullpobug:20170427152003p:plain

f:id:nullpobug:20170427152004p:plain

VIVEのヘッドマウントディスプレイとコントローラーを使ってみるのにちょうどいい感じになりました。

オブジェクトを移動させるためにベクトルの計算が必要でしたが、ベクトルを扱うのなんて学生の時以来でかなり忘れてしまってました。

下着のモデルがUnityのAssetStoreで探しても見つからなかったので、自分でモデリングしてテクスチャも作る、なんてこともやったりしました。なかなかおもしろかったです。

開発の参考にした情報

UnityでVIVEを使う開発についてはフレームシンセシスさんのページが網羅されていて大変参考になりました。

framesynthesis.jp

Unityでゲームを作る部分については、書籍が参考になりました。(Unityのバージョンの違いでそのまま使えない部分も少しありました)

ほんきで学ぶUnityゲーム開発入門 Unity5対応

ほんきで学ぶUnityゲーム開発入門 Unity5対応

AWS LambdaをPython3.6とChaliceで試す

AWS LambdaがようやくPython3に対応したそうなので試してました。

AWS Lambda Supports Python 3.6

Lambdaを使う際、Pythonランタイムだとchaliceというフレームワークを使うと楽なのですが、Python3サポートに合わせてchaliceもバージョンが上がっていました。

GitHub - awslabs/chalice: Python Serverless Microframework for AWS

ChaliceのREADMEも3.6になっていたので、これを試してみました。

手順通りで特に問題なく動いたので、説明は割愛。

コードだけ少し変更してPythonのバージョンを表示させてみることにしました。

app.py:

import sys
from chalice import Chalice

app = Chalice(app_name='helloworld')


@app.route('/')
def index():
    return {'python': sys.version}

デプロイして表示されたURLを確認したところ、Pythonのバージョンは3.6.1でした。

f:id:nullpobug:20170419204531p:plain

管理コンソールのランタイムの表示もPython3.6になっているので良さそうです。

f:id:nullpobug:20170419204532p:plain

使っていきたいと思います。

Travis CIのmatrixでtoxを実行する

Djangoフレームワークに依存するPythonのモジュールを作っていると、複数のPythonバージョンと複数のDjangoバージョンでテストコードを実行する必要があります。

手元で実行する場合はtoxを使うのですが、CIツールでもテストを実行したいです。

Welcome to the tox automation project — tox 2.7.0 documentation

GitHubで公開しているプロジェクトの場合、Travis CIを使うのが簡単でした。

Travis CI - Test and Deploy Your Code with Confidence

Travis CIは、複数の実行環境で並列してテストを実行し、テスト結果を分けて表示してくれます。

設定例

toxはTOXENVで実行する環境を指定できるので、.travis.ymlのmatrixでこれを指定します。

Pythonのバージョンを変えつつ環境変数を指定する設定の書き方がわかりづらくて試行錯誤した結果、次のように落ち着きました。

.travis.yml:

sudo: false
language: python
matrix:
  include:
    - python: '2.7'
      env: TOXENV=py27-dj18
    - python: '2.7'
      env: TOXENV=py27-dj19
    - python: '2.7'
      env: TOXENV=py27-dj110
    - python: '2.7'
      env: TOXENV=py27-dj111
    - python: '3.4'
      env: TOXENV=py34-dj18
    - python: '3.4'
      env: TOXENV=py34-dj19
    - python: '3.4'
      env: TOXENV=py34-dj110
    - python: '3.4'
      env: TOXENV=py34-dj111
    - python: '3.5'
      env: TOXENV=py35-dj19
    - python: '3.5'
      env: TOXENV=py35-dj110
    - python: '3.5'
      env: TOXENV=py35-dj111
    - python: '3.6'
      env: TOXENV=py36-dj110
    - python: '3.6'
      env: TOXENV=py36-dj111
    - python: '3.6'
      env: TOXENV=flake8
    - python: '3.6'
      env: TOXENV=coverage
script:
  - tox
install:
  - pip install tox

tox.ini:

[tox]
envlist =
  py27-dj18,
  py27-dj19,
  py27-dj110,
  py27-dj111,
  py34-dj18,
  py34-dj19,
  py34-dj110,
  py34-dj111,
  py35-dj19,
  py35-dj110,
  py35-dj111,
  py36-dj110,
  py36-dj111,
  coverage,
  flake8

[testenv]
commands = nosetests
deps =
  pyftpdlib
  nose

[testenv:py27-dj18]
basepython = python2.7
deps =
  django>=1.8,<1.9
  {[testenv]deps}

[testenv:py27-dj19]
basepython = python2.7
deps =
  django>=1.9,<1.10
  {[testenv]deps}

[testenv:py27-dj110]
basepython = python2.7
deps =
  django>=1.10,<1.11
  {[testenv]deps}

[testenv:py27-dj111]
basepython = python2.7
deps =
  django>=1.11,<1.12
  {[testenv]deps}

[testenv:py34-dj18]
basepython = python3.4
deps =
  django>=1.8,<1.9
  {[testenv]deps}

[testenv:py34-dj19]
basepython = python3.4
deps =
  django>=1.9,<1.10
  {[testenv]deps}

[testenv:py34-dj110]
basepython = python3.4
deps =
  django>=1.10,<1.11
  {[testenv]deps}

[testenv:py34-dj111]
basepython = python3.4
deps =
  django>=1.11,<1.12
  {[testenv]deps}

[testenv:py35-dj19]
basepython = python3.5
deps =
  django>=1.9,<1.10
  {[testenv]deps}

[testenv:py35-dj110]
basepython = python3.5
deps =
  django>=1.10,<1.11
  {[testenv]deps}

[testenv:py35-dj111]
basepython = python3.5
deps =
  django>=1.11,<1.12
  {[testenv]deps}

[testenv:py36-dj110]
basepython = python3.6
deps =
  django>=1.10,<1.11
  {[testenv]deps}

[testenv:py36-dj111]
basepython = python3.6
deps =
  django>=1.11,<1.12
  {[testenv]deps}

[testenv:flake8]
basepython = python3.6
deps =
  flake8
commands =
  flake8 src/

[testenv:coverage]
basepython = python3.6
deps =
  django>=1.11,<1.12
  coverage
  {[testenv]deps}
commands =
  nosetests --with-coverage

実行結果

tokibito/django-ftpserver - Travis CI

f:id:nullpobug:20170415154656p:plain

ハマった点

  • Pythonのバージョンを3.6にすると、Python3.5が入っていない
  • Pythonのバージョンを3.5にすると、Python3.6が入っていない