orangeProse別館

orangeProse(本ブログ)の補助

iiyamaのディスプレイがよかった話(グラボが壊れたと思ったらそうでもなかった)

年末年始には自分のための仕事を進めるつもりだったのだけれど、12月30日、ディスプレイにほとんどなにもうつらなくなってしまった。1月1日に解決するまで、約48時間、パソコンを使えなくて、仕事にならなかった(古いタイプの人間なので、タブレットスマホだけで仕事はムリ)。

ハードにはほんとうに疎いので、ふつうはもっと迅速に通常モードに復帰できるのだろうけれど、まあ、年末年始で顧客の仕事に影響が出なくてよしとしておこう、今回は。

前兆
1週間前ぐらいから、PCの電源を入れてもディスプレイがONにならない。いったんケーブルを抜き差しするとONになる。

こういう症状が1週間続いた後、12月30日の夜、

  • ケーブルを抜き差しすると1秒ほどうつるがすぐに真っ暗に
  • ディスプレイの電源をOFF/ONすると同様に1秒復帰

という状態になった。

スペック:

再起動したり電源切ったりしてるうちにCMOSがどうのこうのという画面になった。

f:id:hidex7777:20150101222837j:plain

そんで、BIOSに入ると(Windowsはディスプレイ電源のON/OFFで1秒ぐらいしかうつってくれないけどBIOSは4秒ぐらいうつる)、CMOSリセットしてないのに、たしかにDate/Timeが設定されていない状態だった。

この時点での仮説と対応:

マザボの電池切れ
翌日ホームセンターで電池を買うことにしよう
グラボがお亡くなりになった
Amazonで安いグラボをポチった
ディスプレイ(の電源)がお亡くなりになった
どうしよう?
マザボがお亡くなりになった
MacBook Proポチった

最悪、MBPをポチったので、それまでパソコン使うの諦めることにした。

12月31日

マザーボードボタン電池はCR2032というらしい。

それでいろいろ調べると、どうやらCR2032とは、

ということらしい。そしてPanasonic一択らしい。把握。

で買ってきた。

f:id:hidex7777:20150101222913j:plain

Amazonバルク品がクソ安く売ってるけど待ってらんないので買った。

マザボの電池を抜いて、CMOSクリアして(MSIだとclrボタンがある)、こいつを入れた。

PCの電源入れるも、変化なし。

Amazonからグラボが翌日届く予定なので、今日はこのぐらいにしといたる。

ムシャクシャして「笑ってはいけない」を忘れて(というか大晦日だということさえ忘れていた)Ingressしに出かけた。

帰省中と思わしき、名も知らぬAgentたちが、旅の恥はかき捨てとばかりに無理リンク貼りまくっていて(一部だとは思うけれど)「これが『お題』というやつか……」とうなだれる。

1月1日

前日、30日にポチったグラボが出荷されて、1日には届く、というメールがすでに入っていた。何時になるかわからないので、いちおう、以前入っていたグラボを一度抜いて、別のスロットに入れるなどしてみた(ドスパラのハード不調はこれで治ることが多い)。が、何の変化もない。

昼過ぎ、ポチっていた玄人志向グラフィックカードが届く。これ:

f:id:hidex7777:20150101223021j:plain

f:id:hidex7777:20150101223051j:plain

2011年発売で、5000円切っている。ゲームとかしないので(Ingress以外は)、うつればいいのだ。

前のドライバをアンインストールして、これを挿す。

うあー。変化がない!

次の段階だ!

夕方。

パソコン工房に出向く。地方のファスト風土なイオンタウンにはマイルドなヤンキーたちの自家用車が大集合している。つうか満車だ! なんで1月1日から2300台収容の駐車場が満車になってんだ!

中略。

ACERにするかiiyamaにするかで(4秒ぐらい)迷ってiiyamaにした。ProLite XB2380HS-B2。

23インチワイドでIPS方式パネル。解像度は普通の安いやつ同等(Retinaには対応しないぐらいの)で1920x1080。

ドット抜け保障つきで20000円ぐらい。

f:id:hidex7777:20150101223125j:plain

ああ、もしこれでも変化なしだったら、次の可能性、マザボがお亡くなりになった、となってしまい(でも出力はしているのだからそれはないはずなんだけど)、いつ届くかわからないMBPを待つことになってしまう……そしてディスプレイは無駄に2枚余って、ということはMBPでトリプルディスプレイ……などと嬉しそうに妄想していたら、うつった。

今回の結論は、ディスプレイ(のたぶん電源)が問題だった、ということだった。しかしこの結論を出すには、うちにある他のディスプレイをつなげばすぐにわかったことではなかろうか……。

MBP期待。

Herokuチートシート:ネイキッドドメインとメール送信まで

f:id:hidex7777:20140915194425j:plain

さいきん、自サイトをHerokuで運用するようになったので、忘れないように自分用にメモ。

方針は次の通り:

  • アプリサーバにはUnicornを使う
  • ネイキッドドメインで運用(www.foobar.comじゃなくてfoobar.comで)
  • メールを送信する(ActionMailerを使う)
  • ドメイン維持(年980円ぐらい?)以外は無料で
  • いちおうMXレコードの登録まではやったたけど受信がめんどくせーのでやるならMandrill(メールのプラグイン)のAPIを各自見てくだしゃんせ

Heroku用にGemfileを書く

ruby '2.0.0'

gem 'rails', '4.0.5'

group :production do
  gem 'pg', '0.15.1'
  gem 'rails_12factor', '0.0.2'
  gem 'unicorn'
end

gemのアップデート。

$ bundle install --without production
$ bundle update
$ bundle install
$ git commit -a -m "Update Gemfile.lock for Heroku"

--without productionはremembered optionなのでコマンドに保存される。

Unicornの設定

$ touch config/unicorn.rb
$ vi config/unicron.rb

worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

config/environments/production.rb

config.assets.compile = true

データベースの設定

config/database.yml

production:
  adapter: postgresql
  encoding: unicode
  # database: db/production.sqlite3
  pool: 5
  # timeout: 5000

Procfileとforemanでのテスト

./Procfile

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb

Unicornがローカル開発環境にインストールされている必要があるけど)

ローカル環境の環境変数を./.envに。

$ echo "RACK_ENV=development" >> .env
$ echo "PORT=3000" >> .env
$ echo ".env" >> .gitignore
$ git add .gitignore
$ git commit -m "add .env to .gitignore"

foremanでテスト

$ gem install foreman
$ foreman start

ログインする

$ heroku login

または

$ heroku auth:login

ログアウトする

$ heroku logout

または

$ heroku logout

アプリを作成してデプロイ

$ heroku create foobar

または

$ heroku create

からの

$ git push heroku master
$ heroku run rake db:migrate
$ heroku ps:scale web=1
$ heroku ps
$ heroku open

サブドメイン名をリネームする

$ heroku rename foobar

必要ないけど。いちおう。

デプロイに失敗したときは

$ rake assets:precompile
$ git add .
$ git commit -m "add precompiled assets for Heroku"
$ git push heroku master

デプロイ時のエラーを取得

$ heroku logs

または

$ heroku logs --tail

実行環境の確認

$ heroku run console
Ruby console for foobar.herokuapp.com
>> Rails.env
=> "production"
>> Rails.env.production?
=> true

SSLを使う場合

config/environments/production.rb

FooBar::Application.configure do
(…)
  config.force_ssl = true
(…)
end
$ git commit -a -m "add SSL in production"
$ git push heroku
$ heroku run rake db:migrate

本番データベースをリセットする

$ heroku pg:reset DATABASE
$ heroku run rake db:migrate

アプリを強制再起動する

$ touch foo
$ git add foo
$ git commit -m "foo"
$ git push horoku

再度デプロイすればいいということ。

どのアカウントでログインしているのか

$ heroku auth:whoami

CloudFlareでネイキッドドメイン

CloudFlareドメインを入れろと言われたら、自分のドメインを入力(例としてここではfoobar.comとする)。スキャンがはじまる。

DNS Records for foobar.com:

CNAME foobar.com is an alias of hoge.fuga.com ACTIVE

みたいに書いてある画面の設定アイコンをクリック。というか、あとでも設定できる。DNS Zone設定で、CNAMEのfoobar.comのValueをfoobar.herokuapp.comにすればよい。

ネームサーバを変えろと言われるので、お名前ドットコムとかの、自分のドメインを管理しているネームサーバを言われたとおりに変える。

http://foobar.comでアクセスできるのを確認する。

ネイキッドドメインの方針。

  • www.foobar.comにアクセスしたらfoobar.comにリダイレクトする。
  • foo.foobar.comのような存在しないサブドメインも同様。

DNS Zoneを次のように設定:

  • CNAME www foobar.herokuapp.com
  • CNAME * foobar.herokuapp.com

My websitesのページで設定アイコンをクリックしてPage Rulesを選択。

f:id:hidex7777:20140915202746p:plain

無料なら3パターンまでルールを登録できる。

Add new ruleで*.foobar.com

Forwarding http://foobar.com

Forwarding type Permanent 301

(参考記事)

メールを送れるようにする

まずGmailから直接送れるか、試してみる

Gmail使って大量メール一斉送信をすると、そっこーでアカウントロックされるとのことなので、一通でも無理なのか、試してみる。

開発環境と同じ設定を書いてみる。

ActionMailerでは

default from: 'FooBar <foobar@gmail.com>'

みたいに、gmailから送信されたことにしている。

confib/environments/producution.rb

  config.action_mailer.raise_delivery_errors = false
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :enable_starttls_auto => true,
    :address => 'smtp.gmail.com',
    :port => '587',
    :domain => 'smtp.gmail.com',
    :authentication => 'plain',
    :user_name => 'foobar@gmail.com',
    :password => 'foobar'
  }

ダメだった。

一通でも、不正なログインで、ブロック。親切設計のGoogle

プラグインを使う

2014.09.10時点で使用できるメールプラグイン(SMSを除く)

  • Mandrill(月12000通無料)(Mandrill.comにログインしたら1時間250通のリミットもあるようなことが書いてあった)
  • Mailgun(1日300通無料=月9000通)
  • Mail2Webhookβ(受信メールをWEBアプリへのPOSTとして扱うプラグイン
  • CloudMailIn(月200通)
  • SendGrid(1日200通無料=月6000通)
  • Postmark(月10000通無料)

第一候補がMandrillで第二候補がPostmark。

けっきょくMandrillでよさげだったので、ここではMandrillだけ紹介する。

Mandrill

$ heroku addons:add mandrill:starter

でもプロヴィジョンできるけれどもドキュメントみながらやりたいのでHerokuのアドオンページからログインする。

(Oh...クレカ登録してなかったからハネられた…)

Mandrillのドキュメントを見ながら進める。

MANDRILL_APIKEYというのが使えるようになっているはずなので、確認する。

$ heroku config:get MANDRILL_APIKEY
foobarfoobarfoobarfoob

$ heroku config -s
↑これで環境変数が見られる。ユーザ名も記録しておいたほうがよい。

開発環境でテスト。Foremanで.envにMANDRILL_APIKEYを書いておく(↓の設定ファイルを使うならユーザ名も必要か)。

MANDRILL_APIKEY=foobarfoobarfoobarfoob

設定サンプルを見ながらconfig/environments/production.rbを書き換える。

  config.action_mailer.raise_delivery_errors = false
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :enable_starttls_auto => true,
    :address => 'smtp.mandrillapp.com',
    :port => '587',
    :domain => 'heroku.com',
    :authentication => 'plain',
    :user_name => ENV['MANDRILL_USERNAME'],
    :password => ENV['MANDRILL_APIKEY']
  }

できた。Gmailで受信すると、送信者名の隣に「経由」って出てなんとなく嫌だけど仕方がない。

受信もする場合:MXレコードの設定

http://mandrill.com/にユーザ名(heroku config -sで分かる)とパスワード(APIキーがパスワード)でログインできるので、ログインしてみる。

Inboundセクションで、ドメインを入力できるので自分のドメインを入れる。

DNSでMXを設定してないのでinvalidと出ている。

DNS Settings]ボタンをクリックすると、DNSサーバ名が2つ表示される。

別タブでCloudFlare開く。

自分のドメインDNS Settingsを開く。

TypeをMX、Nameを自分のドメインに、ValueをMandrillのサーバ、Priorityを10。

もう一行に、もう一つのMandrillサーバ名入れて、Priorityを20。

[I'm done]なんちゃらボタンを押す。

Mandrillに戻って[Test]ボタンを押すとvalidになる。

ActionMailerのコード(差出人のところ)を書き換える。

default from: 'FooBar <info@foobar.com>'

このドメインへの送信(こっちからすれば、受信)は、InboundにあるRoutesを設定する。

アプリに対するPOSTデータとして送信されるので、うまいことフックするアプリを書く。

APIドキュメントを参照されたし。

(参考記事)

Chefのufwクックブック

f:id:hidex7777:20140730230625j:plain

Chefのufwクックブックの使い方がいまいちわからなかったので、公式のREADMEを訳してみました。

結論。nodeのjsonに直接ファイアウォールのルールを記述してしまっていいみたいですが(じっさい、ぼくは目下のところ、ステージング環境と本番環境の2つのノードしか考えていないのでそれが楽かもしれない)、練習も兼ねて、ロールでAttributeを管理するのがいいかなー、と思っています。

『Chef実践入門』にも「Chefで複数ノードを管理する必要が出てきたら迷わずロールを導入しましょう」(p.104)と書いてあります(第4章執筆id:naoya)。

(誤訳の責任はとらないので、よろしくお願い致します。英語としてよくわからん部分があったのでLang-8でネイティブに聞きましたが"This guy's language use is a mess"って言ってました。そのネイティブの解釈にも疑問があったので、この訳は俺様解釈で訳しています)


説明

Ubuntu上のUncomplicated Firewall (ufw)を設定します。ランリストにufwレシピをインクルードすると、ファイアウォールはenableになり、デフォルトで、SSHとICMP pingをのぞいたすべてをDENYします。

ルールをそのノードに付け加えるには、rolesにおける['firewall']['rules']Attributeにルールを加えるか、そのノードに直接加えます。firewallクックブックは、他のレシピからも直接ルールを適用するのに使うことができるLWRPを持っています〔訳注:ufwクックブックはfirewallクックブックに依存しています〕。明示的にルールを削除する必要はありません。変更やリセットのときにそのルールが再評価されます。ルールは、順序が明示されていないかぎり、ランリストの順に適用されます。

要件

Ubuntu 10.04と11.04でテストしました。

レシピ(recipes)

デフォルト(default)

defaultレシピは、適用すべきファイアウォール・ルールのリストを、ロールやノード自体に加えられた['firewall']['rules']Attributeから探します。そして、ルールのリストが、規定の順にノードに対して適用されます。

無効(disable)

disableレシピは現存するファイアウォールを無効化する必要がある場合に使われます。おそらくそれはテストのためでしょう。たとえ他のufwレシピがenableにしようとしても、ufwファイアウォールは無効化されます。

このレシピを削除しても、自動的に再有効化されるわけではありません。['firewall']['state']の値をクリアし、ファイアウォール・ルールの再計算を強制する必要があるでしょう。これはknife node editで行うことができます。

データバッグ(databag)

databagレシピは、ファイアウォール・ルールを適用するために、firewallデータバッグの中を見ます。それは、ロールのためのランリストの精査、およびデータバッグ項目にマップするキーのためのレシピ名の精査にもとづきます。そして、ファイアウォール・ルールは規定の順に適用されます。

ルールを適用するために、['firewall']['rules']Attributeがセットされた後で、databagレシピはdefaultレシピを呼び出します。なので、もし望むならロールとデータバッグ項目をミックスすることもできます(まずロールの適用、それからデータバッグの内容)。

レシピ(recipes)

recipesレシピはnode[<recipe>]['firewall']['rules']Attributeをもつレシピのランリストの精査にもとづいて、ファイアウォール・ルールを適用します。これらはnode['firewall']['rules']に追加され、そのノードに適用されます。クックブックはレシピのためのAttributeをつぎのように定義することができます:

attributes/default.rb for test cookbook

default['test']['firewall']['rules'] = [
  {"test"=> {
      "port"=> "27901",
      "protocol"=> "udp"
    }
  }
]
default['test::awesome']['firewall']['rules'] = [
   {"awesome"=> {
       "port"=> "99427",
       "protocol"=> "udp"
     }
   },
   {"awesome2"=> {
      "port"=> "99428"
     }
   }
]

'test::awesome'ルールは、その特定のレシピがランリストにある場合のみ適用されることに注意してください。レシピで適用されるファイアウォール・ルールは、ロールAttributeで定義されるルールのあとで適用されます。

セキュリティレベル(securitylevel)

securitylevelレシピは、強制される必要があるnode['firewall']['securitylevel']設定がある場合に使われます。これは設定されていないリファレンス実装です。

アトリビュート(Attributes)

ロールとそのノードは['firewall']['rules']Attributeセットを持つことができます。このAttributeはハッシュのリストであり、そのキーはルール名に、その値はパラメータのハッシュになります。適用の順序はランリストにもとづきます。

ロール例

name "fw_example"
description "Firewall rules for Examples"
override_attributes(
  "firewall" => {
    "rules" => [
      {"tftp" => {}},
      {"http" => {
          "port" => "80"
        }
      },
      {"block tomcat from 192.168.1.0/24" => {
          "port" => "8080",
          "source" => "192.168.1.0/24",
          "action" => "deny"
        }
      },
      {"Allow access to udp 1.2.3.4 port 5469 from 1.2.3.5 port 5469" => {
          "protocol" => "udp",
          "port" => "5469",
          "source" => "1.2.3.4",
          "destination" => "1.2.3.5",
          "dest_port" => "5469"
        }
      },
      {"allow to tcp ports 8000-8010 from 192.168.1.0/24" => {
          "port_range" => "8000..8010",
          "source" => "192.168.1.0/24",
          "protocol" => "tcp" //ポートレンジを使う場合プロトコルは必須です
        }
      }
    ]
  }
)

データバッグ(data_bags)

firewallデータバッグはdatabagレシピとともに使われます。それはロール名にマッピングする項目を含むでしょう(例:'apache'ロールは'firewall'データバッグのなかの'apache'項目にマッピングする)。ロールかレシピがキーになります(role[webserver]は'webserver'、recipe[apache2]は'apache2')。もしレシピで規定するファイアウォール・ルールがあれば、'::'を'__'(アンダースコアふたつ)と置き換える必要があります(例:recipe[apache2::mod_ssl]はデータバッグ項目においては'apache2__mod_ssl'です)。

データバッグにおける項目は、['firewall']['rules']Attributeに適用するための'rules'ハッシュ配列を含みます。

% knife data bag create firewall
% knife data bag from file firewall examples/data_bags/firewall/apache2.json
% knife data bag from file firewall examples/data_bags/firewall/apache2__mod_ssl.json

'firewall'データバッグ項目の例

{
    "id": "apache2",
    "rules": [
        {"http": {
            "port": "80"
        }},
        {"block http from 192.168.1.0/24": {
            "port": "80",
            "source": "192.168.1.0/24",
            "action": "deny"
        }}
    ]
}

リソース/プロバイダ(Resources/Providers)

firewallクックブックはfirewallfirewall_ruleというLWRPを提供します。そのためにufwプロバイダはあります。

ライセンスと著作者

Author:: Matt Ray (<matt@opscode.com>)

Copyright:: 2011 Opscode, Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.


訳語の選択はできるだけ『実践Chef入門』に習いましたが、完全ではありません。

はてな朗読会第1回公演会

タイトルは嘘です。はてな朗読会というものがあるわけではなく(たぶん。はてなスペースに「朗読」スペースはあります)、はてなユーザーによる朗読会というわけでもないです。朗読者ではてなユーザーはぼくだけです(たぶん。知らないだけでじつは、とかだったら面白いけど)。

主催はふくしま現代朗読会で、第1回公演会のタイトルは「第一回 言葉で奏でるコンサート 宮沢賢治の世界」です。タイトルからもわかるように、「宮沢賢治縛り」でいきます。「やまなし」「いちょうの実」「セロひきのゴーシュ」「雨ニモマケズ」の4編を読みます。ぼくは「いちょうの実」の予定です。朗読教室の生徒(ぼくを含む)が前半2編、プロの話し手が後半2編を読みます。

フライヤーはこんな感じ:

f:id:hidex7777:20140711223605j:plain

  • 日時:2014年9月20日(土)13:30~
  • 場所:ホテルハマツ1階ロビー

ホテルハマツって、福島県郡山市でたぶん一番でかいホテルです。

入場無料なので、当日フラッとお寄りいただければ幸いです。

予習はどうするか

宮沢賢治を前もって読んでおいたほうがいいのか、と聞かれたら、聴き手が読んでいなくとも楽しめるように、朗読者はがんばります、というのがたてまえですが、読んでいたらなおいっそう楽しめる、というのが朗読の世界です。

個人的にはちくま文庫からでている全集をおすすめします。新潮文庫とかは省略や修正が多い。それと、ちくま文庫の全集には「異稿」も(研究上明らかになっているものに関しては)入っているので、「宮沢賢治をちゃんと読む」ためには必須ともいえます。

というのは、宮沢賢治の作品は、生前に発表されたもののほうが少く、しかも彼は、しょっちゅう、それもかなりドラスティックに改稿に改稿を重ねる作家でした。「最終稿」とか「決定稿」というものはないと言ってもよいでしょう。具体的には、かの有名な「銀河鉄道の夜」には「第4次稿」まであるのですが、それは4つの原稿用紙の束があるというのではなくて、さまざまな筆記具で、さまざまな用紙を使って、書き加えたり削除したりを繰り返しているプロセスが大雑把に言って4段階ある、というにすぎず、「第4次稿」とされているものも「削除し忘れ」による矛盾点があって(削除されたはずの人物がいきなりセリフを言ったり)、現在我々が「宮沢賢治の作品」として読んでいる「銀河鉄道の夜」は後年に研究者(発掘者)が手直しをしたものでしかないのです。

「やまなし」

宮沢賢治が生前に出版した単著は、童話集『注文の多い料理店』と詩集『春と修羅』(第1集)のみですが、同人誌や新聞・雑誌への寄稿はいくつかあります。この「やまなし」も『岩手毎日新聞』に寄稿されたものです。今回の公演会で朗読される作品で、生前に発表されたものはこれだけです。

ちくま文庫版全集では第8巻に収録されています。第8巻には他に「注文の多い料理店」なども所収。

教科書で読んだよ、という方も多いかと思いますが、むしろ最近だと『花もて語れ』で久しぶりに読んだという方が多いかと。「クラムボン」のあれです(発音は「クランボン」)。

『花もて語れ』はこの記事執筆時点で12巻まで出ていますが(13巻で完結予定)、宮沢賢治作品が頻出なので、いちおう全巻読破しておくと良いかと思います(Kindle版だと32%オフ、現時点でポイントが30%バックなのでお得です。最新刊の12巻はまだKindle版が出てないですが)。

f:id:hidex7777:20140711224831j:plain

今回の公演会では、この「やまなし」しかかぶってないのですが、「朗読」にとって宮沢賢治は、釣りにとってのフナのようなもので、「賢治にはじまり賢治に終わる」と言ったら……過言かもしれませんが、『花もて語れ』で「宮沢賢治はどう読まれうるか」ということをイメージしていただければ、楽しめるかと思います。

「いちょうの実」

全集では第5巻に収録(「いてふの実」)。他に「貝の火」や「よだかの星」といった、斎藤環ラカンを説明するために引用した童話も所収。それから「風野又三郎」も(有名なのは「風の又三郎」の方)。

『花もて語れ』に「おきなぐさ」の朗読が出てきますが(6~7巻)、「おきなぐさ」の原稿表紙裏に「花鳥童話集」として11篇の童話題名が列挙されていて、その中のひとつが「いてふの実」。

「セロひきのゴーシュ」

全集では第7巻に収録。他に「銀河鉄道の夜」「風の又三郎」も所収。前述したように、「銀河鉄道の夜」がいかにドラスティックに書きなおされたのか、その図解が面白いので、解説も必読。

「セロひきのゴーシュ」は、東百道氏が「朗読がうまくなるプロセスをストーリーにしたもの」(大意)と言っているように、朗読者にとってはひとつの重要な道標ともいえる作品。

雨ニモマケズ

全集では第10巻に収録。他に「農民芸術概論」など所収。第10巻は手帳やノートに残されたメモなどを集めた巻で、超マニアック。

雨ニモマケズ」も手帳に鉛筆書きされたメモで、詩として残されたものではない(一般には詩として受容されていますが)。解釈としてもさまざまで、手帳の右ページで終わりとするか(「サウイフモノニ/ワタシハナリタイ」で終わり)、左ページまでを含むとするか(「南無無辺行菩薩/南無上行菩薩/南無多宝如来南無妙法蓮華経/南無釈迦牟尼仏/南無浄行菩薩/南無安立行菩薩」で終わり)によって、出版形態が異なったりします(新潮文庫の賢治詩集は「ページで終わり」派)。

あと、賢治の詩は無題が多く、これも(そもそも詩として書かれていないので当たり前ですが)無題の作品ですが、たいてい第一行を〔雨ニモマケズ〕のような書き方でタイトルの代わりにすることが多いようです。

本題 広告出稿募集

公演会は入場無料ですが、パンフレットが配られます。印刷代とかを広告でまかないます。ぜひ日本の知性のトップを担うはてなユーザーの皆様方におかれましては、広告枠を購入していただきたく!

パンフレットは100~200部ぐらい配布されます。

カラーです。(1)2分の1ページ・縦122mm×横166mm、(2)4分の1ページ・縦61mm×横166mm、(3)8分の1ページ・縦58mm×横81mm、の3サイズ。

価格は(1)20,000円、(2)10,000円、(3)5,000円。

フォトショ・イラレのCS5対応で350dpi、CMYKで。jpgでRGBでもいいそうです。

ご連絡はGMailにお願いします(@の前がhidex7777)

かなり久しぶりにAndroid SDKに触ったのでメモ(基礎の基礎)

f:id:hidex7777:20140603201618j:plain

Android SDKが見つかんねーな(自分のPCに)、と思ったら、OSのクリーンインストールをして以来、ダウンロードすらしていなかった!

そんぐらい触ってないと、何をどうしたらddmsとかができるのかとかまで忘れている!

そんなわけで自分用メモに手順書を残しておくぜ・・・

Android SDKをダウンロードする

http://developer.android.com/sdk/index.html

ここの「DOWNLOAD FOR OTHER PLATFORMS」にあるSDK Tools Onlyのzipをダウンロードする。

ADTバンドルとかいらねー。

ダウンロードしたら解凍、android-sdk-windowsとかいうフォルダが生まれた!

こいつをC:\に配置!

パスとかは後回し!

JDKをダウンロードする

http://www.oracle.com/technetwork/java/javase/downloads/index.html

ここの最新版(でいいのかな?)をダウンロードする。

インストール済みのJDKは1.7系統だけど、1.8系統が出ているみたいだ(記事執筆時点)。

ぼくはWindowsの64bit環境だからそのexeをダウンロードすることにした。

JDKのインストールはexeのおおせのままに・・・

PATHを通す

先に入っていたJDK1.7のパスを書き換えてしまうかな・・・

C:\Program Files\Java\jdk1.8.0_05\bin;C:\android-sdk-windows\tools;C:\android-sdk-windows\platform-tools

にパスを通した。platform-toolsはこれからダウンロードすることになるのだ・・・

コマンドプロンプト

>java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mi

なかなかによさそうだぞ!

SDK managerを使う

Windows版だと、SDK manager.exeというのがついてくる。

ダブルクリックしてしばらくたつと、GUI画面が立ち上がる。

なにやら通信しているが、しばらくするとDone、とメッセージ。

Toolsにチェック、Androidなんちゃらのチェックははずす、Android Support Libraryのチェックもはずす、Google USB Driverのチェックはいちおう入れたままにしておく。

Install 12 Packagesをクリック!

Accept License→Install!

今回はAndroidなんちゃらをインストールしなかったので、思ったよりも時間がかからなかった。

Android SDK Managerを閉じる。

platform-tools/というディレクトリがつくられて、ここにadbがある。

コマンドプロンプトを再起動して

>adb devices
List of devices attached

もしAndroid端末が接続されていて、adb接続もされているのであれば、Listになんかしら表示されるはず。

されないということは、さらになにかが必要なのだ。

Android側の設定

機種によってはGoogle USB Driverでは認識してもらえないことがある。

F-05Dのような極悪非道な充電式カイロなんかがそうだ。

ググって

http://spf.fmworld.net/oss/driver/f-05d/

のようなサイトからダウンロードする。

F-05Dはadb接続を可能にするためにいろいろとめんどくさすぎるぞ!

ドライバをインストールした後もadb_usb.iniがないからandroid update adbコマンドを打ったり、iniファイルに文字列がないから自分で書き込んだり・・・

menu→本体設定→アプリケーション→開発→USBデバッグにチェック。

USBケーブルでPCに接続。

コマンドddms

Dalvik Debug Monitorが開く。

接続されているデバイスを選択して、Device→Screen Captureでスクリーンショットがとれたりする。

Android4.0以降は、デバイス側で簡単にスクショとれるんだけどね。

いろいろ作業が終わったらadb kill-serverでプロセスを終了しておく。

いまさらながらBower入れてGruntでcss-modal

f:id:hidex7777:20140602010208j:plain

いまフロントエンドのみの案件にとりかかっているのですが、いわゆるモーダルウィンドウが必要なケースが出てきました。

なんとなーく「jQueryでいいよなー」と考えていたのですが、「そーいやCSSだけでできるのがなんかあったよなー」と思い出し、

を試してみることにしました。

bowerインストール

Bowerはnpmみたいなパッケージマネージャです。

そんでBowerはNode.jsのパッケージです。なのでNode.jsのパッケージマネージャであるnpmでインストールできます。

ややこしいですね。

Bowerの基本的なことはfrom scratch様の記事

らへんを参考にさせていただきました。

まずNode.jsのアップデートから始めるのが基本ですが、ぼくの環境はWindowsなのでアップデートするにはインストーラ使うしかないです。

Windowsじゃない方は

$ node -v
$ sudo npm cache clean -f
$ sudo npm install -g n
$ sudo n stable
$ node -v

でアップデート。

Windowsだとnコマンドが使えないです(n --helpだけ使えますw)。

この記事を書いている時点で、Windowsで利用できる最新版が0.10.28みたいです。

つぎにBowerのインストール。

(たぶんWindowsだと、Gitがインストールされていることが必須です)

>npm install -g bower
>bower -v
1.3.3

bower init

使いたいパッケージと目的が決まってるので、いきなり現行の開発環境に行きたくなりますが、テストから始めるのが良いかと思います。

さっき現行の開発環境で試しながらやってたら、とあるディレクトリがきれいさっぱり消えてなくなりました。

gitがなかったら死んでました。

>mkdir bowertest
>cd bowertest
>git init

.gitignoreファイル
node_modules/
bower_components/

>git add .
>git commit -m "init bowertest"
>bower init

めっちゃいろいろ聞かれますが、

[?] main file: index.js
[?] add commonly ignored files to ignore list?: Yes

このふたつの項目は「公開するライブラリ(Bowerにレジストする)なら」重要、とfrom scratch様の記事には書いてあった。

ここでは公開するライブラリの制作目的でなく、プロダクトの制作にのみ使うことを想定していますが、いちおう上記のように答えました。

あと、公開されないようにprivateのマークを付けるか、と聞かれるので

[?] would you like to mark this package as private which prevents it from being accidentally published to the registry? Yes

これもYesにしました。

最後に書きだされるbower.jsonファイルが良さそうかどうか聞かれるのでこれもYesで答えます。

とりまcss-modalをインストール

>bower install css-modal --save-dev

bower.jsonのdevDependenciesにcss-modalが記述されます。

インストールしてみると、./bower_components/css-modal/以下にいろいろとファイルが置かれていますが、このうち必要なのはmodal.scssとmodal.jsだけです。

そんでもってscssファイルは/dev/scssディレクトリに、jsファイルは/dist/jsディレクトリに配置したいとします。

手作業でやるのでは自動化している意味がないので、Gruntでディレクトリ・レイアウトを指定することにします。

grunt-bower-task

bowerでパッケージをインストールすると、ディレクトリ構造ごと持ってくるので、レイアウト的に使いづらい。

レイアウトを使いやすいようにするgrunt-bower-taskをインストールします。

まだgrunt-cliがインストールされていなければ:

>npm install -g grunt-cli

まだカレントディレクトリがGruntで運用されていなければ:

>npm init
>npm install grunt --save-dev

package.jsonのdevDependenciesにgruntが記述されます。

>npm install grunt-bower-task --save-dev

終わったら、Gruntが使うpackage.jsonファイルのdevDependenciesにgrunt-bower-taskが記述されています。

Gruntfile.coffeeにbowerの挙動を記述します

module.exports = (grunt) ->
  pkg = grunt.file.readJSON 'package.json'
  #config
  grunt.initConfig
    bower:
      install:
        options:
          #ターゲットディレクトリを指定します
          targetDir: './lib'
          #byTypeでファイルの種類ごとにディレクトリを分けます
          layout: 'byType'
          #bower installタスクを実行したいか否か
          install: true
          #詳細ログを出すか
          verbose: true
          #インストール前にターゲットディレクトリを削除するか
          cleanTargetDir: true
          #必要なファイルをターゲットディレクトリにコピーした後にbower_components/を削除するか
          cleanBowerDir: false
     #plugin
     for taskName of pkg.devDependencies
          grunt.loadNpmTasks taskName if taskName.substring(0, 6) is "grunt-"

return

とりあえずこの設定でインストールを実行してみます。

>grunt bower:install

/lib/css-modal/にmodal.jsとmodal.scssがインストールされました!

cleanBowerDirをfalseにしたので、bower_components/も残っています。

bower_components/css-modal/bower.jsonをみると、"main"にmodal.scssとmodal.jsが書いてあるので、必要なファイルのみ/lib/以下にコピーされたわけです。

exportsOverride

layoutをbyTypeにしたのに、ファイルタイプごとに分けられず、/css-modal/以下に2ファイルとも配置されてしまいました。

これはタイプが定義されていないためです。

bower.jsonファイルで定義します:

  "devDependencies": {
    "css-modal": "~1.0.4"
  },
  "exportsOverride": {
    "css-modal": {
      "js": "**/*.js",
      "scss": "**/*.scss"
    }
  }
}

このように定義してgrunt bower:installを実行すると、

  • /lib/scss/css-modal/modal.scss
  • /lib/js/css-modal/modal.js

のようにタイプ分けしてくれます。

今回のケースではcss-modalしかインストールしていないので、よけいにゴチャゴチャしたように見えますが、いろんなパッケージをbowerでインストールしたときは、こっちのほうが便利なケースがあるかもしれません。

ファイルタイプでのレイアウトよりコンポーネントでのレイアウトのほうがいい、という場合は、layoutオプションを'byComponent'にします。

grunt-contrib-copy

もしかしたらgrunt-bower-taskでうまいことやれば、最終目的配置までやれるのかもしれませんが(layoutオプションに関数を定義できます)、めんどくさいので、grunt-contrib-copyを使って、決め打ちでコピーしてしまいます。

どうせファイル名がわかっているので。

>npm install grunt-contrib-copy --save-dev

package.jsonに追記されました。

Gruntfile.coffeeでコピーのタスクを記述します:

module.exports = (grunt) ->
  pkg = grunt.file.readJSON 'package.json'
  #config
  grunt.initConfig
    bower:
      install:
        options:
          targetDir: './lib'
          layout: 'byType'
          install: true
          verbose: true
          cleanTargetDir: true
          cleanBowerDir: true
    copy:
      cssModalScss:
        expand: true
        cwd: "lib/scss/css-modal/"
        src: "modal.scss"
        dest: "dev/scss/"
        flatten: true
        filter: 'isFile'
      cssModalJs:
        expand: true
        cwd: "lib/js/css-modal/"
        src: "modal.js"
        dest: "dist/js/"
        flatten: true
        filter: 'isFile'
  #plugin
  for taskName of pkg.devDependencies
    grunt.loadNpmTasks taskName if taskName.substring(0, 6) is "grunt-"
  #tasks
  grunt.registerTask "bowerinstall", [
    "bower:install"
    "copy:cssModalScss"
    "copy:cssModalJs"
  ]
return

こんどはcleanBowerDirをtrueにしてみました。

(copyの書き方も、もっとうまいことできるかと思いますがめんどくさいので1ファイルごと書いています)

これでgrunt bowerinstallを実行すると、/bower_components/ディレクトリが消え、/lib/以下に配置された各ファイルが、目的の場所にコピーされました。

css-modal

そういえば、この記事は、CSS-Modalを使うために書き始めたのでした。

完全に忘れていた。

CSS-Modalは、cssのみを使ってモーダルウィンドウを表現するライブラリです。

ただしIE8との互換性やESCキーでモーダルを消す、などの機能のためにmodal.jsも使うことになります(jsがなくても、IE8で機能することは機能するらしいです)。

使い方は簡単で

@import 'modal';

でscssファイルにインポートして、モーダルウィンドウになるパーツに対して

.my-modal-section{
  @extend %modal;
}

のように適用するだけです。

注意点は、

  • modal.scssは_modal.scssにリネームして使ったほうがいいかなー
  • _modal.scssの1行目に@charset "UTF-8";を書かないとたぶんエラーが出る
  • csslintはオフる

HTMLのマークアップはこんな感じ

<div class="work">
    <figure class="workimg">
         <a href="#modal-work01"><img src="img/dummy300.png"></a>
    </figure>
    <dl>
         <dt class="worktitle">モーダル作品1</dt>
         <dd class="workdesc">モーダル作品についての説明です。モーダル作品についての説明です。モーダル作品についての説明です。</dd>
    </dl>
    <section class="modal-work" id="modal-work01" tabindex="-1" role="dialog" aria-hidden="true">
         <div class="modal-inner">
              <div class="modal-content"><img src="img/work_01_image.jpg" alt="作品01"></div>
         </div>
         <a href="#!" class="modal-close" title="Close this modal" data-close="Close" data-dismiss="modal">×</a>
    </section>
</div><!-- /.work -->

imgにaのhrefで#modal-work01へのトリガー、モーダルウィンドウ側はhrefに#!でトップに移動しないようにする。

f:id:hidex7777:20140602010208j:plain

ちょっと気になるのは、CLOSEしたときにURLに#!がついてしまうことかなー。

WindowsでもVagrantでChefしたい、rbenvも(11.12.4-1版)

f:id:hidex7777:20140512174308p:plain

以前、Chefの導入編の記事を書きましたが、4月に、Ubuntu14.04 LTSのまっさらなVagant Boxをつくったので、Chefのレシピを書いておきたいと思います。

ところで。

心を入れ替えます。

導入編から書きなおしてみます。

方針としては、Chefリポジトリは(1)Git+GitHubで管理する、(2)Vagrantプロジェクトの中に入れる(ディレクトリ構成のはなし)。

「Chefって結局なんなの?」という方は『入門Chef Solo - Infrastructure as Code』を読んで下さい。

  • ChefとChef-Soloを(ひとまず)区別しましょう(ローカル開発環境=Vagrantで使うのはChef-Soloです)
  • 「冪等性(べきとうせい: Idempotence)」「収束(Convergence)」がキーワードですよ
  • NodeのことをClientとよんだりする(厳密にはChefのAPIと通信できるすべての端末のこと、したがってknifeもChef Clientのひとつ)
  • knife-soloとはChef-Soloを扱うにさいして便利なツールです

こう書いてみると当たり前のことばかりですが、Chefの概念図だけ頭にあると、こんがらがってきます。

ぼくはこの本を読んで、Chefライフがすべてうまく行き始めた気がしてきました。不思議なマジックをもった本です。

筆者の環境:

VagrantにはUbuntuサーバ14.04のボックスが登録されている:

>vagrant box list
Trusty      (virtualbox, 0)

Vagrantプラグインvagrant-omunibusは便利ですがknife solo prepareで済むので、個人的には必要ないかな―と思っています。本番環境でVagrant使うかどうかわかんないですし。

あとvagrant-berkshelfは開発が終わるようなので、見送ります。gemでインストールするBerkshelfは終わるわけではないので、gemで入れましょう。

この記事では、rbenvとruby-buildでrubyをインストールするのに使います。

下準備

>pwd
/c/Users/hidex7777

>mkdir mychef3
>cd mychef3
>vagrant init Trusty
>vim Vagrantfile
(Vagrantfileの修正)
 config.vm.network "private_network", ip: "192.168.33.10"

:wq

>vagrant up 
>vagrant ssh
$ exit
>vagrant ssh-config --host mychef3 >> %HOME%\.ssh\config
>ssh mychef3
$ exit

Macとかの場合、ssh-config --hostの出力先は~/.ssh/configにします。

WorkstationにChefとかをインストール

Step 2: Set up your workstationの"Run the Chef installer"の指示に従ってChef Clientをインストールします(前回、WindowsはGemでインストールするべきだと書きましたが、いまのインストーラならそちらを使うべきかと思います。knifeとかのツールもこれで使えるようになります)。

Windows版インストーラ

11.12.4-1がWin7で使える記事執筆時点の最新版みたいです。

インストールが終わったらコンソールを再起動して:

>path
C:\opscode\chef\bin;C:\opscode\chef\embedded\bin;

にパスが通っているのを確認。

knifeの設定:

>knife configure

いろいろ聞かれますがぜんぶYとかEnterでOK。

便利なツールknife-soloは入れておきます:

>gem install knife-solo

Windowsの場合

ちなみに、Windows版だとないと困るgemを、前もってアンインストールしておきましたが:

gem uninstall win32-process
gem uninstall windows-pr

このChefのインストールで、これらも入りました。

さらに、Windowsだとやはりrsyncがないので、cwRsyncのFree Editionをダウンロード、解凍して、中身をぜんぶパスが通っているディレクトリ(ぼくの場合はC:\Users\hidex7777\bin)に入れて、ssh.exeとssh-keygen.exeを削除

以下の環境変数も追記:

chef-repo作成

>pwd
/c/Users/hidex7777/mychef3

>knife solo init chef-repo
  • ~/mychef3/chef-repo/.chef/knife.rb

ができていればたぶんOK。

自作のレシピは、つくられたディレクトリのなかのsite-cookbooksに入れます。

とりあえずGitHubにpush

GitHub側であらかじめchef-repoリポジトリをつくってあるとして:

>cd chef-repo
>git init
>git add .
>git commit -m "first commit"
>git remote add origin https://github.com/hidex7777/chef-repo.git
>git push -u origin master

NodeをChefに対応させる

>knife solo prepare mychef3
  • ~/mychef3/chef-repo/nodes/mychef3.json

というファイルができていれば、たぶんOKです。

defsetというcookbookをつくってみる

>knife cookbook create defset -o site-cookbooks
  • ~/mychef3/chef-repo/site-cookbooks/defset/recipes/default.rb

ができていればたぶんOK。

/chef-repo/.chef/knife.rbに

cookbook_path    ["cookbooks", "site-cookbooks"]

という記述があることを確認します。

(このknife.rbは~/.chef/knife.rbとは別のファイルです)

とりあえずHello Worldをやっておきます。

default.rbをテキストエディタで開いて:

log "hello world"

と記入。

~/mychef3/chef-repo/nodes/mychef3.jsonに:

{
  "run_list":[
    "recipe[defset]"
  ]
}

と記入。

CookbookをNodeに反映

>pwd
/c/Users/hideo64temp/mychef3/chef-repo

>knife solo cook mychef3

  * log[Hello World] action write

ここまででいちおうコミットしておく:

>git status
>git add .
>git commit -m "add defset"
>git push origin master

ここまでは前回と同じです。

今回は、もうちょっと先に進みたいと思います。

ここから先は、すべてdefsetのdefault.rbに追記していきます。

aptitudeupdateしてdist-upgradeする

aptのupgradeはユーザがrecipeで自動化するべきではない、と述べられています。

そのため、これはインストール後、手動でやるべきとされています。

パッケージを最新版にしたければ、packageのリソース内に記述するべきであると。

例:

package "nginx" do
  action :upgrade
end

とはいえ、使い捨てのVagrantにそこまで気を使う必要もない気がするので、次のように書いてしまう:

execute "aptitude-dist-upgrade" do
    command "aptitude dist-upgrade -y"
    action :nothing
end

execute "aptitude-update" do
    command "aptitude update -y"
    notifies :run, "execute[aptitude-dist-upgrade]", :immediately
end

cookのとき、dist-upgradeのほうはaction :nothingなのでスルーされて、updateが実行されたときにnotifiesでdist-upgradeを:runするようになっています。

なお、「この書き方ではaptシステムを使っているディストリビューションでしか有効でなく、普遍性がないではないか」という批判は正しいのですが、「個人的レシピは徐々に育てる」をモットーにしていきたいと思います。

.bashrcファイル中のHISTSIZEとHISTFILESIZEをそれぞれ90000にする

templateリソースを使います。

ぼくはConsole2を使っているので、chef操作をしているタブとは別タブで、sshログインしておきます。

ssh mychef3したコンソールのタブで、

cp /home/vagrant/.bashrc /vagrant/.bashrc.erb

でコピーしておく。

Nodeの/vagrantディレクトリは、WorkstationのVagrantfileがあるディレクトリと共有フォルダになっているので、手元にコピーがきます。

このファイルをおもむろにコピーして、/chef-repo/site-cookbooks/defset/templates/defaultディレクトリにペーストします。

この.bashrc.erbファイルをテキストエディタで開き、以下の部分を次のように書き換えます:

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=<%= node['bashrc']['histsize'] %>
HISTFILESIZE=<%= node['bashrc']['histfilesize'] %>

サイズは変数にしておきます。ファイル名は拡張子.erbをつけて.bashrc.erbとして保存。

/chef-repo/nodes/mychef3.jsonテキストエディタで開き、次のように変数の値(Attribute)を用意しておきます:

{
    "bashrc":{
        "histsize": 90000,
        "histfilesize": 90000
    },
    "run_list":[
        "recipe[defset]"
    ]
}

/chef-repo/site-cookbooks/defset/recipes/default.rbにtemplateリソースの記述をします:

template ".bashrc" do
    path "/home/vagrant/.bashrc"
    source ".bashrc.erb"
    mode 0644
end

コンソールのChef操作タブに戻り、

> knife solo cook mychef3

でNodeに反映させます。

-HISTSIZE=1000
-HISTFILESIZE=2000
+HISTSIZE=90000
+HISTFILESIZE=90000

のようにdiffが表示されればOKのはずです。

Vagrantにログインしているタブに切り替えて、llコマンドで.bashrcファイルのモードが-rw-r--r--(つまり0644)になっているのを確認。

vi .bashrcで、ファイルが適切に書き換えられているのを確認する。

.bash_aliasesファイルにalias eng='export LANG=en_US.UTF-8'alias jpn='export LANG=ja_JP.UTF-8'の行を追記

これはssh接続でなく直接サーバのターミナルを開いたときに、日本語がちゃんと表示されないのを回避するためのエイリアス

ssh接続のときはjpnで日本語表示、ターミナルで直接開いたときはengで英語表示にする。

これもtemplateを使う。

たぶんインストールしたばかりのサーバには.bash_aliasesファイルはないので、Workstation側で作る。

alias eng='export LANG=en_US.UTF-8'
alias jpn='export LANG=ja_JP.UTF-8'

と書いて、.bash_aliases.erbとして/chef-repo/site-cookbooks/hell/templates/defaultに保存する(この時点ではerbにする意味はないのですが)。

/chef-repo/site-cookbooks/defset/recipes/default.rbに追記する:

template ".bash_aliases" do
    path "/home/vagrant/.bash_aliases"
    source ".bash_aliases.erb"
    mode 0644
end

vim-noxをインストールしてデフォルトエディタにする

vim-noxのインストールのnotifiesからupdate-alternativesを呼び出すようにする(default.rbに追記):

execute "update-alternatives-editor" do
    command "update-alternatives --set editor /usr/bin/vim.nox"
    action :nothing
end

package "vim-nox" do
    action :install
    notifies :run, "execute[update-alternatives-editor]", :immediately
end

etckeeperとgitとtigのインストール

Chefで完全管理して冪等性が保たれているのにetckeeperもなにもないだろう、という気もしますが、なければないで不安なので、入れます。

vim-noxのときのように、actionに:nothingを指定しておいて、他から呼び出すように書いてもいいのだけれど、どれかが何かのはずみでインストールされてしまうと、他がインストールされなくってめんどくさいので、個別に書きます:

package "etckeeper" do
     action :install
end

package "tig" do
    action :install
end

package "git" do
    action :install
end

もちろんvim-noxのところでやったように

package "git" do
    action :install
    notifies :install, "package[tig]", :immediately
end

とやってもよいでしょう(tigのactionは:nothingに)。

/etc/etckeeper/etckeeper.confの編集

.bashrcのときと同じように、ssh mychef3したコンソールのタブで、

cp /etc/etckeeper/etckeeper.conf /vagrant/etckeeper.conf.erb

でコピーしておく。

このファイルを/chef-repo/site-cookbooks/defset/templates/defaultディレクトリにペーストします。

次の部分を書き換えます:

# The VCS to use.
#VCS="hg"
VCS="git"
#VCS="bzr"
#VCS="darcs"

これも、この時点ではerbにする意味はないですが(変数の埋め込みがないので)、念の為にerbファイルにしてtemplateとして扱うのがベターかと思います。

伊藤直也本でもそう述べられています。

template "etckeeper.conf" do
  path "/etc/etckeeper/etckeeper.conf"
  source "etckeeper.conf.erb"
  mode 0644
end

ntpをインストール

package "ntp" do
  action :install
end

ntpはサービスですが、Ubuntuは「インストールしたサービスは、常時動いている。止めたきゃアンインストールせよ」という方針のOSなので、基本的にはサービスのスタートを考えなくてよいとも言えます。

時刻が著しくズレていて同期がとれなくなった場合のことを考えて、設定ファイルを書き換えてもよいかもしれません:

service "ntp" do
  supports :status => true, :start => true, :stop => true, :restart => true, :reload => true
  action :nothing
end

execute "ntpdate" do
  command "ntpdate ntp.nict.jp"
  action :nothing
  notifies :start, "service[ntp]", :immediately
end

template "ntp.conf" do
  path "/etc/ntp.conf"
  source "ntp.conf.erb"
  mode 0644
  notifies :stop, "service[ntp]", :immediately
  notifies :run, "execute[ntpdate]", :immediately
end

この場合もあらかじめ

$ cp /etc/ntp.conf /vagrant/ntp.conf.erb

でコピーをもってきて、次のように書き換えるか:

server ntp.nict.jp
#server 0.ubuntu.pool.ntp.org
#server 1.ubuntu.pool.ntp.org
#server 2.ubuntu.pool.ntp.org
#server 3.ubuntu.pool.ntp.org

デフォルトをコメントアウトせずにntp.nict.jpの行を書き加えるだけにするか、どちらでもよいでしょう。

あるいは設定ファイルは書き換えずに、installと同時にstopしてntpdateしてstartする、というだけでもいいかもしれません(ぼくはそうしています)。

パスワード認証の無効化(/etc/ssh/sshd_config)

sshd_configファイルをテンプレート化します。

ssh mychef3してあるタブで:

$ cp /etc/ssh/sshd_config /vagrant/sshd_config.erb

手元にきたコピーを/templates以下にペースト:

#ポート番号を変数化しておく
Port <%= node['sshd_config']['port'] %>

#'#PasswordAuthentication yes'の行を書き換える
<%= node['sshd_config']['passauth'] %>

#'UsePam yes'の行を書き換える
<%= node['sshd_config']['usepam'] %>

mychef3.jsonファイルに変数を追記:

  "sshd_config":{
    "port": 22,
    "passauth": "PasswordAuthentication no",
    "usepam": "UsePam no"
  },

default.rbファイルに追記:

service "ssh" do
  supports :status => true, :start => true, :stop => true, :restart => true, :reload => true
  action :nothing
end

template "sshd_config" do
  path "/etc/ssh/sshd_config"
  source "sshd_config.erb"
  mode 0644
  notifies :restart, "service[ssh]", :immediately
end

UFW有効化、「OpenSSHへのWorkstationからの許可およびそれ以外からのリミット」ルール作成

UFW(Uncomplicated FireWall)をあつかうのに便利なFirewallリソースが公開されているのですが、この記事を書いている時点で、Travis CIのテストがFailしているので、ひとまず避けておくことにします。

ここではより原始的な方法で。

execute "ufw-allow-openssh" do
  command 'ufw insert 1 allow from 192.168.33.0/24 to any app OpenSSH'
  action :nothing
end

execute "ufw-limit-openssh" do
  command 'ufw limit OpenSSH'
  action :nothing
  notifies :run, "execute[ufw-allow-openssh]", :immediately
end

execute "ufw-enable" do
  command 'printf y | ufw enable'
  notifies :run, "execute[ufw-limit-openssh]", :immediately
end

ufw enableしたときに対話的に入力を求められるので(-yオプションがきかない)、printf yで渡しています。

apache2インストール

UbuntuのAPTで配布されているApache2も、バージョンが2.4系統になったようです。

Apacheを入れたらufwにも許可を入れます:

execute "ufw-allow-apache" do
  command 'ufw allow "Apache Full"'
  action :nothing
end

package "apache2" do
  action :install
  notifies :run, "execute[ufw-allow-apache]", :immediately
end

Workstationのブラウザからhttp://192.168.33.10(Vagrantfileで設定したプライベートネットワーク)に接続して"Apache2 Ubuntu Default Page"が表示されれば成功です。

以前の簡素な"It works!"ページからだいぶ様変わりしていてびっくりしました。

ドキュメントルートを/vagrantにしたwwwサイトを作ってa2enable、000-defaultをa2disable

まずデフォルトの設定ファイルをコピー(いつのまにか.confという拡張子が付くようになりました):

$ cp /etc/apache2/sites-available/000-default.conf /vagrant/www.conf.erb
$ echo "from vagrant" > /vagrant/index.html

2.2ではデフォルトのドキュメントルートが/var/wwwでしたが、設定ファイルを開くとわかるように、2.4では/var/www/htmlになっています(Ubuntu)。

また、Directoryディレクティブが書かれていないので(apache2.confに書かれている)、書き加える必要があります。

www.conf.erbファイルをtemplatesディレクトリにペースト、次のように記述:

  DocumentRoot <%= node['wwwconf']['documentroot'] =>

  <Directory <%= node['wwwconf']['directory'] %>>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
  </Directory>

mychef3.jsonアトリビュートを記述:

  "wwwconf":{
    "documentroot": "/vagrant",
    "directory": "/vagrant"
  },

レシピの記述:

service "apache2" do
  supports :status => true, :start => true, :stop => true, :restart => true, :reload => true
  action :nothing
end

execute "a2dissite-default" do
  command 'a2dissite 000-default'
  action :nothing
  notifies :reload, "service[apache2]", :immediately
end

execute "a2ensite-www" do
  command 'a2ensite www'
  action :nothing
  notifies :run, "execute[a2dissite-default]", :immediately
end

template "www.conf" do
  path "/etc/apache2/sites-available/www.conf"
  source "www.conf.erb"
  mode 0644
  notifies :run, "execute[a2ensite-www]", :immediately
end

新しい設定ファイルwwwをensiteすると同時にデフォルトの000-defaultをdissiteするのがポイントです。

mod_sslをa2enmod、apache2リロード

テンプレート用設定ファイルをコピーします:

$ cp /etc/apache2/sites-available/default-ssl.conf /vagrant/www-ssl.conf.erb

書き換えるところはありませんが(DocumentRootを書き換えたければお好きに)、templates/defaultにコピーします。

レシピ:

execute "a2ensite-ssl" do
  command 'a2ensite www-ssl'
  action :nothing
  notifies :reload, "service[apache2]", :immediately
end

execute "a2enmod-ssl" do
  command 'a2enmod ssl'
  action :nothing
  notifies :run, "execute[a2ensite-ssl]", :immediately
end

template "www-ssl.conf" do
  path "/etc/apache2/sites-available/www-ssl.conf"
  source "www-ssl.conf.erb"
  mode 0644
  notifies :run, "execute[a2ensite-ssl]", :immediately
end

service[apache2]はすでに定義してあるものを使います。

WorkstationのChromehttps://192.168.33.10にアクセスしてデフォルトページが表示されれば成功です(証明書が自己証明なので警告メッセージが出ます)。

rbenvとruby-build

rubyのReadline6.3に対応してない問題(https://bugs.ruby-lang.org/issues/9578)があって、rbenvからのインストールが難航していたのですが、この問題に対するパッチが適用されたバージョンならインストール(ビルド)可能です。

最近のものだと:

1.9.3系統はたぶん大丈夫かと……(わかんないですが、ぼくの環境では1.9.3-p392がビルドエラー出ませんでした。Bug#9548をみると1.9.3もRequiredになってますが)。

>gem install berkshelf

Windowsだと死ぬほど時間がかかりますが……。

リポジトリトップに"Berksfile"というファイル名のファイルを作ります:

source "https://api.berkshelf.com"

cookbook 'ruby_build'
cookbook 'rbenv', github: "fnichol/chef-rbenv"

Berkshelfのv0.3系統からBerksfileの書き方も変わったので、注意。

cookbookをインストールします:

>berks vendor

現在のリポジトリにberks-cookbooksというディレクトリがつくられて、そこにインストールされます。

ちなみにv0.2のときみたいにberks installすると、デフォルトでは~/.berkshelf/cookbooksにインストールされます(設定によると思いますが)。

>berks vendor cookbooks

だとcookbooksにインストールしようと試みますが、すでに存在するディレクトリだと怒られます。なので、必要があれば、cookbooksディレクトリを削除してからやりましょう。

/chef-repo/.chef/knife.rbを修正します:

cookbook_path    ["cookbooks", "site-cookbooks", "berks-cookbooks"]

自動的に追加してくれればいいのに……。

mychef3.jsonに追記:

(省略)
  "rbenv": {
    "user_installs": [
      {
        "user": "vagrant",
        "rubies": ["2.1.2"],
        "global": "2.1.2"
      }
    ]
  },
  "run_list":[
    "recipe[defset]",
    "ruby_build",
    "rbenv::user"
  ]
}
>knife solo cook mychef3

必要な依存パッケージも自動的にじゃんじゃかインストールしていってくれます。超楽チン。

>ssh mychef3
$ ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
$ gem -v
2.2.2
$ rbenv versions
  system
* 2.1.2 (set by /home/vagrant/.rbenv/version)

ふう~大変だった。。。(Readline6.3問題を知らなかったので)

ぼくの現時点のrecipe@GitHub