トップ 最新 追記

人徳ゼロ日記


2013-02-08

_ ScribeFire NextはWYSIWYGエディタでカーソルが効かない

ScribeFire Nextを使っていて気づいたのですが、WYSIWYGエディタの中でカーソルキーを押すと、エディタ内でカーソルが動かず、画面の他のボタン等にフォーカスが移動してしまいます。かなり使いづらい。

せっかく使えると期待していたのに、さすがにカーソルが使えないとつらいです。やや期待はずれで残念。


2013-02-10 Puppet3.0の新機能Hiera auto-lookupの使い方

私はPuppet を結構使っていました(最近は設定作業してないので遠ざかっている)。 設定の作業を手続的にスクリプトとして記載するのではなく、 宣言的に理想状態を記載する、と言う考えは非常に良いと思っています。

ずっとPuppetはウォッチしたりちょっと動かしたりして遊んでいましたが、 昨年2012年10月に出たメジャーバージョンアップPuppet3.0 (リリースノート)に 「Hiera(設定値をマニフェストの外部ファイルに書ける仕組み)をPuppet本体に標準搭載」「パラメタのHiera Auto-lookup機能」と言う かなり重要な機能が追加になりました。

何が重要かと言うと、いままで設定パラメタがロジックの中に混在していたのですが、これがロジックと設定値の分離ができて、ロジックから即値を排除し設定値だけ別ファイルにかけるようになったことです。

ただ、全然ドキュメントがなく、本家Puppetlabsでもわずかしかありません。 唯一書いてあるのは、Language: Classes のInclude-Like Behaviorという所です。 あとはPuppet User Groupメーリングリストで語られているくらいですね。 ましてや、日本語の資料は皆無です。

せっかく手元で試してみたので紹介します。

クラス定義

クラスの書き方はPuppet2.7までと変わりません。 クラスはparameterized classとしてパラメタを受けるようにします。

ファイル: /etc/puppet/modules/mymodule/manifests/conf.pp

class mymodule::conf(
    $p1,
    $p2="p2 default"
) {
    file { "/tmp/mymodule.txt":
        ensure => present,
        mode => 600,
        owner => root,
        group => root,
        content => template("mymodule.txt.template"),
    }
}

クラスのパラメタはテンプレート内で使用します。

ファイル: /etc/puppet/modules/mymodule/templates/mymodule.txt.template

****mymodule test file
p1:<%= p1 %>
p2:<%= p2 %>
name:<%= name %>

site.ppでのクラス適用

Puppet2.7までの例

ノード別に、どのクラスを適用するのか、その際どのようなパラメタにするのか、 site.ppに記載します。 Puppet2.7まではクラス呼び出しの引数でパラメタを指定します。 今回の例では、クラス引数に指定したパラメタがテンプレートに埋め込まれます。

ファイル: /etc/puppet/manifests/site.pp

node mgcent61 {
    class { "mymodule::conf":
        p1=>"puppet2.7 example p1",
        p2=>"puppet2.7 example p2"
    }
}

Puppet適用結果例

# puppet apply -v /etc/puppet/manifests/site.pp 

適用結果のファイル/tmp/mymodule.txt

****mymodule test file
p1:puppet2.7 example p1
p2:puppet2.7 example p2
name:mymodule::conf

Puppet3.0でのHieraを使った例

HieraはPuppet2.7の頃から存在はしていましたが、 Puppet本体とは別でインストールする必要があったのと、 値を取得するところは

  $v = hiera("keyname")

と言うように、明示的にHieraから値を取得するように記載する必要がありました。 そのため、Hieraを使うようにするにはsite.ppでパラメタを渡すところすべてで hiera()を呼び出すように書き換える必要があり、使うまでのしきいが高かったです。

しかし、Puppet3.0からはHieraが標準搭載になったのと、 クラス呼び出しのところで暗黙のうちに Hieraから情報を取って与えてくれる、Auto-lookup機能が追加になりました。

これを使うと、以下のうれしいことがあります。

  • site.pp内でクラスを呼び出す時は、パラメタを指定しなくても良くなるので、 site.pp内のnode定義は、単なるinclude文の羅列で良くなるので非常にシンプルになる。
  • site.pp内でhiera()関数を明示的に呼び出すように書き換える手間がなくなる。

site.ppでのクラスの呼び出し方法は以下のようにincludeを書くだけのシンプルなものになります。 パラメタ値はHieraファイルから自動的に読み込まれます。(Hieraファイルの内容は後ろで書きます)

ファイル: /etc/puppet/manifests/site.pp

node mgcent61 {
    include 'mymodule::conf'
}

参考: 注意: ResourceはHieraのAuto lookupできない と言う記事を追加しました

これでもマニフェストから値が分離できてsite.ppがシンプルになり非常に良いのですが、 さらに、「どのノードにどのクラスを適用するか」をHieraに切り出す方法があります。 Puppet3.0にはhiera_include()という、クラスのincludeをHieraの情報を参照して まとめて行う機能が追加になりました。 これを使えばノード定義はわずか1行になり、 どのノードにどのクラスを適用するかもHiera化できます。(具体的なHieraの書き方は後ろで書きます)

node mgcent61 {
  hiera_include(classes)
}

ノード別Hieraパラメタファイル

Hieraのファイルは、YAMLかjsonで記述します。今回はYAMLを使いました。 ファイルの単位は、PuppetのFacterで取得するfact値ベースで好きに指定できますが、 今回はオーソドックスにノード名単位にファイルを作ることにしました。

例の内容:

  • ノードmgcent61にmymodule::confクラスを適用します。 site.ppのhiera_include(classes)で指定したclassesと言う引数が キーになってHieraからリストを取得し、それをクラス名とみなしてincludeします。
  • mymodule::confの引数p1,p2に値をセットします。

ファイル: /etc/puppet/hieradata/mgcent61.yaml

---
mymodule::conf::p1: hiera test p1
mymodule::conf::p2: hiera test p2
classes:
  - mymodule::conf

Puppet適用結果例

# puppet apply -v /etc/puppet/manifests/site.pp 

適用結果のファイル: /tmp/mymodule.txt

****mymodule test file
p1:hiera test p1
p2:hiera test p2
name:mymodule::conf

Hieraのデータファイルで指定した設定値が、テンプレートに埋め込まれています。 これで、PuppetでのHiera Auto-lookupの動作が確認できました。

参考: Hiera自体の設定hiera.yaml

Hieraの設定は、hiera.yamlで行います。 hiera.yamlの中で出てくる%{::clientcert}という部分は、 PuppetのFacterで取得したFact値のことです。 実際のシステムでどのような値になっているのかは、 /var/lib/puppet/yaml/facts/ホスト名.yamlを参照してください。 以下に、hiera.yamlの内容を解説します。

  • Hieraの記述にYAMLを使う
    :backends:
      - yaml
    
  • Hieraを探す順序の指定
    1. ホスト名.yamlのファイル(fact値としては、clientcertを使う)
    2. common.yamlのファイル(全ノード共通の設定値を記述する。今回の例では特に使用していない)
    :hierarchy:
      - %{::clientcert}
      - common
    
  • Hieraのファイルを配置するディレクトリの指定
    :yaml:
       :datadir: /etc/puppet/hieradata
    
  • ファイル: /etc/puppet/hiera.yaml

    ---
    :backends:
      - yaml
    :logger: console
    :hierarchy:
      - %{::clientcert}
      - common
    :yaml:
       :datadir: /etc/puppet/hieradata
    

    2013-02-12

    _ 注意: PuppetのResourceはHieraのAuto lookupできない

    前回、 Puppet3.0の新機能Hiera auto-lookupの使い方 を紹介しましたが、注意点を一つ。

    • 「クラス」のノード適用にHieraのAuto lookupが使えるのですが、 「リソース(defineで提起する)」のノード適用には使えません。

    考えてみれば、確かにclassはシングルトン(1ノードにインスタンス1個のみ)と言う制約があるので クラス名::パラメタ名で一意に値が決まりますが、 resourceだと複数インスタンスが入るのでclassと同じではダメです。

    脱線ですが、classがシングルトンでresourceがマルチインスタンスと言うのは、 オブジェクト指向言語でのclassの印象からすると逆のイメージになり、非常に混乱します。 Puppetは、言語仕様的にオブジェクト指向言語っぽい雰囲気を醸し出しつつ 実は意味は異なる、と言う傾向にあるので、個人的にはあまり好みではありません。 まあ、間違っている訳ではないですがね。


    2013-02-13

    _ puppetコマンドに、pupet forgeからモジュールをダウンロードしてインストールする機能がついていた

    今まで、Puppetのモジュールは自前で作っていて、 Puppet Forge (モジュールをgitで開発、配布できるコミュニティサイト)にあるモジュールは使っていませんでした。 以前はモジュールの汎用性をあげる作り方が浸透していなかったようで、 作者の特定の環境では使えても他の環境(私の環境)では色々決め打ち過ぎて使えない傾向にありました。

    使えないイメージを持ったままだったので、Puppet Forgeは気にしていなかったのですが、 Puppetlabsのブログで、 PostgreSQLモジュールの紹介記事(Module of the Week: inkling/postgresql – PostgreSQL Management) があり、興味を持ったので使って見ました。

    知らないうちにpuppetコマンドが強化されていて、 「puppet module install モジュール名」 と打つと、Puppet Forgeからモジュールをダウンロードして modulesディレクトリ(Redhat/CentOSなら/etc/puppet/modules)に格納してくれます。 さらに、モジュール間の依存関係まで自動で解決して依存するモジュールもまとめてダウンロードしてくれます。 (もちろん、インターネット接続環境が必要です)

    以下、PostgreSQLモジュールを取り込む例です。

    $ puppet module install puppetlabs-postgresql
    Preparing to install into /etc/puppet/modules ...
    Downloading from https://forge.puppetlabs.com ...
    Installing -- do not interrupt ...
    /etc/puppet/modules
    └─┬ puppetlabs-postgresql (v1.0.0)
      ├── puppetlabs-firewall (v0.0.4)
      └── puppetlabs-stdlib (v2.6.0)
    

    このように依存関係を見て、puppetlabs-firewall,puppetlabs-stdlibも一緒に ダウンロード、展開されました。とても楽で良いですね。 インターネット接続できない閉じた環境だと自動ダウンロードはできないですが、 そもそもmoduleは複雑な依存関係ができないように作るべきなので、 rpmとは異なり手動で取り込んでもまあまあ何とかなるのでしょうね。

    puppet moduleコマンドの詳細は Docs: Installing Modules に書いてあります。


    2013-02-20

    _ puppetlabs-postgresqlモジュールはDB内の管理までできる

    前の記事( puppetコマンドに、pupet forgeからモジュールをダウンロードしてインストールする機能がついていた) で紹介したように、 Puppetlabsが作成したPostgreSQLモジュール は思ったより良かったです。試しに使って見ました。OSはCentOS6.1です。

    モジュールのダウンロードと展開

    モジュールのダウンロードと展開は、前の記事に書いた ように、puppet module install puppetlabs-postgresqlで行えます。

    $ puppet module install puppetlabs-postgresql
    Preparing to install into /etc/puppet/modules ...
    Downloading from https://forge.puppetlabs.com ...
    Installing -- do not interrupt ...
    /etc/puppet/modules
    └─┬ puppetlabs-postgresql (v1.0.0)
      ├── puppetlabs-firewall (v0.0.4)
      └── puppetlabs-stdlib (v2.6.0)
    

    PostgreSQLクライアントのインストール

    まずは、PostgreSQLのデータベースサーバ本体ではなく、 クライアントパッケージ(postgresql)をインストールします。

    クライアントはpostgresqlクラスになります。 site.ppのnode定義にpostgresqlクラス呼び出しを追加します。 以下はPuppet3.0の新機能Hiera auto-lookupの使い方 で紹介したように、hiera_include(classes)でHieraでインクルードするクラスを指定しているので、 ノードごとのHieraファイルに記載します。

    ファイル: /etc/puppet/manifests/site.pp

    node mgcent61 {
      hiera_include(classes)
    }
    

    ファイル: /etc/puppet/hieradata/mgcent61.yaml

    classes:
      - postgresql
    

    puppet適用

    # puppet agent --no-daemonize --onetime --server mgcent61 -v
    (PostgreSQLクライアントのインストールが行われる)
    # rpm -qa |grep postgre
    postgresql-libs-8.4.7-2.el6.x86_64
    postgresql-8.4.7-2.el6.x86_64
    

    PostgreSQLサーバのインストール

    サーバはpostgresql::serverクラスになります。 引数config_hashはハッシュテーブル形式でパラメタを渡します。 例ではPostgreSQLのスーパーユーザであるpostgresユーザのパスワードを指定しています。

    ファイル: /etc/puppet/hieradata/mgcent61.yaml

    classes:
      - postgresql
      - postgresql::server
    postgresql::server::config_hash:
      postgres_password: postgres1
    

    puppet適用

    # puppet agent --no-daemonize --onetime --server mgcent61 -v
    (PostgreSQLのサーバがインストールされて、デーモンが立ち上がった)
    # rpm -qa |grep postgre
    postgresql-libs-8.4.7-2.el6.x86_64
    postgresql-8.4.7-2.el6.x86_64
    postgresql-server-8.4.7-2.el6.x86_64
    # service postgresql status
    postmaster (pid  1324) を実行中...
    # psql -W -U postgres -h localhost
    ユーザ postgres のパスワード: 
    psql (8.4.7)
    "help" でヘルプを表示します.
    postgres=# 
    

    PostgreSQLのデータベース作成(ラッピングリソースpostgresql::db)

    データベース作成、PostgreSQLのユーザ作成、ユーザへの権限設定を一度に行うリソースpostgresql::db があります。一度に行えて便利ように見えますが、細かい制御ができないので、個人的にはあまりおすすめできませんが、 一応例を書いておきます。 なお、postgresql::dbはクラスではなくリソースなので、Hieraのauto lookupが使えません。 site.ppのnode定義で明示的にリソースのインスタンス化をします。 以下の例では、testdb1と言う名前のデータベースを作成し、データベースユーザtestuserを作成します。

    ファイル: /etc/puppet/manifests/site.pp

    node mgcent61 {
      hiera_include(classes)
      postgresql::db { 'testdb1':
        user     => 'testuser',
        password => 'password1',
        grant    => 'all'
      }
    }
    

    puppet適用

    # puppet agent --no-daemonize --onetime --server mgcent61 -v
    (DB作成、DBユーザ作成が行われる)
    $ psql -W -U postgres -h localhost
    ユーザ postgres のパスワード: 
    psql (8.4.7)
    "help" でヘルプを表示します.
    postgres=#  select * from pg_database where datname='testdb1';  ←データベースができていることの確認
     datname | datdba | encoding | datcollate | datctype | datistemplate | datallowconn | datconnlimit | datlastsysoid | datfrozenxid | dattablespace | datconfig |                                     datacl                                     
    ---------+--------+----------+------------+----------+---------------+--------------+--------------+---------------+--------------+---------------+-----------+----------------------------------------------------------------------------------
     testdb1 |     10 |        6 | C          | C        | f             | t            |           -1 |         11563 |          648 |          1663 |           | {=T/postgres,postgres=CTc/postgres,testuser=CTc/postgres,testuser2=CTc/postgres}
    (1 行)
    postgres-# \q
    $ psql testdb1 -W -U testuser -h localhost   ←作成したユーザでログイン	
    ユーザ testuser のパスワード: 
    psql (8.4.7)
    "help" でヘルプを表示します.
    testdb1=> 
    

    postgresql::dbはDB,ユーザを一度に作成してしまうので、 後から変更したくなった場合に色々困ってしまいます。 それでは、postgresql::dbのパラメタを変更して、 ユーザ名をtestuser→testuser2に変更してみます。

    ファイル: /etc/puppet/manifests/site.pp

    node mgcent61 {
      hiera_include(classes)
      postgresql::db { 'testdb1':
        user     => 'testuser2',
        password => 'password2',
        grant    => 'all'
      }
    }
    

    puppet適用

    # puppet agent --no-daemonize --onetime --server mgcent61 -v
    

    結果: 新規にtestuser2が作成された。以前のtestuserは残ったまま。

    元々Puppetは後から変更できることが利点の1つですが、 後から変更に柔軟に対応できないのはPuppetの良さが減ってしまうので、 postgresql::dbは後から変更が必要ないと分かっているときだけにした方が良いです。 なお、個別に削除するPuppetの書き方として、 postgresql::database_user { "testuser": ensure => absent } と明示する方法がよく使われるのですが、PostgreSQLモジュールではまだ実装されていないようです。

    データベースと、PostgreSQLのユーザの管理を個別に行うには、以下のリソースを利用します。 どちらもクラスではなくリソースです。

    • データベース postgresql::database
    • データベースのユーザ postgresql::database_user

    2013-02-21

    _ puppetlabs-postgresqlモジュールの裏側

    puppetlabs-postgresqlモジュールはDB内の管理までできる で紹介したPuppetlabsのPostgreSQLモジュールですが、 内部ではpostgresql::psqlというリソースが中心的な役割を果たしています。 これは名前の通りpsqlでSQL文を発行するのですが、 Puppet的なidempotent(冪等性: 何度適用しても同じ結果になる)を保つために unlessでSQL文が実行される条件を指定できるようになっています。

    以下はpostgresql::role内でpostgresql::psqlを呼び出している例です。

      postgresql::psql {"CREATE ROLE ${username} ENCRYPTED PASSWORD '${password_hash}' $login_sql $createrole_sql $createdb_sql $superuser_sql":
        db      => $db,
        user    => 'postgres',
        unless  => "SELECT rolname FROM pg_roles WHERE rolname='$username'",
      }
    

    この例では、「作成すべきroleの存在チェックをして、存在しない場合のみroleを作成する」 と言う動作になりますこの仕組みはSQL文を使った管理で良くあるパターンなので、 かなり汎用的に使えるはずです。

    psqlはパスワード入力なしでPuppetから発行できる必要があるのですが、 以下の条件を満たしている必要があります。 このモジュールでPostgreSQLを設定している場合は、 当然条件を満たした状態になっていますが、PostgreSQL自体は別途インストールしている場合は 注意が必要です。

    • PostgreSQLの設定ファイルpg_hba.confで、 ローカルからpostgresユーザからの接続は 認証なしで接続できるようにする。
      local   all         postgres                          ident  
      
    • postgresqlユーザでpsql実行する。 psqlコマンドの引数には、--no-passwordオプションをつけてパスワードを聞かれないようにする。
      psql --no-password --tuples-only --quiet --dbname $db"
      

    2013-02-22

    _ Puppetlabs PostgreSQLモジュールの最新版2.1.0が出ていた

    ちょうどPuppetlabsのPostgreSQLの紹介記事 「puppetlabs-postgresqlモジュールはDB内の管理までできる」 「puppetlabs-postgresqlモジュールの裏側」 を書いたタイミングで、新しいバージョン2.1.0がリリースされました。

    PuppetDBのバックエンドでPostgreSQLを使用していることもあり、 色々進化しているようです。まだ使っていないですが、ぱっと見たところ、以下の変化が目につきました。

    • クライアントのインストールは、postgresqlクラスからpostgresql::clientになった。 postgresqlクラスは、postgresqlモジュール全体の設定クラスになった。
    • JDBCドライバをインストールするクラスpostgresql::javaが追加になった。