White Box技術部

WEB開発のあれこれ(と何か)

Twitter画像取得ツール「reins」の0.3版をリリースしました

seri.hatenablog.com

前回の紹介からほぼ2年ぶりですが、Twitterからいい感じに画像を取得するツールのreinsの最新版をリリースしました!

reins 0.3

今回、以下の機能追加・バグ修正を行っています。

  • リツイートの取得に関する動作変更の選択機能の追加
  • reinsで取得した画像の元ツイートを表示する機能の追加(コマンド入力機能)
  • Twitterの画像ファイルはlargeを指定して取得するように変更
  • 複数画像があるツイートから先頭の画像しか取れていなかったのを修正

リツイートがつぶやいたユーザのディレクトリ配下に!

リツイートもリストのユーザと同列に保存していたら、正直管理しきれないほどディレクトリが増えてしまったので、 リツイートリツイートしたユーザのディレクトリ配下にrtディレクトリを作成して、その配下に保存するようにしました。

同一ユーザの同一画像を複数保存する可能性が上がりましたが、視認性はよくなったかと思います。

またオプション設定により、そもそもリツイートを取得しないこともできるようにしました。

コマンド入力機能を追加!

reinsを起動しているコンソール(コマンドプロンプト)からのコマンド入力を受け付けるようにしました。

今回は、reinsで取得した画像の元ツイートを表示する「url」コマンドが実装されています。

url -o reinsで取得した画像ファイル名

このようにコマンド入力すると画像ファイルがつぶやかれたツイートを(これはオプションがついているのでブラウザで)表示します(URLを取得するだけなら-oはなくてもOK)。

ログが流れていても認識するので、気にせず入力してください。

注意

画像の元ツイート表示は、今回のバージョンのreinsを使って取得した画像からしか利用できません。 また、dbディレクトリのデータを削除しても同様に利用できなくなります。

所感

画像がつぶやかれた元のツイートの表示機能が楽しいです。

画像元のツイート表示機能は作りたかった機能なので実現できて嬉しいです。

実装のあれこれ

まず2年近くも触ってないと、自分で書いたコードですらなにがなんだかわかりませんね。。
処理と設計方針を思い出すので数日かかりました。

なので今回はドキュメントも並行して作成しています。ドキュメント大事。

それと今回、ツイート表示機能を実装するにあたり、一度テーブル設計を見直したのですが、 結局元のテーブルに追加する感じで機能追加してあります。 リストをベースにした設計になっているので、個別ユーザの情報にアクセスするのがなかなかに大変です。

今後のあれこれ

リツイート毎に同じユーザの情報があったりするので、ここらへんをいい感じに一覧化できるといいかなと思っていたりします。 リスト毎に保存するという現在の作り上だと、どうも難しそうではあるんですが、GUI化でなんとかできないかなと模索中です。

GUI化は別プログラムからreinsを呼び出す感じで実現しようかと思っています。 ここらへんも、どうGUIで表示するとか諸々まとまっていないので、まだなんとも言えないのですが、ユーザ名での検索ができるだけでも結構いいかなと思ったりしています。今回作ったコマンド入力機能を拡張しながらやっていく予定です。

あとは1週間くらい放置しているとTwitterからデータ取得する方のThreadが落ちちゃってるのを直したいのですけれど、 現状のSleep処理から見直さないとダメかもしれないので、結構根が深いです。 バージョン1のリリースまでにはなんとかしたいですが、そろそろTwitterの存続も怪しいのでどうですかね、間に合うかな?

【Shansible】VagrantとAnsibleでのShangriLa開発環境構築

Shansible

Shansibleは、秋葉原IT戦略研究所Project ShangriLaでAnime APIが動作するサーバ群を構築するためのプロジェクトです。

Shansibleを利用することにより、VagrantとAnsibleを使って簡単にローカルでAnime APIの動作を確認する環境を作ることができます。

利用方法

基本的にはshansibleをgit cloneしてvagrant upするだけです。

ですが、環境によってはVagrantやAnsibleの不具合に対する対処がいくつか必要になる場合があります。 READMEに判明している不具合への対処方法を記載していますので、上手くいかない場合はご確認ください。

READMEに記載した、利用するVagrantのバージョンが現時点の最新である1.8.5でないのは、1.8.5にはSSHに関する不具合があり、素の設定ではまともに起動しないためです。(一応対処方法は本家のIssueに上がっています)

Ansible

ミドルウェアのインストールにはAnsibleを使っているのですが、本Playbookに記載している以下のミドルウェアについては まだ他にもそんなに例がないと思いますので、結構いい参考になるのではないでしょうか!

  • MySQL 5.7
  • Jenkins 2
  • Ant

とくにMySQL 5.7のrootパスワード設定は苦労したので、使ってもらえると嬉しいです。(べったり貼っておきます)

- name: download
  get_url: url=http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm dest={{ src_dir }}/
  tags: mysql

- name: local install
  yum: name={{ src_dir }}/mysql57-community-release-el7-7.noarch.rpm state=present
  tags: mysql

- name: install
  yum: name=mysql-community-server state=present
  tags: mysql

- name: create log directory
  file: path={{ mysql_log_dir }} state=directory owner=mysql group=mysql mode=0764
  tags: mysql

- name: replace my.cnf
  template: src=my.cnf.j2 dest=/etc/my.cnf mode=0644
  tags: mysql

- name: start MySQL service
  service: name=mysqld enabled=yes state=started
  tags: mysql

- name: get temporary root password
  shell: cat {{ mysql_log_dir }}/mysqld.log | grep 'password is generated' | awk '{print $11}'
  register: mysql_default_password
  tags: mysql

- name: install MySQL-python module for ansible
  yum: name=MySQL-python state=present
  tags: mysql

- name: check .my.cnf exists
  stat: path=/root/.my.cnf
  register: mycnf_file
  tags: mysql

- name: deploy my.cnf for root user
  template: src=root.my.cnf.j2 dest=/root/.my.cnf mode=0600
  when: not mycnf_file.stat.exists
  tags: mysql

- name: change password validation to the easy way
  shell: |
    mysql -u root -p'{{ mysql_default_password.stdout }}' --connect-expired-password -e "SET GLOBAL validate_password_length=4;"
    mysql -u root -p'{{ mysql_default_password.stdout }}' --connect-expired-password -e "SET GLOBAL validate_password_policy=LOW;"
  when: not mycnf_file.stat.exists and stage == "development"
  tags: mysql

- name: change root user password
  shell: |
    mysql -u root -p'{{ mysql_default_password.stdout }}' --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ mysql_root_password }}';"
  when: not mycnf_file.stat.exists
  tags: mysql

Ansibleの作成方針

以前、Ansible Meetupで「もっとシンプルに」とか話した手前、Ansibleの構成はシンプルになるように心がけました。 基本は公式のベストプラクティスを踏襲しています。

  • 利用者が変更する可能性のある変数はgroup_vars/all.ymlに集約
  • サーバ個別にPlaybookを作成するのではなく、site.ymlにまとめて記載し、インベントリファイルでchildrenを使って、ローカル・開発・STG・本番毎に構成を作れるようにした
  • 環境毎に変数を切り替えたい場合は、group_varsに環境毎のファイルを作成して設定する(local/development/staging/productionのような単位)

これにより、利用者は環境毎のインベントリファイルとsite.yml、group_varsを見るくらいになり、変数を変えたい場合も基本はall.ymlを編集すればよくなります。

注意する点としては、この方法では環境毎にサーバで実行するroleを変えることが、実行時パラメータでも使わないとできないというところです。 これについてはroleを変えるのではなく、whenでstage変数を見て、実行を分けるようにしています。 (例えば、MySQLのパスワードのバリデーションレベルの設定タスク:change password validation to the easy way)

こうすることで1ファイルの複雑度は増しますが、管理するファイルは1つであり、コードの重複も抑えられるため、結果的に見通しが良くなると思います。

雑記

疲れました・・・

いつも実際の開発よりこういう環境周りとかビルドツールとかで詰まる時間の方が長いので、 結果すっかりVagrant/Ansibleおじさんになってしまった感じがありますが、アプリ開発おじさんになれるよう巻き返していこうと思います。

【Reviewet】アプリレビュー通知ツールのその後

Reviewet

以前も紹介したアプリレビュー通知ツールのReviewetですが、その後も少しずつ変更を加え、 一部の挙動や起動方法も変わりましたので、今日はその紹介です。

変更内容

ざっくり書くと変更点は以下になります。

  • メールの件名に、どちらのOSのレビューかが記載されるようなった
  • Reviewetの起動にforeverコマンドを使うように変更
  • checkDateオプション未指定の場合、起動後の新着レビューを通知するように変更

Reviewetをバックグラウンドで起動させていると、プロセスが落ちることがあるので、foreverモジュールを導入して死活監視して貰うようにしました。 導入後はプロセスが落ちる心配はしなくて良くなったのですが、foreverがプログラムを再起動させたときにcheckDateの値が設定されていると、 一度飛んでいたiOSのレビュー結果が再通知されてしまいます。

そこで、checkDateオプションの未指定時の挙動を「既存を全件通知」から「これから来たものを通知」に変更し、 再起動後も重複して通知されないようにしました。なので、基本的にはcheckDateの値は「なし」で利用してください。
(もともとcheckDateは動作確認を目的としてつけたオプションだったので、本来の用途に戻ったような感じです)

今後の予定

コード中にはまだTODOが残っていたりするのですが、機能も一段落、夏の作業も一段落したので、別のものを作る予定です。 9月末までには公開できるといいのですがどうなることやら・・・

【Ansible Meetup】うちのチームの話をしてきました:共通言語「Ansible」

Ansible Meetup in Tokyo 2016.06で発表者枠が頂けたので、自チームでのAnsible運用の様子を発表してきました。

共通言語「Ansible」

Ansibleは仕組みがシンプルなので、コード全体が正確にはわからなくても、なんとなく動作を推測できる構成管理ツールだと思います。 実際、私がまるで知らない状態で触れたときも、実行コマンドだけからなんとなく処理を追っていくことができました。

それがドキュメントに使われる英語をイメージさせるところがあったのと、色々なタイプのエンジニアと話してもAnsibleには結構興味を持っているような印象を受けたので、「Ansibleはエンジニアの共通言語になりえるのでは?」と思い、そのまま発表タイトルとしました。

環境構築自体はどんなエンジニアでも必ずついてまわりますし、意外と苦労するところでもあるので、話のネタにいいですからね。

発表スライド

以下が発表に使ったスライドです。

speakerdeck.com

表紙のイメージは割とすぐ思いついたのですが、なかなかいい感じに作れなくて苦労しました。 せっかくなので「A」をAnsibleのロゴの文字にしようかとも思ったのですが、気力が尽きてそのままです。

もちろん表紙の画像以外も頑張って作ったので、ぜひ見てください。

あと、今回初めてまともにKeynoteを使いましたが、PowerPointの方が使いやすかったです。

見てくださいとは言いつつ、行間を補足するのを前提として作ったので、これだけだとさっぱりかもしれません。
と言いますか、誤解を生みそうな表現を結構入れているので、この資料だけを出すのはちょっと抵抗があったりします。

殴りあったりとかしないですよ?

インフラチームには色々相談にのって貰ったり、助けて貰ったりしているので、いつも感謝しています。 だからこそなのですが、作業を色々お願いしているのに、同じスペースで作業をしていないので大変さが見えず、そこからいつか関係が険悪になったりしないか、とかが結構気がかりだったりするので、その危機感を冗談めかして表現したのがあれです。

話したかったこと

  • Ansibleはインフラ作業を苦手としているメンバーにも興味を持って貰いやすい
  • ドキュメントと引き継ぎ作業は、引き継ぐ人が考えている以上に大事
  • シンプルに保とうとする継続努力が必要
  • 話すネタに困ったらAnsibleのことを話そう!

まとめが駆け足になってしまったので話せていたのか不安ですが、こんなことを伝えたかったです。 勉強会に参加していると、参加者のバックグラウンドは様々なので、話すネタの選択に困るときがありますが、そんなときに構成管理ツールの話は割といいかと思います。

Ansibleの認知度・利用率が上がって、運用方法としてのベストプラクティスが確立されていくといいなーと考えての発表でした。

あと話せませんでしたが、少しはテックな話のおまけも用意していたので、当日話を聞いてくださった方も、スライドの最後の方を改めて見て頂ければ幸いです。

でも発表時間に関してはちょっとモヤっとしてます。持ち時間20分だったのですが、ストップウォッチが16分過ぎたあたりで時間過ぎてると言われたんですよね。
20:05に登壇スペースに行った後、機材トラブルがあって数分待ったので、その時間もカウントされてたのかもしれませんが、オーバーしていると言われた後、急いで締めて、質問受けて、元の位置に戻って時計見たら20:25を少し過ぎてるくらいだったので、話してるときにはオーバーしていないと思うんですよね・・・
最後にLTした方には粗品云々の話があったのですが、私にはなかったので、打ち切りの洗礼だったのかなーと思ったりしている感じです。

→洗礼とかではなく、手違いなだけのようです。よかった・・・(2016/6/6 追記)

Ansible Meetupの感想

なんとなく認識している問題点はどこも同じように感じました。

  • ドキュメントや手順書のこと
  • Playbookのメンテナンスのこと

AnsibleのPlaybookを最新に保つ方法があれば歓迎されそうでした。 というか私が歓迎します。

ちょうど前々日にKibanaの更新やZabbix Agentの設定で、Ansibleが意図通りに動作しない問題の対応をしていたので、Playbookのメンテ方法はどうにか確立させたいですね・・・

逆に、コードの書き方とかにはあまり困ってないような雰囲気を感じました。
これはAnsible自体がシンプルなのと、利用シーンの限定化ができているからかもしれません。 もしくは、開発側の人が少なかったので、Ansibleでアプリケーションの実行に絡む設定までしないですんでいるからかもしれません。

というような話を参加している人としたかったのですが、懇親会がなかったので話すことは叶わず、消化不良気味でした。
テック寄りの勉強会だと懇親会はあまり参加する方ではないのですが、こういう運用経験を共有し合う方が重要な会だと、 参加費払っても懇親会がある方がいい、ということがわかったのは勉強になりました。

そんな感じです。
いやー、今回も準備大変でした。5月最後の宿題でもあったので、肩の荷が下りた感じがしています。

この流れで6月はShansibleを完成させて、ブログのネタにしたいところです。