Ruby」カテゴリーアーカイブ

Slackで不在時に代理応答する仕組みを作った

今日からペパボで運用を始めた仕組みの紹介です。

モチベーション

ペパボでは新型コロナウィルスをうけて、全社でリモートワークを前提として事業活動を継続しています。そのなかでSlackの各チームのチャンネルを眺めていると、「今からランチに行きます」とか「ちょっと席を外します」といったSlack投稿が結構見受けれました。これはおそらくチームメンバーに対する気遣いで、暗にすぐに反応できないことを伝えているのだと思いました。また有給休暇の際にもステータスメッセージや、ディスプレイネームで工夫しているケースが多くあります。(大和田太郎@8/24有給など)

一方でこれらの発言によって誰がご飯に行っているとか不在とかわかりそうですが、100人とかいるチャンネルだと、なかなか全員の状況を把握するのが難しくなります。そこで、不在時にメンションが飛んできた場合に、代理で応答する仕組み Away From Keyboardを開発し、運用をはじめました。

使い方

導入はgithub.comのREADMEに書きました。支援が必要な人はissueに書いてもらえればサポートします。

導入すると /lunch コマンドと /afk (away from keyboard) コマンドが利用可能になります。

Slackでスラッシュコマンドを実行すると、不在時にメンションを受けた際に不在応答してくれます。標準でそれらしいメッセージを応答しますが、カスタムしたい際は、/afk 今日から8/30までたびに出ます、探さないでください や  /lunch 子供と食べるので14時過ぎそう といったように好きなメッセージを入れることも可能です。席に戻った際は /comeback と入力してください。

実際の様子は下記のような感じです。

最後に

僕自身がリモートワークを前提として働く中でオフィスでは誰が席にいるというような情報が目で見てわかるが、リモートワークだと相手がいるかいないかは結構わからないところに不便さを感じていたのと、またリモートワークを前提とする場合に同期的に働くよりも非同期を前提として働いたほうが効率的に働けると感じているため、今回の仕組みを作りました。

またこれ以外でもオフィスで機能していた働き方をそのままリモートワークに持っていくと知らずとバッドノウハウになっているケースも多くあるのではないかなと思います。今後も僕自身が気づき、改善したものはOSSに切り出して広く公開していきます。

これからお盆休みに入るので活躍の場面が多い時期です。ぜひ導入を検討してみてください。

カテゴリー: Ruby

ロリポップ!マネージドクラウドでAlexaスキルを開発する

僕が開発に携わっているロリポップ!マネージドクラウドはFastContainerアーキテクチャと呼ばれる、リクエストに応じてコンテナを起動するアーキテクチャで実装されています。このアーキテクチャのメリットとして、起動していない間はリソース消費を抑えられるため、非常に安価に利用できることにあります。

今回はその特性を利用して 小山さんを煽る会 という Alexaスキルを開発してみました。

AWS Lambdaで開発した前作はこちらです。

まずはプロジェクトの作成は無料なので下記の手順でRailsアプリを作成します。

次に4. Amazon AlexaからHerokuのRailsにつなぐを参考に、Railsアプリを作ります。今回の用途だとAPIで問題ありません。


$ rails new [project_name] --api

ルーティングを書いていきます。

  • config/routes.rb

Rails.application.routes.draw do
  resources :stir_up, only: %i(create)
end

次にコントローラーを作成しましょう。


% rails generate controller StirUp
Running via Spring preloader in process 64601
      create  app/controllers/stir_up_controller.rb
      invoke  test_unit
      create    test/controllers/stir_up_controller_test.rb

  • app/controllers/stir_up_controller.rb

class StirUpController < ApplicationController
  def create
    Rails.logger.info params
  end
end

ここまで出来たらマネクラにプッシュします。


$ git push lolipop master

Alexaコンソールに移動しアプリを登録します。
今丁度コンソールがリニューアルしているようなのですが、新しい方はまだ不安定で上手く動かなかったので旧コンソールで行きます。

こんな感じでスキルを登録していきます。
input

エンドポイントはマネクラのアドレスにしましょう。

マネクラ

次に対話モデルを定義します。インテントは下記のような形式でOKです。

煽り
煽り2

ここまで登録するとテストを実行することが出来ます。

サービスシミュレータ

サービスシミュレーターを利用して、スキルを呼び出します。マネクラにSSHしてログを見ると、呼び出されているパラメーターが確認できますね。


$ tail current/log/production.log 
I, [2018-03-21T07:08:14.443013 #4]  INFO -- : [38aea28d-4e59-4db0-9961-70364ae3f42d]   Parameters: {"session"=>{"sessionId"=>"SessionId.845fe10e-99c7-4e4c-8087-4b02a845fa86", "application"=>{"applicationId"=>"amzn1.ask.skill.af7ebe42-b341-4a2b-bb92-064e57ab6f42"}, "attributes"=>{},
...

次に簡単な応答をしてみます。Gemfileに下記を追記し、bundle installしてください。


gem 'alexa_rubykit'

次にコントローラーのメソッドを変更します。


class StirUpController < ApplicationController
  def create
    request = AlexaRubykit::build_request(params)
    response = AlexaRubykit::Response.new
    response.add_speech("あれ?小山さん、まだそこの実装やってるんですか?")
    render json: response.build_response
  end
end

commitしてpushすると、レスポンスの変更が確認できます。

レスポンス

せっかくなので、動画でもお伝えしたいと思います。自分のアカウントに紐付いた開発アプリはDEVスキルタブから登録します。

今日は最近仲間入りした洗面所のAlexaで試してみます。

最高ですね?

まとめ

Railsとマネクラを利用して簡単にAlexaスキルを開発できました。もしかするとどこかでハンズオンなどやるかもしれないので、その際はぜひ僕と一緒にコード書きましょう!!!

今日開発に使用したリポジトリはこちらです。

カテゴリー: Ruby

Mackerel運用を支える仕組み

ペパボでムームードメインの開発運用を担当している@pyama86です。

このエントリはMackerel Advent Calendar 2015の12月14日のエントリです。昨日は@ariarijpさんによるエントリでした。

はじめに

ペパボでは従来よりサーバ監視の多くがNagiosにより行われていました。しかし昨今では、クラウドとの相性の良さからMackerelによるサーバ管理へと移行しつつあります。このエントリでは細かい管理の紹介については以前筆者がMackerel MeetUp #5で登壇した際の資料に譲り、Mackerelを大規模導入した際に起こりがちな問題を検知する仕組みを紹介します。

  • ロールに属していないホストを検知する
  • 開発、検証環境ホストへのインストールを検知する
  • 退役忘れホストを検知する
  • オーバースペックなホストを検知する

ロールに属していないホストを検知する

Mackerelにおいては御存知の通りロールを軸として様々な監視、管理を行うことが出来ます。ホストをロールに所属させるにはmackerel-agent.confに定義、APIを用いて操作いずれかの作業が必要ですが、その作業の両方を行っていない場合、ロールに所属しないホストが出来てしまいます。そうなってしまった場合に、気づくにはmkrコマンドでmkr hosts | jq -r '.[] | select(.roleFullnames == null)'とするか、WEBUIから探し出すといった作業が必要になります。これを自動で検知すべくペパボでは筆者が開発したmalsh(マルシェ)というコマンドを利用しています。malshは同僚の@ryutaro_mizokamが開発しているmackerel-rbを利用して各APIの実行結果をSlackに通知することができるコマンドです。筆者の使用方法としてはwheneverと組み合わせて下記のような使い方をしています。

%w(
  MACKEREL_APIKEY
  SLACK_WEBHOOK
  SLACK_CHANNEL
  SLACK_USER
).each do |e|
  env e.to_sym, ENV[e]
end
every :day, :at => '1:00pm' do
  command "/path/to/bin/malsh maverick"
end

これだけの定義で毎日13時にSlackに対してロールに所属していないホストを通知することが出来ます。

marveric

ちなみにmaverickの由来はこのコマンドを書いている時に、映画「トップガン」をながら見していて、作品中でのトム・クルーズの役が一匹狼の凄腕パイロットmaverickであったことに由来します。(トム・クルーズ最高!!!!)

開発、検証環境ホストへのインストールを検知する

puppet,chef,itamaeでのインフラ管理が当たり前となった昨今においてはMackerelのインストールにおいてもコード・自動化していることがほとんどだと思います。しかし新たにレシピを書いた際についつい分岐を入れ忘れたりして、開発、検証環境に誤ってMackerelをインストールしてしまうことも少なくないのではないでしょうか?解決策としてmalshではホスト名で検索し、通知することが出来ます。他にもやり方としてはIPアドレスがローカルアドレスであるというような条件付けも可能に思えますが、現状はホスト名による検知で問題なく運用出来ています。

/path/to/bin/malsh search -e local dev -v exclude.local --subject 不要ホスト候補一覧

この定義ではホスト名にlocalもしくはdevを含むかつexclude.localを含まないホストを、不要ホスト候補一覧という件名でSlackに通知しています。

退役忘れホストを検知する

Mackerelのライセンスはホスト単位となっており、出来るだけ費用を抑えるには、無駄なインストールはしない、必要のないホストは退役させるこれに尽きます。ただし、ライセンスの体系は必ずしもインストール数ではありません。以下公式FAQより引用

1時間程度以内の間隔で定期的にアクティブなホスト数をカウントします。
ホストのステータスに関わらず、メトリック投稿APIにアクセスしたユニークなホスト数を計上します。
通常はmackerel-agentの起動数となります。
退役(Retired)状態のホストはアクティブなホストとしてカウントされません。
30日間、もしくはこれまでの利用済み期間の短かい日数の平均を計算し、その値を利用しているホスト数とします(端数切り上げ)。

上記のホストのステータスに関わらず、メトリック投稿APIにアクセスしたユニークなホスト数を計上します。に注目して、malshでは過去5分のロードアベレージの投稿がないにもかかわらず、Mackerelに登録されているホストを検知することが出来ます。

/path/to/bin/malsh retire

本来であればAUTO_RETIREMENT(自動退役)使えばよい話なのですが、AUTO_RETIREMENT自体がリリース時から使えたわけではなく、またsystemd環境での動作がうまくいってなかったこともあり、必ずしも全ホストにAUTO_RETIREMENTを適用できていないケースも多いのではないかと思います。そういった場合にこの通知を行うことによって退役忘れを防ぐことが出来ます。

オーバースペックなホストを検知する

冒頭で申したとおり、Mackerelはクラウドとの相性が非常によく、AWSやOpenStackと合わせて利用しているユーザーも多いのではないでしょうか?いずれにおいてもインスタンスの費用はスペックに応じて高くなる傾向があり、逆に言えばインスタンスのスペックを低くすればコストを抑えられる事になります。malshでは先日リリースされたグラフメトリックデータ取得APIを利用してCPU、Memory過去N日間の最高使用率がXX%を下回っているホストを検知することが出来ます。

/path/to/bin/malsh search -memory 40 -cpu 40 -subject '過去7日間CPUとMemoryの最高使用率が40%以下のホスト一覧'

過去N日間のデフォルトは7日間で、月次バッチなどを考えると1ヶ月(–past_date 30)といった運用も良いのではないかと思います。またCPU、Memory単独でのしきい値指定も可能です。この通知を行うことによって、ついつい安心モードで大きく作ってしまうインスタンスを見直すきっかけを生み出すことが出来ます。

最後に

本エントリではMackerelを使って何かをすることではなく、Mackerelを上手く運用する幾つかの手段について紹介しました。これまでの監視ツールと異なり、監視対象側に設定の多くを持つことから導入の手間が少ない反面、全体的な管理がしにくい部分もあります。その部分はAPIが提供されているので、上手く利用し、足りない部分を自分たちの運用に合わせて実装していけばより良い運用になると考えます。

そしてグラフメトリックデータ取得APIなど、多くの要望をはてな社に送り、順次対応していただけていることから今後も出来ることが広がり、サーバ監視からよりサーバ管理により近づいていくことが期待できるので、ぜひMackerel利用してみてはいかがでしょうか?

明日は@fujiwaraさんです。

Pecの最近のバージョンアップ事情

どもー。
年末になり一層イケメンに磨きがかかってきました山下です。
今回は僕が開発し、メンテナンスしているOpenStackのインスタンス作成ラッパーのPecの最近のバージョンアップについてまとめてみました。

記事を書いた時点の最新バージョンは0.8.1です。

各コマンドに指定できるホスト名が動的に

例えばこれまでは、各コマンドに渡せるホスト名は一つでFQDNでした。

$ pec status example.foo.jp
Current machine status:
 example.foo.jp ACTIVE  muumuu m1.small nova comp-node.local  10.10.10.1

これが複数渡せるようになったり、

$ pec status example.foo.jp example.bar.jp
Current machine status:
 example.foo.jp ACTIVE  muumuu m1.small nova comp-node.local  10.10.10.1
 example.bar.jp ACTIVE  muumuu m1.small nova comp-node.local  20.20.20.1

ワイルドカードが利用できるようになっています。

$ pec status example*
Current machine status:
 example.foo.jp ACTIVE  muumuu m1.small nova comp-node.local  10.10.10.1
 example.bar.jp ACTIVE  muumuu m1.small nova comp-node.local  20.20.20.1

statusコマンドの高速化

こちらはキャッシュ周りのチューニングを行っていて、フェッチ回数を減らすことでこれまでと比べて爆速で表示できるようになっています。

インスタンス作成失敗時のポートリカバリ

これまではインスタンスの作成に失敗した時、既にポートが作成済みであった場合、作成されたポートはそのまま在庫として残ってしまっていましたが、リカバリで削除するように修正されています。

make start pyama-test001.test.com
image is centos-7.1_chef-12.3_puppet-3.7
flavor is m1.small
availability_zone is nova
port create start : eth0
assgin ip : 10.10.10.10
keypair is example001
create error
recovery start pyama-test001.test.com ⇐
start port recovery
port delete id:1
complete port recovery

ERBテンプレートに対応

これが最近の最大のアップデートです。
もともとyamlマージ記法に対応していたので、デフォルト値を定義すれば同じようなVMはほぼコピペで定義できました。
– Pec.yaml

_default_: &amp;def                                                                                                                                                                                        
  os_type: centos
  tenant: your_tenant
  image: centos-7.1_chef-12.3_puppet-3.7
  flavor: m1.small
  availability_zone: nova
  networks:
    eth0:
      bootproto: static
      allowed_address_pairs:
      - 10.1.1.5/24
      ip_address: 10.1.1.0/24
      gateway: 10.1.1.254
      dns1: 8.8.8.8
# vm config
pyama-test001:
  <<: *def
pyama-test002:
  <<: *def

今回ERBテンプレートにしたことで内部にRubyのコードを埋め込むことが可能になり、こういった定義が可能になりました。
– Pec.yaml.erb

_default_: &amp;def                                                                                                                                                                                        
  os_type: centos
  tenant: your_tenant
  image: centos-7.1_chef-12.3_puppet-3.7
  flavor: m1.small
  availability_zone: nova
  networks:
    eth0:
      bootproto: static
      allowed_address_pairs:
      - 10.1.1.5/24
      ip_address: 10.1.1.0/24
      gateway: 10.1.1.254
      dns1: 8.8.8.8
# vm config
<% ["pyama-test001:", "pyama-test002:"].each do |name| %>
<%= name %>
  <<: *def
<% end %>

ERBを利用することで数100台のホスト定義も工夫すれば数行で定義できるようになったので定義の可読性も上がり、管理がしやすくなりました。
ERB化するにあたり、configコマンドで全定義の出力を差分比較することで、移行ミスを防げることが出来ると思うのでご活用下さい。

$ pec config

今後のアップデート予定

やりたいなぁと思っているのは設定ファイル内のパスワードとかを暗号化する仕組みを何か考えたい。
sshとかプロビジョニングは他のツールに任せて、Pecはいかにインスタンスを楽に作り、管理するかというところに注力していきたいと思っている。

POPメールを便利にするpopperというデーモンプログラムを開発した

POPメールとSlack,GitHubをつなげるツールを書いて運用してました。

困りごと

僕が開発・運用を行っているムームードメインは長らく運用をしてくる中で、プログラムエラーが発生した時や特定の申し込みが行われた場合にいわゆるデバッグメールで通知するという運用になっていて、お問い合わせや、不具合があった場合に、◯十万件のメールの中を本文検索をして、そのメールに含まれる情報を元に対応を行うという状況でした。

加えて、取引先システムの障害通知や、取引先からの業務問い合わせ(クレカ引き落とし調査など)もメールで通知が行われるため、それが埋もれてしまうという問題もありました。

そして、ペパボでは社内のコミュニケーションの殆どがSlackで行われていることから上記のようなメールでのインターフェースをSlackにまとめたいという欲求から開発しました。
SlackのEmail Integrationを採用しなかった理由としてはお客様の個人情報などを含む可能性があったため、外部流出を防ぐ必要があり、すべてをペパボ内で完結させています。(GHEにも対応)

popperで出来ること

設定されたメールアカウントをPOP受信し、件名や本文(任意のメールヘッダ)を正規表現でマッチングさせ、Slack通知、GitHubのIssueを作成することができます。
例えば
– 件名に[問い合わせ]を含む
– 返信メールではない
– 上記に該当した場合、Slackに通知し、Issue作成する
こういったルールをToml形式でコンフィグに記述し、デーモンを起動すると指定した間隔で処理を行ってくれます。

解決できたこと

メールがみんなごとになってどんどん改善が進む

メールって基本的には個人で受信するものなので、小さいエラーとかのメールが来てもなかなか自分事として考えるのって難しいと思うんですね。その点、popperでSlack通知してIssue立てまでやっちゃうと、Slackで全員が同じ情報を共有できるし、そのIssueで解決まで管理することが出来るようになりました。
結果的に小さいエラーの撲滅をガンガン行うことによってムームードメインのユーザービリティを向上させることができています。

周知ワークフローを撲滅できる

例えば決済系の取引先システムの障害がムームードメインの開発メーリングリストに届いたら、それを関連する部署に通知し、調整するような業務とかがあったのですが、そういった業務もpopperが関連部署のSlackチャンネルにメンションと心あたたまるメッセージを添えて通知してくれるので、間に人が入ることなく周知できるようになりました。

使い方

まずはコンフィグを作成します

$ cat /etc/popper.conf  
#----------------------------------
#
# グローバルデフォルト値
#
#----------------------------------

# 返信メールは対象にしない
[default.condition]
subject = ["^(?!.*Re:).+$"]

[default.action.ghe]
token = "************************************"
url   = "http://git.ghe.com"

[default.action.slack]
webhook_url = "https://hooks.slack.com/services/********/***********/**************************"
user = "popper"
channel = "#pyama_botest"
mentions = ["@pyama"]
#----------------------------------
#
# pyama
#
#----------------------------------
[pyama.login]
server = "mail-server.jp"
user = "pyama"
password = "**********"

[pyama.rules.test.condition]
subject = [".*popper テストだぜ.*"]

[pyama.rules.test.action.slack]
message = "popperからテスト通知です"
channel = "#pyama_botest"

[pyama.rules.test.action.ghe]
repo = "pyama/popper_test"

popperをデーモン起動します

$ popper -d 

基本的にはこれだけでokで、/var/log/popper.logにログの出力が行われるので何かあればそちらを確認してもよいですし-dオプションを使わなければカレントターミナルで起動するので、そちらでデバッグしても良さそうです。
また設定されている内容はいつでもpopper printコマンドで確認することが出来ます。

スクリーンショット 2015-11-04 12.05.57スクリーンショット 2015-11-04 12.05.25スクリーンショット 2015-11-04 12.05.36

自分で運用してみて本当に便利だったので、レガシーで似たようなデバッグメールに悩んでいる方、監視システムからのメール通知をより便利にしたい方、利用してみてはいかがでしょうか。

カテゴリー: Ruby

SerfでLvsを管理するNaminoriを書きなおした

夏休み、終わっちゃいますね。
どうも、P山です。

今年の夏休みの宿題は3つ考えていて、今日ようやく終わりました。

OpenStackのKeyPairを利用してSSHログインできるようにする
fogでallowed_address_pairsをサポートする
Naminoriを完成させる

Naminoriは以前第2回ペパボテックカンファレンスの僕の発表で軽く触れていて、
その当時はとりあえず動くだけの状態だったのですが、ようやく書き上げました。

Naminori is

Serfでlvsに動的にメンバーを追加したり、ヘルスチェックを行うrubyのライブラリです。
Serfのmember-joinやleave時のLBメンバーの追加削除、サービスがダウンしている場合に
自動でLBメンバーを削除したりすることができます。(VIPは事前に定義してください)

背景としてlvsはヘルスチェック機能がなく、サービスがダウンした場合でも
パケットを割り振ってしまったりするので、そのあたりのケアをしています。
またlvsであればUDPパケットも管理できるため、
DNSなどのサービスを動的LBしたい場合に是非使ってみてください。

使い方

独自のDSLを採用しており、簡単な設定だけで使い始めることができます。

event.rb

#! /usr/bin/env ruby
require 'rubygems'
require 'naminori'

Naminori.configure do |config|
  # slack通知の設定
  config.notifier :slack do
    webhook_url "https://hooks.slack.com/services/hoge/fuga/test"
    channel     "#pyama"
    user        "#naminori"
  end

  # dnsサービスの設定
  config.service :dns_role do
    service  :dns
    protocol "udp"
    vip "192.168.77.9"
  end
end

Naminori.run

通知設定

メンバーの追加削除時にSlackに通知を行うことができます。

config.notifier :slack do
  webhook_url "https://hooks.slack.com/services/hoge/fuga/test"
  channel     "#pyama_botest"
  user        "#naminori"
end

サービス設定

ロール名ごとにイベント、ヘルスチェックを管理するサービスを定義することができます。
サービスごとのデフォルト値はREADMEを参照してください。

config.service serfロール名 do
  service  :dns(:http)
  protocol "udp"(tcp)
  vip "192.168.77.9"
end

実行

このタイミングで定義された設定に基づき、イベントの判定、ヘルスチェックが実行されます。
ヘルスチェックだけ実行したい場合でも、同じスクリプト(event.rb)をcronなどで実行しておくと
設定された間隔でサービスのチェックが実施できます。

Naminori.run

今今はDNSとHTTPだけ対応していますが、ヘルスチェック部分だけの追加で追加でサービス対応できるようにしてあるので、
必要になったらそのタイミングで追加していきます。

それでは皆様残り少ない夏休み良い時間を〜。

カテゴリー: Ruby

mackerelでログ検知を行うプラグイン macklogを作った

ども。
最近イケメンなので普段は精製水を飲んでいます、
山下です。

mackerelのプラグインとして指定したログに指定したキーワードが出力されたらCritical通知するツール書いてみました。

使い方はこんな感じ

[plugin.checks.http_fatal_error]
command = "macklog -f /var/log/httpd/error.log -w fatal -i"

最近ムームードメインのサーバのリプレイスと合わせて、PHPバージョンアップを実施したことで
時折、PHPのFatalエラーが発生していたりして、それを検知するために作りました。

mackerelはfulentdのプラグインも提供しているのでできないことはなかったのですが、構築するのがそもそもだるかったりするのでフランクに監視したい場合に有効だと思います。

ちなみに同じログを何度も検知しないように/tmp配下に履歴ファイル作成しているので繰り返しの通知は行われません。
また、一度検知をして次の周期で正常判定となるために、繰り返し出力する類のエラーでなければ流れていくのでそのへんもご注意ください。

nagiosのプラグインとの差異はいちいちシークファイルをクリアする必要がないのでさくっと見たいときに使ってください。

それでは残り少ない3連休、素敵にお過ごしください。

カテゴリー: Ruby

VMを作っては壊すPecというコマンドを作った。

どうも!
イケメンの申し子P山です。

現在ペパボではOpenStackを用いてプライベートクラウドを絶賛構築中でして、
その中でVMををガンガン作ってガンガン壊してニヤニヤするためにコマンド作ってみました。

インストール

$ gem install specific_install
$ gem specific_install 'git@github.com:fog/fog.git'
$ gem install pec

specific_installを利用する理由はfogというgemを使用していて、
PRがmasterに取り込まれはしているのですが、
月に一回くらいのリリースのようなので、とりあえず今はgitからmasterブランチをインストールしてます。
(今時点でgem installされるfogだとSecurity Groupが適用されない)

追記
specific_installするとうまく動かないケースがあるので、その場合は抜いてください。

使い方

サンプル設定ファイルの作成と接続先の設定

pec initコマンドを実行すると対話式で接続先のAPIの設定を行ったり、
サンプルファイルが作成されます。

$ pec init
Start Configure by OpenStack
openstack auth_uri: http://your-api-url:35357/v2.0/tokens
openstack username: pyama
openstack api_key: your_password
openstack tenant: your_tenant
Configure Complete!
create directry user_datas
create configure file Pec.yaml

設定ファイルの編集

$ cat Pec.yaml
pyama-test001.cloud.local:
  tenant: pepabo
  image: centos-7.1
  flavor: m1.small
  networks:
    eth0:
      bootproto: static
      ip_address: 10.10.10.0/24
      gateway: 10.10.10.254
      dns1: 8.8.8.8
      dns2: 8.8.8.8
  security_group:
    - default
    - ssh_from_office
  templates:
    - users/default
  user_data:
    hostname: pyama-test001
    fqdn: pyama-test001.cloud.local

設定ファイルはyaml形式で、詳細なフォーマットはこちらに記載してます。
特徴はnetworksに設定を行うと、NeutronAPIとcloud-initのcloud-configを用いて、ifcfg-ethXXXファイルを自動で作成し、かつbootprotostatic を設定して、ip_addressにネットワークアドレスを指定すると
DHCPがない環境でも空きポートからIPアドレスを自動で採番します。
bootprotodhcpを設定した場合でも必要な設定が作成され、いずれの場合でも例えばonboot: noとか任意の項目を書いておくと設定ファイルに項目が追加されます。

またcloud-initに渡すuser-dataのtemplate管理が可能でtemplatesディレクティブに、users/defaultと定義しており、このファイルの中身はこんな感じです。

$ cat user_datas/users/default.yaml 
users:
  - name: centos
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh-authorized-keys:
      - ssh-rsa koukaikagidayooolfkjfsaldkjfaldkfjlasdjfa2398320fdskajf pyama

VM個別に書きたい内容があればuser_dataディレクティブに記載すればこちらももちろん適用されます。

仮想マシンの操作

起動

pec upコマンドで定義ファイルに記載されたファイルをまとめて起動する事ができます。

$ pec up     
pyama-test001.cloud.local: assingn ip 10.10.10.1
success create for server_name:pyama-test001.cloud.local
pyama-test002.cloud.local: assingn ip 10.1.10.2
success create for server_name:pyama-test002.cloud.local

こんな感じでホスト名を指定すると、指定したホストのみの操作も可能です。

$ pec up pyama-test001.cloud.local
pyama-test001.cloud.local: assingn ip 10.10.10.1
success create for server_name:pyama-test001.cloud.local

状態確認

VMの起動状態や、各種状態を確認可能です。
割り当てられたポートのIPも見れる。

$ pec status
Current machine stasus:
 pyama-test001.cloud.local         ACTIVE     pepabo     m1.small   comp-node0001.u01.cloud.local     10.10.10.1                                 
 pyama-test002.cloud.local         uncreated                                                        

VMの削除

VMをまとめて根こそぎ削除します。
一応Yes/No確認しますが-fを引数に渡すと有無を言わさず削除も可能です。

$ pec destroy
pyama-test001.cloud.local: Are you sure you want to destroy the 'pyama-test001.cloud.local' VM? [y/N] y
server_name:pyama-test001.cloud.local is deleted!
pyama-test002.cloud.local: Are you sure you want to destroy the 'pyama-test002.cloud.local' VM? [y/N] y
server_name:pyama-test002.cloud.local is not fond!
can't destroy server:pyama-test002.cloud.local

もう、起動削除が楽しすぎて一人で423回くらい作っては壊してを繰り返してしまいました。

今後の野望

でもとりあえずテスト書きたい。

rspecのwebmockを使ってXMLRPCのテストをする時にハマったこととか。

どうも。
GW太り真っ最中、P山です。

先日XMLRPCを使用するコマンドをThorで書いていて、
rspecでwebmockを使おうとした際に、activesupportのto_xmlを使って、ハッシュから戻り値を生成すると、
XMLRPCの処理できる形式のxmlが生成されず、上手くいかなかった。

require 'active_support/core_ext/hash/conversions' 
require 'yaml' 
describe 'add' do
    before do
      stub_request(:post, "http://api-test.com/host_add").to_return(
        { :body => YAML.load_file('spec/fixtures/test001.yml').to_xml, :status => 200 }
      )
    end
    it 'stdout check' do
      expect { Hoge::Host.new.add('ptr', '157.7.190.0/26', '157.7.190.1', 'hoge.com') }.to output(/Add Record/).to_stdout
    end
  end
end
$ bundle exec rspec spec/
 Failure/Error: server.call2(method, params)
 RuntimeError:
   Missing return value!

具体的には上記エラーがでる。

stackoverflowに同じことはまってる人がいて、
回答を見ると、

<?xml version="1.0" encoding="UTF-8"?>
  <methodResponse>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>wm_description</name>
            <value>manual create</value>
          </member>
…

のような形式で返す必要があるみたいで、
僕がto_xmlで出力していたのは

<?xml version="1.0" encoding="UTF-8"?>
  <responseCode>200</responseCode>
  <responseMessage>テスト</responseMessage>
…

このような値だった。
でもベタ書きするのダサいし、yamlでスッキリ管理したい思いがあったので、
調べていくと、

    before do
      stub_request(:post, "http://api-test.com/host_add").to_return(
        { :body => XMLRPC::Create.new.methodResponse(true, YAML.load_file('spec/fixtures/test001.yml')), :status => 200 }
      )
    end

このように、XMLRPC::Create.new.methodResponseに対して、responseの正否とハッシュを渡してあげると、
XMLRPCが処理できる形式のXMLが生成され、正常にテストが通るようになった。

ドキュメントに実コード書いてあればもうちょっとわかりやすそうだなぁなんて思ったけど、
わからなかったらソース読む活動が出来たので良いハマりだったっぽい。

カテゴリー: Ruby

[続編]aliasを登録するラッパーコマンド書いた

記事概要

昨日ブログに書いてたaliasを楽に登録する方法(よく使うコマンドを楽にalias登録する)だと
バッチ処理には良いのだけど、

「あ、これ登録しとこう」

っていうときにフランクに登録できないので、フランクに登録出来るコマンド作った。

使い方

README.me通りインストールして頂いたら、

オプションなしだと登録されている設定が表示されます。

# am
current commands of the config

 1 : test    = 'ls -la'
 2 : geminst = 'gem install am'

追加は2パターン設けていて、オプション無しだと直近に叩いたコマンドを登録出来ます。

# cd /hoge
# am add
add command is 'cd /hoge'
please input add command alias: 

-l [list]をつけて実行すると直近5件の中から登録することが出来ます。

# am add -l
1: am del -l
2: am add -l
3: cat /root/.am_config
4: am
5: am del geminst
please input add command number: 1
please input add command alias: amdel

[success] amdel / 'am del -l' added command
please run: [ source /root/.am_config ]

削除も名前指定、リスト選択可能としています。

# am     
current commands of the config

 1 : test  = 'ls -la'
 2 : a     = 'am'
 3 : amdel = 'am del -l'

# am del test

[success] delete alias test
please run: [ source /root/.am_config ]

# am del -l
current commands of the config

 1 : a     = 'am'
 2 : amdel = 'am del -l'

please input delete command number: 1

[success] delete alias a
please run: [ source /root/.am_config ]

出来なかったっぽいこと

今回Rubyのthorというgemを使って実装しました。
困ったのがhistoryとかaliasなどのシェルビルドインコマンドを叩いても、
コマンドが走るシェルプロセスとコマンドを叩いたシェルプロセスが分離しているっぽくて
同じセッションで値をとったり、反映することが出来なかったです。

gdb噛ませて無理やりプロセスにアタッチすることも考えたのですが、
少々お行儀が悪い気がしたので、設定ファイルを読み込む形式にしています。

多分便利だと思うので、よければ使ってみてください。

カテゴリー: Ruby