CentOS 7でmongoDB 3.0のWarningを回避する。

CentOS 7環境でmongoを3.0系にアップグレードしたらWarningが出まくってたのですが、時間なくてしばらく放置してたのを回避することにしました。

** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
**        We suggest setting it to 'never'
** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
**        We suggest setting it to 'never'
** WARNING: Readahead for /var/lib/mongo is set to 4096KB
**          We suggest setting it to 256KB (512 sectors) or less
**          http://dochub.mongodb.org/core/readahead
** WARNING: soft rlimits too low. rlimits set to 4096 processes, 64000 files. Number of processes should be at least 32000 : 0.5 times number of files.

hugepageとsoft rlimitsのエラーについては下記を参照しました。
困った何かメモ |mongoDB 3.0.2 mongo shellのWARNINGを回避する
…echo never > /sys/kernel/mm/transparent_hugepage/enabled…については、mongoのサービス起動コマンドをrc.localに書きたくないので、/etc/init.d/mongodのstart()関数を直接いじりました。
soft rlimitsについては公式ドキュメントそのまんま、/etc/security/limits.d/99-mongodb-nproc.confを新規作成しました。

Readaheadのエラーについては下記を参照しました。
centos – Readahead for /var/lib/mongo is set to 4096KB – Server Fault
$df -hでファイルシステムとマウントポイントを調べて$sudo blockdev –setra 256 ファイルシステム を実行します。

最後にmongodを再起動。
$sudo systemctl daemon-reload
$sudo systemctl restart mongod.service

無事Warningが消えました。

OS起動時(Linux)に特定ユーザにスクリプトを実行させたい。

VPS再起動ネタに絡んで。普段OS再起動時に実行させたいスクリプトはrc.localに書いているのですが、特定ユーザでスクリプトを実施させる場合(主にhypnotoadの起動)、suコマンドの-lオプションと-cオプションを使ってコマンドを実行させてたので、すごく気持ち悪くて嫌だなーと思っていました。
具体的には下記の記事と同じ感じです。
rc.localの実行権限とsuによるユーザー切り替えで詰まった – あお日記

仕方ないのでGoogle先生に教えてもらった結果が下記。
システム起動時に特定のコマンドを実行するには - @IT
crontabに@rebootなんていうのがあるのを初めて知りました。スクリプトを実行したいユーザのcrontabを編集してOS再起動したら見事に思ったような挙動になったので良かったです。
ちなみにCentOS 7ですが、Debian系でも同じような挙動をすると思います。

グラディウス2とは関係ない。

【重要】VENOM(KVM・XenなどのQEMUの脆弱性)に関する対策について(5/15 18:10更新) | さくらインターネット
【重要】【さくらのVPS】「VENOM」脆弱性対応に伴うメンテナンス実施のお知らせ(5/20更新) | さくらインターネット

仮想マシンからホストに対して任意のコードが実行できちゃう脆弱性です。あんなとこやこんなとこで試してみたいと思った方も多いんじゃないでしょうか。
自分が使用していたサーバは当初「VENOMの影響を受けない」とアナウンスされていたのですが、残念ながら全VPSが影響を受けるとのことで、さくら側から強制的に再起動を食らう前に自分で電源を入れ直しました。久々にさくらVPSのコンパネにログインしたのですが、さくら本体のメニュー画面とだいぶクオリティが違うなぁと思いました。

TimeLine Copierのバグを修正しました。

(問い合わせがちらほらあったのですが、ずっと原因不明だった)リストのメンバが1000人を超えると429エラーを返すバグを修正しました。

原因

リストに追加できてないメンバーがいないか確認する処理の中で、リストのメンバを取得する処理にcountを設定していなかったため、デフォルトの20人でリストの全メンバを取得しようとして、全員を取得する前に429エラーになっていました。

リストに追加できてないメンバーがいないか確認する処理自体は1年以上前から追加していたので、1年以上バグに気づいていなかったことになりますね。残念極まりないです。

Windows & ruby2.2.2でuserstreamを使ったお返事twitter botを作る。

環境

  • OSはWindows 8.1
  • ruby 2.2.2p95 (2015-04-13 revision 50295) [x64-mingw32]
  • twitter用のgemはsferik/twitter · GitHubのv5.14.0を使用する

なぜWindowsかというと、Windowsでrubyを使っている気になるあのコ向けに書いてるからです。(まあ多分見ないだろうけど。)
eventmachineと組み合わせると、気になるあのコが作りたがってる時報botもWindowsのイベントタイマを使わずに実装できるため、eventmachineの上で動いているtweetstream/tweetstream · GitHubを使用したいと思っていました。が、どう頑張ってもSSLフラグが有効の状態でeventmachineをインストールできなかったため(gem install時にwith-ssl-dirを指定してもさっぱり有効にならない)、em-twitterが動かず、Windowsのruby2.2.2でtweetstreamを動かすのは無理なんじゃないかと思っています(解決法を教えて欲しいレベルでわからないです)。

botの仕様

userstreamを監視して、自分宛てのメンションが来た場合にお返事します。
EM::PeriodicTimer.new(3600)と組み合わせて時報botとお返事botを合体させたかったのですが、うまく動いてくれなかったので今後の課題としたいです。
(私がeventmachineとsferik/twitterの仕様を理解してないからなのですが。)

実装

require 'twitter'

# Consumer key, Secretの設定
CONSUMER_KEY     = "xxx"
CONSUMER_SECRET  = "xxx"
# Access Token Key, Secretの設定
ACCESS_TOKEN_KEY = "xxx"
ACCESS_SECRET    = "xxx"

## Windowsの証明書の検証回避用設定
## 環境変数SSL_CERT_FILEを設定したくない場合下記のコメントアウトを外す
## 正攻法ではないのでおすすめしない。そもそもWindowsでRuby使うこと自体(ry
#OpenSSL::SSL.module_eval{ remove_const(:VERIFY_PEER) }
#OpenSSL::SSL.const_set( :VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE )

client = Twitter::REST::Client.new do |config|
    config.consumer_key       = CONSUMER_KEY
    config.consumer_secret    = CONSUMER_SECRET
    config.access_token        = ACCESS_TOKEN_KEY
    config.access_token_secret = ACCESS_SECRET
end

stream_client = Twitter::Streaming::Client.new do |config|
    config.consumer_key        = CONSUMER_KEY
    config.consumer_secret     = CONSUMER_SECRET
    config.access_token        = ACCESS_TOKEN_KEY
    config.access_token_secret = ACCESS_SECRET
end

# userstreamを表示する
stream_client.user do |object|
    if object.is_a?(Twitter::Tweet)
        puts "#{object.user.screen_name}: #{object.text}"
        # 自分宛てのメンションがきた場合、挨拶を返す
        if object.in_reply_to_screen_name == "YOUR_SCREEN_NAME"
            client.update("@#{object.user.screen_name} リプライありがとう。", options = {in_reply_to_status_id:object.id})
        end
    end
end