tanacasinoのメモ

what are you waiting for ?

Slick で 複数のカラムを同時にアップデートする方法

表題の件が、パッと見てもわからなかったので調べたのでメモ。

GitBucketのバグ修正で、とあるカラムをとあるカラムと同様に更新するというコードを書いたのですが、同時に更新する方法がさっとわからなかったので、それぞれのカラムを別々のクエリで更新するというしょうもないことをしてしまったので、反省を込めてメモ。(せっかくなんでリリースに間に合わせたくてとりあえずバグが直ってて動くことを優先した・・・)

Before

def updateCommitIdTo(owner: String, repository: String, issueId: Int, commitIdTo: String): Unit =
  Query(PullRequests).filter(_.byPrimaryKey(owner, repository, issueId)).map(_.commitIdTo).update(commitIdTo)

def updateCommitIdFrom(owner: String, repository: String, issueId: Int, commitIdFrom: String): Unit =
  Query(PullRequests).filter(_.byPrimaryKey(owner, repository, issueId)).map(_.commitIdFrom).update(commitIdFrom)

After

def updateCommitId(owner: String, repository: String, issueId: Int, commitIdTo: String, commitIdFrom: String): Unit =
  Query(PullRequests).filter(_.byPrimaryKey(owner, repository, issueId))
                     .map(pr => pr.commitIdTo ~ pr.commitIdFrom)
                     .update((commitIdTo, commitIdFrom))

多分あってるはず。 言葉で説明すると、 map で更新するカラムを選択するが、単一カラムでない場合は、~ でつなげたオブジェクトを返す必要があり(.map(pr => pr.commitIdTo ~ pr.commitIdFrom))、updateで値を設定する際には、タプルで渡す。

ちなみに、ググるまでもなく初めからGitBucketのリポジトリの中に答えがあったとうオチもある。当たり前だけどまずはそこのコード読むだけで自分がやりたいことは大体そこに答えがある。素敵なことです。 SlickのQueryは今回初めて読み書きしましたが、結構面白い書き方するんで、もっといろいろ遊んでみたくなりますね。

去年はScalaとか構文すらほぼ忘れてるレベル(Javaもあやうい)だったので、ここ半年ちょいいいトレーニングになったなと思い返してみる。

積もり積もった下書きまとめ

ちょっと気を抜くと半年近く更新してないという残念な状態に。。。

下書きに未完成品やタイトルだけ決めたものがいろいろ積み残ってしまったので、いつかかけるといいなと思いつつ、もう書かない気がするのでここにダンプする。

古い順に。。。

  1. Omnibusを使用して/opt 以下に一式を入れるdeb/rpmパッケージを作成する
    • Chefのrpmパッケージに憧れて、Omnibusを使用して、gitbucketをjdk込のオールインワンパッケージを作ってみようとした話。
    • JDKのインストールすらも面倒だろ?と。あとサービス化してくれてたほうが嬉しいやんと。
    • OpenJDKのビルドが面倒でほぼ挫折。Omnibusは面白いのでいつか何かで使えるといいな。 https://github.com/opscode/omnibus-ruby
  2. Copy to clipboard ボタンを作れる ZeroClipboardを使ってみた
    • GitBucketに Copy to clipboard を追加してみたので、その時使った ZeroClipboardを紹介しようと思っていました。ごめんなさい。
  3. OpenStack keystoneにabを仕掛けるメモ
    • 無駄に Keystoneをぶっ飛ばしたいと思って token getしまくってやろうと思ったのです。ab で json送れるので。ボコボコにしてやろうとしたのです。
    • uuid tokenとpki tokenの比較もしてみたかった。(この時すでにOpenStackから完全引退していたけど・・・)
  4. OpenStack の Python 3対応に関するメモ
    • ただの趣味で調べていたので・・・
    • eventletとか どうなるんかね?何か進展したのかなぁ。eventlet楽しいよね。ノンブロッキングだけどブロック!
  5. python testr fixtures によるUnit Test
    • これも趣味で。正直結構そそられたけど、並列化とか考えるほどのUTを書くことはなさそう。
  6. Keystone PKI Tokenの仕組み
    • なんか暇な時にソースを読んだので。なんかメモ書きしようと思った。脳内にしかなかったので完全にロスト!
  7. eventlet backdoor 経由で heapy 使って ヒープダンプとかしチャオ!
    • とか思ってた日もありました。
  8. Amazon EC2インスタンスを復旧する
    • EBSバックエンドを再起動したら、もう起動しなくなっちゃった!な時にバックアップも何もないときの復旧作業
    • volumeからsnapshot作って、snapshotからvolume作って、それを別インスタンスにattachして、ファイルシステムのチェックや、設定の修正を行って、detachして、snapshotにして、VMイメージとして起動する。みたいなやつ。
    • 人生で二回ほど経験。二回目は前の担当者がSSHの設定を変更した後に、設定内容のチェックとかしておらず、再起動するとsshdのconfigがくさってて ssh できないインスタンスが完成するという時限式の罠にかかった。泣いた。
  9. Apache MINA sshdと jgitを使って、オレオレ gitリポジトリサーバを作ろう!
    • GitBucketに ssh アクセス機能を追加したので、その時に使った Apache MINA sshdの紹介をしようと思った。
    • これはすでに @takezoe さんが代わりに書いてくれました。 http://d.hatena.ne.jp/takezoe/20140330
    • そして sshアクセス機能を追加した!と胸をはっていえないほど、自分がやった部分は簡単な実装だけで、むしろ公開鍵登録やCloneURL表示、SSH設定画面のUI作ったりの方が大変だったと思うので、sshアクセス機能を開発したのは、ほぼ @takezoe さんであるw

その他自分で下書き読んでも、なんでそれ書こうとしたのか思い出せない奴は永久に削除しました。

Git の http proxy に関するまとめ

この記事は、Git Advent Calendar 2013 の21日目の記事です。

前日(20日目)の記事は、@harupong さんの Get Great Pro Git !! です。
Pro Gitのサイトは、git関連のことでググると大体行き着くので、よく見てましたが、書籍だったんですね。それを無償公開で、さらには継続的に更新されているとは・・・。また、日本語翻訳は非常にありがたいので感謝感謝です。


Gitでは、ローカルレポジトリとリモートレポジトリ間のデータ転送(clone/push/pull/fetchなど)用のプロトコルに、Local、ssh、git、httpの4つが使用できます。

圧倒的にsshやgitを使用するケースが多かったように思いますが、最近ではGitHubもhttpsプロトコルが clone URLのデフォルトになっているようにみえます。 これは企業等のファイアウォール内から使用する人にもGitが普及してきたという事かもしれません。 私も http proxyサーバを経由せねば外部にアクセス出来ない環境にいることがあるため、SSHなどの利用に不自由することが多いです。

そこで私のように社内LAN等から http proxy サーバ経由で Gitレポジトリを扱わねばならぬ人のためのまとめです。

ちなみに、git http proxy でググるgit config --global http.proxy の話がすぐ見つかるので、それプラスアルファのまとめです。 ほとんどの人にとってそれだけで十分ですw

  1. 環境変数を使用する

    GitはUNIX環境でよくある http_proxy/https_proxy 環境変数が使えます。

     $ export http_proxy=http://proxy.example.com:8080
     $ export https_proxy=$http_proxy
     $ git clone https://github.com/tanacasino/dotfiles.git
    

    認証付きのproxyを利用している場合は、ユーザ名とパスワードは以下のように設定できます。

     $ export http_proxy=http://<username>:<password>@<hostname>:<port>
    
  2. $HOME/.gitconfig に書く

    毎回 環境変数を指定するのは面倒ですし、bashrcなどに http_proxy を書くと proxyを使ってほしくないツールにも影響が出るので記載したくない。 そんな時は $HOME/gitconfighttp.proxy を設定します。

      $ git config --global http.proxy http://proxy.example.com:8080
      $ cat $HOME/.gitconfig
      ...
      [http]
          proxy = http://proxy.example.com:8080
    

    これで git clone/push/fetch/pull/ls-remote などの使用時に自動的に proxyを使用してくれます。 ちなみに、http/https の両方のケースでhttp.proxyを使用してくれるので https.proxy の設定は不要です。 というか、https.proxyという設定はGit的に存在しないように見えます。

  3. REPOSITORY/.git/config に書く

    $HOME/.gitconfig で設定すると、そのユーザで git を使う際のすべてに影響します。 例えば、GitBucketGerrit といった、httpプロトコルでGitレポジトリを提供するアプリケーションを社内LANに設置している場合、 $HOME/.gitconfig に書いた http.proxy の設定のせいで、社内のレポジトリを使用する際も、proxy を経由してしまいます・・・。

    通常ですと、 no_proxy を設定すればええんやー!と考えるかもしれませんが、 残念ながら git では no_proxy という設定がなく使用できません。

    このような場合は、 $HOME/.gitconfig に書くのをやめて、各レポジトリ.git/config に proxyを設定することで回避できます。

     $ mkdir dotfiles
     $ cd dotfiles
     $ git init
     $ git config --local http.proxy http://proxy.example.com:8080
     $ git remote add origin https://github.com/tanacasino/dotfiles.git
     $ git fetch
    

    これで、レポジトリ毎に proxyを設定できるので、社外(eg. GitHub, BitBucket)、社内(eg. GitBucket, Gerrit)のgitレポジトリを使うといった混在環境でも困りません。

  4. REPOSITORY/.git/config で リモートレポジトリ毎に proxy を設定する

    3番までで完璧と思いきや gitではリモートレポジトリを複数設定できますので以下のように、社外のレポジトリと社内のレポジトリの両方をみるレポジトリを使うことがあります。(いや私だけかもしれませんが。。。)

    私の場合は、GitHubに置いてある dotfiles 群のうち、仕事向けに完全に特化する内容(ユーザ名・メールアドレスやproxyのための設定など)を GitHub にpushするのは怒られそうな気がするので、社内業務の設定は、社内の GitBucketレポジトリに pushして、その他の修正を受け取るために、upstream レポジトリとして GitHub を使用しています。

     # 以下のように origin がLAN内のGitBucket、upstreamがGitHub
     $ git remote -v
     origin  https://192.168.32.10/gitbucket/git/tanacasino/dotfiles.git (fetch)
     origin  https://192.168.32.10/gitbucket/git/tanacasino/dotfiles.git (push)
     upstream  https://tanacasino@github.com/tanacasino/dotfiles.git (fetch)
     upstream  https://tanacasino@github.com/tanacasino/dotfiles.git (push)
     # この場合は、 globalに http.proxyを設定するわけにもいかず。。。
    

    さて、このような場合は no_proxy を使うんや!そうや絶対そうやー!と思いますが、no_proxy はありませんので、諦めます。 このようなケースでは、REPOSITORY/.git/config でリモートレポジトリ毎に proxy を設定します。

     $ cd dotfiles
     $ vim .git/config
     [remote "origin"]
         # ここにも proxy が書けるんだぜ!!!
         # 以下のように空白にしておけばproxyを使用しない
         proxy =
     [remote "upstream"]
         # 以下は、http.proxy を設定している場合は不要ですが載せておきます
         # proxy = http://proxy.example.com:8080
    

    これで、リモートレポジトリが外部・内部にわかれててややこしい感じでも問題なっしんぐ!

  5. no_proxyを使えるようにしてみる

    長々といろいろな http proxy 設定してきましたが、3番以降の問題はGitが no_proxyを使えない!という話です。 とりあえず無理やり追加してみました。

    私はC言語の読み書きはできませんので http.proxy の設定部分のコードのコピペだけで作ってみました。 誰か詳しい人が upstream向けにパッチを作ってくれるんじゃないかという期待。

    使用方法は以下の通り。prefix 等はいい感じに自分の環境でどうぞ。CentOS6.4でもビルドできましたが手順はどっかいっちゃいました。

     # Ubuntu 12.04でのビルド手順
     $ sudo apt-get build-dep git
     $ wget http://git-core.googlecode.com/files/git-1.8.4.3.tar.gz
     $ tar xzf git-1.8.4.3.tar.gz
     $ cd git-1.8.4.3
     # apply patch
     $ wget https://gist.github.com/tanacasino/7528954/raw/0ca5bf774a88189ffaca9bf69917d6c29130eb9e/git-1.8.4.3-noproxy.patch
     $ git apply git-1.8.4.3-noproxy.patch
     # build and install
     $ ./configure --prefix=$HOME/local/packages/git-1.8.4.3-noproxy
     $ make
     $ make install
     $ $HOME/local/packages/git-1.8.4.3/bin/git --version
     git version 1.8.4.3
    
     # gitconfig
     [http]
         proxy = http://proxy.example.com:8080
         noproxy = localhost,192.168.32.10
    

このように http proxyの設定1つだけでも、いろいろあって楽しめますね!


明日22日目は、@kozyty さんの記事になります。お楽しみに! Git Advent Calendar 2013

日本OpenStackユーザ会 第16回勉強会に行ってきました

というわけで参加報告するまでが勉強会ということで。

まずはじめに勉強会の準備・会場の準備をしていただいた方、発表者の方、お疲れ様です。 本当にありがとうございました。

では、私の記憶と手元のメモを晒します。 意外とメモが役に立たなくてなんのメモかもう思い出せない・・・ あと、発表者が言ったことなのか?自分の感想・メモなのかが思い出せない・・・

誰かこれを読んで間違いに気づいた方いれば教えて下さいませ。

勉強会について

テーマ

資材

  1. ソースコード

    • https://github.com/openstack/nova
    • GitHubにソースあるしご自由に準備してくださいとのことでしたが、講師の @boot_vmlinuz さんが、GNU Globalを使用したHTML資材を準備してくれいました
  2. GNU GlobalでHTML化した novaのソースコード

  3. 発表スライド

内容

発表スライド読んだほうが正しいですが、なんとなく。

  • ディレクトリ構造
  • nova-* のブートストラップ
  • RPC(プロセス間通信)
  • DB
  • 定期実行処理(Periodic Tasks)

ディレクトリ構造 編

発表スライドに書いてます。こんなメモよりそれを見るのが正解。

何となくとっていた and スライドに書いてない気がする メモをとりあえず

  • hacking : なんだっけ?知ってる人います?に誰も反応せず
  • objects
    • サービス間のデータ受け渡し用(RPC)
    • instance_id とか渡してたけど、それだとinstance_id使ってDBの情報を引くことになる。DBへの負荷高いから、objects の objects に突っ込んで渡そうになっているとのこと
  • servicegroup: 死活監視
    • 昔は DBで管理してた
    • それは負荷が高い
    • 死活監視をモジュール化した。DB以外使える
    • 3種類
      • DB
      • zookeeper
      • memcacched
    • DBドライバは @boot_vmlinuz さんが書いたから不具合あれば教えてくださいとのこと
  • storage: ストレージ操作関連 multipathとかも

この辺でファイルの話もあったけどなぜかメモも記憶も飛んでいる・・・

  • requirements.txt

    • novaが依存する pythonのライブラリが記載される。バージョン指定がきもいやついる
    • RHELが提供する rpm や、Ubuntuが提供する debで入れる人は、これらもパッケージングしてくれてるのであんま気にしないかも
    • ソースから直接入れる人は使うかも(devstackみたいな?)
  • etc に設定ファイルにサンプルあるのでのぞいてみる

    • 設定の数は超絶多いとのこと
    • @ishikawa84g さんがエクセルにまとめてくれているそうな

nova-* プロセスのブートストラップ

  • プロセスのエントリーポイントとなるコードは、nova/cmd/*.py ですよ
  • 昔は、binディレクトリ以下にあったけど変わった
  • setup.cfg でスクリプトになるように書かれてる

簡単なサンプルとして nova/cmd/consoleauth.py を見てみた。

novaは3種類に分けれるよん

  1. 単一プロセスのサービス
    • nova-consoleauthなど。ここが多い
  2. 複数プロセスのサービス
    • nova-conductor
    • workers で設定できる
  3. RESTful APIサービス

nova/cmd/*.py から始まりソースを順番に読む。このあたりで、迷子の参加者多数。

そしてなぜか自分のメモがここだけ だぜ口調。

  • nova.service.Service の解説だぜ
  • nova.service.Service.create で作るんだぜ
  • つまりは、 nova-compute だけ db_allowed=False だぜ
  • nova-compute はDBアクセス禁止だぜ
  • 今までDBからとっていたような情報が欲しい場合は、nova-conductor に問い合わせるぜ

この辺は1行ずつ読んで解説をしていただいたと思いますが、ソース追いかけてて断片的にしかメモがないので、記憶で読んだ気がするコードやキーワードを並べときます。

  • nova/cmd/*.py
  • nova/service.py
    • class Service
    • def create
    • def start
  • nova/openstack/common/service.py
  • nova/manager.py
    • def start の init_hostの話
    • nova-computeの場合 nova/compute/manager.py
  • additional_apisがあるのはのnova-conductorのみ(たぶん)
  • post_start_hook は nova-cells だけ
  • backdoor_port の話

RPC用 consumer の話

Sercice の startの解説で

  • consumer 3つ
  • topic = computeとかみたいにサービスの種類を表す
  • host = サービスが動作するホスト

  • topic and fanout=False : 複数ある同一topicのサービスのうち1つだけが、メッセージ受け取る

  • topic.host and fanout=False : 自分宛てのメッセージを受け取る
  • topic and fanout=True: topic関係者全員が受け取る

RPCの話

発表スライドの13枚目。

  • サービスBのAPIでも rpcしないケースもあり。
    • 例: DBみるだけのときなど
  • RPC送信部 impl_kombuなど
    • nova/openstack/common/rpc/__init__.py
    • nova/openstack/common/rpc/amqp.py
    • nova/openstack/common/rpc/impl_kombu.py
      • RabbitMQ
    • nova/openstack/common/rpc/impl_qpid.py
    • nova/openstack/common/rpc/impl_zmq.py
      • ZeroMQ
    • nova/openstack/common/rpc/impl_fake.py
      • UnitTest向け。
  • dispatcherにより適切なモジュールを呼び出し
    • B/manager.py or baseapi.py
  • check_for_lock

    • よくわかんなかった・・・
  • rpc の データのserialize/desirialize => MQに突っ込むために、JSON形式の文字列データにしたり、受信側でそれを pythonのプリミティブ型(int,str,dict,list)に戻したりする

nova/conductor/ 以下の例(スライド 14)

  • manager.py nova-conductor 自身の本体
  • api.py => 他のサービスからの nova-conductor の呼び出しコード
  • rpcapi.py => 他のサービスからの nova-conductor のRPC呼び出しコード

おまけ編

DB呼び出し

スライド 16

サービスA => nova/db/api.py => nova/db/sqlalchemy/api.py => DB

  • impl は sqlalchemy だけ。
  • zookeeper かなんか別のドライバ作る?って話もあるとか。
    • 作る話は止まってたけど、最近動き出した?みたいな話もありんすた
  • DB操作のメソッドを追加する場合は、両方にメソッドを足しましょう
    • nova/db/api.py
    • nova/db/sqlalchemy/api.py
  • すべての APIが context を渡すようになっている
    • context には、ユーザの権限をチェックしている
    • デコレータでチェック @requires_admin_context
    • DBのAPIで、わざわざ権限チェックとかいらないんじゃないの?という話になっているらしい
      • そもそものHTTP APIリクエスト来てすぐにに権限チェックしてるやん的な
      • 廃止されるかも?

periodic tasks

ユーザからのリクエストイベントからの処理じゃなくて、定期的に実行する処理。periodic_task

  • nova/openstack/common/periodic_task.py
  • nova/compute/manager.py
    • デコレータがついてるやつがperiodic_taskになりんす
    • @periodic_task.periodic_task
    • いろいろあるよねーな話。ザクッと解説していただけましたがメモなし
    • shelved => havanaからできた
      • 停止に近い
      • VMの定義を残したまま、ハイパーバイザー上のリソースを開放する
    • デコレータに引数も付けれるよ
      • interval を個別にコントールできたりする?
      • spacing

まとめ

今日まだまだ読んでないところあるよん。virt のところとか。 でもまあプログラムのエントリーポイントとか、どこにコードがあるかわかったはずなので、今日の説明を足がかりに処理を追いかけれるよ。みんながんばれ。

その他宣伝

  • クラウドマネジメントツール勉強会 第二回
    • 12/4 水曜日
    • みんなくるよね?
  • OpenStack Advent Calendar 2013
    • 小ネタでもなんでも歓迎
    • Glance の代わりに Walrus を使おうとしている人や、イジメ抜く、許さない、絶対な人もいる
  • 沖縄 OpenDays
    • 沖縄でやる。丸一日は、OpenStackのみ。マジチャレンジャー。
  • OpenStack Days Tokyo 2014
    • 2/13,14
    • 今年は二日間だから day ではなく days だよ

おしまい!意外とメモしてないとこ多いけどもう覚えてません! その他の情報は、 Twitter のハッシュタグ #opst16 でどうぞ。