SOURCE POD Blog ソースポッドブログ

Ansible Role Degoss を Python2/3 に対応させた話

はじめに

本ブログを読んでいただいてありがとうございます。
情報システム部所属のエンジニア MKです。

現在、プロジェクトにおいて Degoss (ansible-role-degoss) (以下、Degoss)というツールを利用・検証しています。
Python で記述されたツールですが、Python3には対応していないため、その調整を行なった話をしたいと思います。

TL;DR

本家の Degoss は 2020/3/12 のコミットを最後にメンテナンスが停止しています。
Python3 対応の修正パッチのプルリクエストが提出されていますがマージされていません。

asciifaceman さんが fork したプロジェクトに Python3対応パッチを適用した bugfix/corbett-bytestostring ブランチがありますが、今回は諸事情により Python2 でも Python3 でも動作させる必要があったため、独自に fork を行い Degossハイブリッド版 を作成することとなりました。

Ansible Galaxy の requirements.yml に、以下のように記載することで利用することができます。


# degoss - Python2/3 support
- src: https://github.com/pettyconan/ansible-role-degoss.git
  version: bugfix/corbett-bytestostring
  name: naftulikay.degoss

サーバー構築の自動化とテスト

私の部門では Ansible によるサーバー構築の自動化を推進してます。 当然、構築したサーバーは本当に正しい状態になっているのか検証(テスト)する必要があります。
サーバーのテストツールとしては Serverspec が有名ですが、RSpec というカスタマイズされた Ruby 言語で記述する必要があることと、実行速度が遅いという難点があり、Go言語で記述された Goss という代替ツールが良さそうだったので、検証をはじめました。

YAMLによる記述も理解しやすく、なかなか良さげです。

サーバのテストを実行するのであれば、構築用の Ansible に統合したい、ということで調べたところ、goss-ansibleansible-role-degoss というものがありました。  goss-ansible は Ansible のタスクとして動作し、ansible-role-degoss は Ansible のロールとして動作するという違いがあります。 さらに ansible-role-degoss は、テスト完了後にはクリーンアップが行われ、「サーバの環境を汚さない」 のが特徴で大きな魅力を感じたため、こちらを採用しました。

Degoss とはなにか?

Degoss とは Goss によるサーバテストを Ansible から実行するためのラッパーです。

Goss とはなにか?

サーバの設定を検証するためのYAMLベースの Serverspec 代替ツールです。
YAMLという書式を用いてサーバのあるべき状態を記述し、実際に対象サーバがその状態になっていることを検証することができます。

YAML(Gossfile)記述例


port:
  tcp:22:
    listening: true
    ip:
    - 0.0.0.0
  tcp6:22:
    listening: true
    ip:
    - '::'
service:
  sshd:
    enabled: true
    running: true
user:
  sshd:
    exists: true
    uid: 74
    gid: 74
    groups:
    - sshd
    home: /var/empty/sshd
    shell: /sbin/nologin
group:
  sshd:
    exists: true
    gid: 74
process:
  sshd:
    running: true

Python3 で動かない、そして、Degoss はもうメンテナンスされていない、だと!?

かなりの苦労と試行錯誤の末、どうにか構築用の Ansible に Goss のテストを統合することができそうです。
これについてはまた別の機会に記事にしたいと思います。

最初は何の問題もなく利用できており、いい感じだなととても満足していましたが、新環境の構築の検証をはじめた時に悲劇は起こりました。
Goss のテストを実行しようとすると Ansible でエラーが発生して動作しません...
エラーの内容は Python の構文エラーで、調べてみると新環境ではデフォルトでインストールされる Python がv3系であり、これが原因であることが判明しました。

本家 のプロジェクトを確認しみると、Python3 対応の修正パッチのプルリクエストが提出されているもののマージされていません。
2020/3/12 のコミットを最後にメンテナンスが停止していました。なんと!
OSS(オープンソース)のプロジェクトは大変便利なのですが、こういうこともあるあるですよね...

さて、困ったものだとGitHubを調べてみると、このプロジェクトの fork がいくつかあり、その中の1つ asciifaceman さんが fork したプロジェクトに、Python3対応パッチを適用した bugfix/corbett-bytestostring ブランチがありました! 世界中には誰かしら同じことを考えて、しかも先行して対応している方がいらっしゃるものです。OSS万歳!

Python2 と 3 への対応

これで解決か...と思いきや、当然ですが今度は Python2 の環境で動作しません... 今回は新旧の環境の比較を行いたいため、古いOSの Python2 環境でも動作してもらわないと困るのです。
最初は実行ターゲットに合わせて都度ライブラリを切り替えて対応していましたが、これが面倒極まりないです。 GitHub を漁りながら、どうしたものかと悩んだ挙げ句、自分で fork してパッチを当てることにしました。

幸い、修正箇所は2箇所だけです。
ただ、Python2/3 共通で動作する記述はできない修正であったため、ベタですが、


    if sys.version_info.major < 3:
        // Python2 の処理
    else
        // Python3 の処理  

というパッチを当てて対応しました。

独自に fork した拡張機能を Ansible で参照する場合は Ansible Galaxy の requirements.yml に、以下のように記載することで利用できます。


# degoss - Python2/3 support
- src: https://github.com/pettyconan/ansible-role-degoss.git
  version: bugfix/corbett-bytestostring
  name: naftulikay.degoss

src でリポジトリのURLを指定し、version でブランチを指定します。
最後に name でAnsible側で参照する名前(本家のプラグイン名)を記述します。

これで無事、Python 2/3 それぞれの環境で動作するようになりました。

さいごに

オープンソースは大変有用で色々とお世話になっていますが、プロジェクトをメンテナンスし続けるには労力を含めたコストがかかります。
メンテナンスされずに放置されてしまうプロジェクトも少なくなく、リスクが大きすぎるので大抵は利用そのものを諦めますが、今回は代用できるものがなかったことと、内部ツールであるためにバグやセキュリティ等のリスクがほぼ無視できるため、必要に応じて自分でメンテナンスする選択をしました。

ですが、そもそもは素晴らしいコンセプトの本家プロジェクトを作成していただいた naftulikay さんをはじめ、本家プロジェクトを支えてくれた方々、本家のメンテナンスが停止しても fork して独自にメンテナンスをされている方々など、オープンソースコミュニティへの感謝を忘れずに、自分が fork したプロジェクトは自己責任で利用していきたいと思います。

関連リンク

SOURCE POD Blog一覧へ戻る