sosreportの取得内容

# 調べた背景
* Pythonの勉強題材としてとっかかりやすかったので
* 知りたがっていた人がいたので
* ここの方が詳しいです
<pre>
https://github.com/sosreport/sos/wiki/
</pre>

# sosreportとは
* Linuxが稼働するシステムの設定ファイルやコマンド結果などをアーカイブするツール
* OSサポートなどに問い合わせすると調査にあたって取得を依頼されることがある

# sosreportの実装
* 言語はPython
* 設定ファイルやコマンド結果を取得する実装はプラグインとしてモジュール化されている
* プラグインは配布されているものを追加したり自身で実装して追加することも可能

# プラグインの格納先
* sos-3.3-5の場合
<pre>
/usr/lib/python2.7/site-packages/sos/plugins
</pre>

# プラグインの実装
* 主にプラグイン用に用意されたモジュールを利用して実装する
* メソッド名から何をしている処理かは何となく察しがつく

# 例：yumプラグインのソース

```python:yum.py
from sos.plugins import Plugin, RedHatPlugin


class Yum(Plugin, RedHatPlugin):
    """yum information
    """

    plugin_name = 'yum'
    profiles = ('system', 'packagemanager', 'sysmgmt')

    files = ('/etc/yum.conf',)
    packages = ('yum',)

    option_list = [
        ("yumlist", "list repositories and packages", "slow", False),
        ("yumdebug", "gather yum debugging data", "slow", False)
    ]

    def setup(self):
        # Pull all yum related information
        self.add_copy_spec([
            "/etc/yum",
            "/etc/yum.repos.d",
            "/etc/yum.conf",
            "/var/log/yum.log"
        ])

        # Get a list of channels the machine is subscribed to.
        self.add_cmd_output("yum -C repolist")

        # candlepin info
        self.add_forbidden_path("/etc/pki/entitlement/key.pem")
        self.add_forbidden_path("/etc/pki/entitlement/*-key.pem")
        self.add_copy_spec([
            "/etc/pki/product/*.pem",
            "/etc/pki/consumer/cert.pem",
            "/etc/pki/entitlement/*.pem"
        ])
        self.add_cmd_output("yum history")

        if self.get_option("yumlist"):
            # List various information about available packages
            self.add_cmd_output("yum list")

        if self.get_option("yumdebug") and self.is_installed('yum-utils'):
            # RHEL6+ alternative for this whole function:
            # self.add_cmd_output("yum-debug-dump '%s'"
            # % os.path.join(self.commons['dstroot'],"yum-debug-dump"))
            r = self.call_ext_prog("yum-debug-dump")
            try:
                self.add_cmd_output("zcat %s" % (r['output'].split()[-1],))
            except IndexError:
                pass
```

* plugin_name
プラグインの名前

* profiles
-p (--profile) NAME を指定してsosreportを実行した場合に、NAMEに指定した値がprofilesに指定されていると、そのプラグインが実行される。
なお、どのプラグインが何のprofilesを持っているかは、sosreport --list-profilesで確認可能。

* files, packages
filesに指定されたファイルが存在する、もしくはpackagesに指定されたパッケージがインストールされている場合、デフォルトではプラグインが有効になる。プラグインの有効・無効はオプションで切り替え可能。

* option_list
プラグインに指定できるオプション
左からオプション名、オプションの説明(sosreport -lで確認可)、fast or slow(ソースをgrepした限り今は使われているパスは無い。この項目自体の削除が提案されている)、デフォルトの有効・無効。

* setupメソッド
必須
sosreportは各プラグインが持つsetupメソッドをループしている(sosreport.pyの1247行目あたり)。

```python:sosreport.py
1240     def setup(self):
1241         msg = "[%s:%s] executing 'sosreport %s'"
1242         self.soslog.info(msg % (__name__, "setup", " ".join(self._args)))
1243         self.ui_log.info(_(" Setting up plugins ..."))
1244         for plugname, plug in self.loaded_plugins:
1245             try:
1246                 plug.archive = self.archive
1247                 plug.setup()
1248             except KeyboardInterrupt:
1249                 raise
1250             except (OSError, IOError) as e:
1251                 if e.errno in fatal_fs_errors:
1252                     self.ui_log.error("")
1253                     self.ui_log.error(" %s while setting up plugins"
1254                                       % e.strerror)
1255                     self.ui_log.error("")
1256                     self._exit(1)
1257                 if self.raise_plugins:
1258                     raise
1259                 self._log_plugin_exception(plugname, "setup")
1260             except:
1261                 if self.raise_plugins:
1262                     raise
1263                 self._log_plugin_exception(plugname, "setup")
```

* add_copy_specメソッド
ファイルをコピーして取得する。

* add_cmd_outputメソッド
コマンドの実行結果を取得する。

* add_forbidden_pathメソッド
指定したファイルを取得対象から除外する。

* get_optionメソッド
option_listに設定したプラグインのオプションが指定された場合にTrueを返す。

* is_installedメソッド
指定したパッケージがインストールされている場合にTrueを返す。

* call_ext_progメソッド
sosreportとは別プロセスでコマンドの実行結果を返す。

以上を纏めると、yumプラグインの実装は下記となる。

| 項目 | 内容 |
|:-----------|:------------|
|profiles|system<br>packagemanager<br>sysmgmt|
|有効となる条件|/etc/yum.confが存在する、もしくはyumパッケージインストール時|
|yumlistオプション|yum listコマンドの実行結果を取得する。デフォルト無効|
|yumdebugオプション|yum-debug-dumpコマンドが生成したアーカイブをzcatコマンドで参照した結果を取得する。デフォルトは無効|
|取得ファイル|/etc/yum<br>/etc/yum.repos.d<br>/etc/yum.conf<br>/var/log/yum.log<br>/etc/pki/product/\*.pem(\*1)<br>/etc/pki/consumer/cert.pem<br>/etc/pki/entitlement/\*.pem<br>/etc/pki/entitlement/key.pem<br>/etc/pki/entitlement/\*-key.pem<br>yum-debug-dumpコマンドが生成したアーカイブのzcatコマンドでの参照結果(*2)|
|取得コマンド|yum -C repolist<br>yum history<br>yum list(*3)<br>|

* *1 下記ファイルを除く
<pre>
/etc/pki/entitlement/key.pem
/etc/pki/entitlement/\*-key.pem
</pre>
* *2 yumdebugオプション有効かつyum-utilsパッケージインストール時のみ取得
* *3 yumlistオプション有効時のみ取得