Perlでansibleライブラリを作成する方法

October 4,2023 11:55 PM
Category:[Perl, ansible]
Tag:[ansible, Perl]
Permalink

Perlでansibleライブラリを作成する方法を紹介します。

1.問題点

ansibleのシナリオを作成する中で、既存のansibleライブラリに存在しない処理をする必要が生じました。

が、ライブラリの作り方がわかりません。

具体的には、

  • 配置場所
  • 引数の送受信
  • 返却値の送受信

です。

ということで、Perlでansibleライブラリを作成する方法を紹介します。

ここではPerlで説明していますが、他の言語にも応用できると思います。

2.ansibleのディレクトリ構造

本題に入る前に、サンプルとして使用するansibleシナリオのディレクトリ構造を示します。

複雑ですいませんが、ansibleのベストプラクティスで記載しています。

ansible実行ディレクトリ/
  inventory
  send_user_password.yml
  roles/
    send_user_password/
      tasks/
        main.yml
      files/
        lib.tar.gz perlで使用するライブラリ
  library/
    send_user_password Perlスクリプト

このansibleシナリオの実行方法は下記です。

$ cd ansible実行ディレクトリ
$ ansible-playbook -i inventory send_user_password.yml

これで、roles/send_user_password/tasks/main.ymlが動作します。

そして、main.ymlの中でライブラリを使用します。

ansibleライブラリは"library"が該当します。詳細については後述します。

ここでは、ライブラリ以外の、各ファイルの内容を示します。

設定内容は環境に合わせてて適宜修正してください。

inventory

server_00 ansible_host=192.168.0.123
 
[all:vars]
ansible_user=root
ansible_ssh_pass=hogehoge
 
[server1]
server_00

send_user_password.yml

- hosts: server1
  roles:
    - role: send_user_password
      vars:
        work_path: "/tmp"

main.yml

- name: "Perlライブラリ転送"
  unarchive:
    src: lib.tar.gz
    dest: "{ work_path }"
 
- name: ユーザ・パスワード送信
  send_user_password:
    user: test
    password: hoge
  register: result
 
- name: "結果出力"
  debug:
    msg: "{{ result }}"

3.ライブラリ用Perlスクリプトのサンプル

Perlスクリプトのサンプル(send_user_password)を下記に示します。

このスクリプトは、受信した引数をそのまま返却するだけのものです。

#!/usr/bin/perl
 
use lib '/tmp/lib';
 
my $file = shift(@ARGV);
open( my $fh, "<", $file );
my $contents = do { local $/; <$fh> };
 
my @content = split( /\s/, $contents );
 
my $user;
my $password;
for my $data ( @content ) {
    my @tmp1 = split( /user=/, $data );
    if ( $tmp1[1] ) {
        $user = $tmp1[1];
    }
    my @tmp2 = split( /password=/, $data );
    if ( $tmp2[1] ) {
        $password = $tmp2[1];
    }
}
 
if ( !$user || !$password ) {
    print "{ \"msg\" : \"illegal parameter\", \"rc\" : 0, \"changed\" : \"false\", \"failed\" : \"1\" }";
    exit;
}
 
print "{ \"msg\" : \"OK\", \"user\" : \"$user\", \"password\" : \"$password\", \"rc\" : 0, \"changed\" : \"false\" }";

4.ライブラリの実行

まず、ansibleシナリオに記述した"send_user_password"が、そのままライブラリの実行ファイル名になります。

ansible実行ディレクトリ直下にlibraryディレクトリを配置することで、その配下のスクリプトがライブラリとして自動認識されます。

なお、このansibleのサンプルのライブラリ"send_user_password"は、ターゲットサーバに転送されて実行されます。

必要なライブラリがターゲットサーバに存在しない場合、ライブラリをlib.tar.gz等のファイル名でアーカイブして、roles/send_user_password/files/に配置し、unarchiveモジュールでターゲットサーバに転送・展開します。

- name: "Perlライブラリ転送"
  unarchive:
    src: lib.tar.gz
    dest: "{ work_path }"

展開されたPerlライブラリは、Perlスクリプト内のlibモジュールで追加して利用します。

use lib '/tmp/lib';

5.ライブラリの引数

send_user_passwordの引数となるuserとpassword(のキーと値)は、ファイルとして保存され、そのファイル名がPerlスクリプトに渡されます。

- name: ユーザ・パスワード送信
  send_user_password:
    user: test
    password: hoge
  register: result

サンプルの場合、ファイルの中身は次のようになるはずです。

user=test password=hoge

下記に引数を取得するサンプルを示します。

# 引数としてファイル名を取得
my $file = shift(@ARGV);
 
# ファイルオープン
open( my $fh, "<", $file );
 
# 中身をすべで取得
my $contents = do { local $/; <$fh> };
 
# 半角スペースで分割
my @content = split( /\s/, $contents );
 
# 引数を取得
my $user;
my $password;
for my $data ( @content ) {
    my @tmp1 = split( /user=/, $data );
    if ( $tmp1[1] ) {
        $user = $tmp1[1];
    }
    my @tmp2 = split( /password=/, $data );
    if ( $tmp2[1] ) {
        $password = $tmp2[1];
    }
}

6.ライブラリの返却値

返却値はJSON形式です。ダブルクォーテーション等にはエスケープが必要です。

ここでは受信した引数をそのまま返却しています。

print "{ \"msg\" : \"OK\", \"user\" : \"$user\", \"password\" : \"$password\", \"rc\" : 0, \"changed\" : \"false\" }";

サンプルのansibleでは、受信した返却値を変数resultに保存し、出力するようにしています。

- name: ユーザ・パスワード送信
  send_user_password:
    user: test
    password: hoge
  register: result
 
- name: "結果出力"
  debug:
    msg: "{{ result }}"

個別に出力したい場合は、result.userやresult.passwordとします。

Comments [0] | Trackbacks [0]

cpanflute2でエラーになる場合の対処

October 2,2023 11:55 PM
Category:[Linux]
Tag:[Linux, Perl]
Permalink

cpanflute2でエラーになる場合の対処方法を紹介します。

1.問題点

cpanflute2コマンドを実行したところ、下記のエラーが発生しました。

# cpanflute2
Unescaped left brace in regex is illegal here in regex; marked by <-- HERE in m/\$options{ <-- HERE '?(.*?)'?}/ at /usr/local/bin/cpanflute2 line 353.

ということで、cpanflute2でエラーになる場合の対処方法を紹介します。

2.原因と対処

cpanflute2が新しいPerlの仕様に追従できていないようです。

/usr/local/bin/cpanflute2を開いて、353行目を次のように修正します。

変更前

$inst =~ s/\$options{'?(.*?)'?}/$options{$1} || ''/ge;

変更後

$inst =~ s/\$options\{'?(.*?)'?\}/$options{$1} || ''/ge;

再度実行してエラーが出なければOKです。

Comments [0] | Trackbacks [0]

perlのCPANモジュールからRPMを作成する方法

September 29,2023 11:55 PM
Category:[Perl]
Tag:[Linux, Perl]
Permalink

perlのCPANモジュールからRPMを作成する方法を紹介します。

1.rpm-rebuildのインストール

rpmrebuildコマンドが使える必要があるので、事前にインストールしてください。

# yum install rpm-build

yum等でインストールできない場合は、rpmパッケージでインストールしてください。

# rpm -ivh rpm-build-4.14.3-13.el8.x86_64.rpm

2.perl-RPM-specfileのインストール

作業で利用するコマンドは「cpanflute2」ですが、これが含まれているPerlモジュール「perl-RPM-specfile」をインストールします。

# yum --enablerepo=rpmforge -y install perl-RPM-Specfile

yum等でインストールできない場合は、CPANからアーカイブをダウンロードしてビルドします。

https://metacpan.org/pod/RPM::Specfile

の左側にある「Download」のリンクをクリック。

ダウンロードしたアーカイブを展開して、下記のコマンドを実行すればインストール完了です。

# perl Makefile.PL
# make
# make install

3.RPM作成用のディレクトリ作成

下記の構造になるようにディレクトリを作成します。

/home/foo/rpmbuild/
  BUILD
  BUILDROOT
  RPMS
  SOURCES
  SPECS
  SRPMS<

このディレクトリ構成はrpmbuildコマンドで利用するケースを想定していますが、cpanflute2で使うのは、

  RPMS
  SOURCES
  SRPMS

だけと思われます。

4.CPANからtar.gzをダウンロード

CPANなどからRPMを作成したいアーカイブ(tar.gz)をダウンロードし、そのままSOURCESディレクトリに配置します。

以下、RPMパッケージ作成方法が2パターンあるので、どちらかで実行してください。

5.RPMの作成(その1)

こちらは一気にRPMパッケージを作成する方法です。

# cd SOURCES
# cpanflute2 --buildall xxx.tar.gz

生成されたRPMはRPMSディレクトリに配置されます。

7.RPMの作成(その2)

こちらはSRPMパッケージを作成し、そこからRPMパッケージを作成します。

# cd SOURCES
# cpanflute2 xxx.tar.gz

実行例

$ cpanflute2 pg-rex_operation_tools-13.1.tar.gz
書き込み完了: /home/foo/rpmbuild/SRPMS/perl-pg-rex_operation_tools-13.1-8.src.rpm
実行中(--clean): /bin/sh -e /var/tmp/rpm-tmp.ZcWANz
+ umask 022
+ cd /home/foo/rpmbuild/BUILD
+ rm -rf pg-rex_operation_tools-13.1
+ exit 0
$

rpmrebuildコマンドでSRPMパッケージからRPMを生成します。生成されたRPMはRPMSディレクトリに配置されます。

# cd ../SRPM
# rpmbuild --rebuild xxx.tar.gz

実行例

$ rpmbuild --rebuild perl-pg-rex_operation_tools-13.1-8.src.rpm
perl-pg-rex_operation_tools-13.1-8.src.rpm をインストール中です。
実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.4vM3NV
+ umask 022
+ cd /home/foo/rpmbuild/BUILD
+ cd /home/foo/rpmbuild/BUILD
+ rm -rf pg-rex_operation_tools-13.1
+ /usr/bin/gzip -dc /home/foo/rpmbuild/SOURCES/pg-rex_operation_tools-13.1.tar.gz
+ /usr/bin/tar -xof -
+ STATUS=0
+ '[' 0 -ne 0 ']'
+ cd pg-rex_operation_tools-13.1
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
実行中(%build): /bin/sh -e /var/tmp/rpm-tmp.XRsSgT
+ umask 022
+ cd /home/foo/rpmbuild/BUILD
+ cd pg-rex_operation_tools-13.1
+ CFLAGS='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
+ /usr/bin/perl Makefile.PL
Checking if your kit is complete...
Warning: the following files are missing in your kit:
        lib.in/command-rhel6.pm
        lib.in/command-rhel7.pm
Please inform the author.
Warning: prerequisite IO::Tty 1.11 not found.
Warning: prerequisite Net::OpenSSH 0.62 not found.
Warning: NAME must be a package name
Generating a Unix-style Makefile
Writing Makefile for pg-rex_operation_tools
+ make -j4 'OPTIMIZE=-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection'
Skip lib/PGRex/common.pm (unchanged)
Skip lib/PGRex/command.pm (unchanged)
Skip lib/PGRex/Po/ja.pm (unchanged)
Skip lib/PGRex/Po/en.pm (unchanged)
+ exit 0
実行中(%install): /bin/sh -e /var/tmp/rpm-tmp.xO4smU
+ umask 022
+ cd /home/foo/rpmbuild/BUILD
+ '[' /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64 '!=' / ']'
+ rm -rf /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64
++ dirname /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64
+ mkdir -p /home/foo/rpmbuild/BUILDROOT
+ mkdir /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64
+ cd pg-rex_operation_tools-13.1
+ rm -rf /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64
+ make pure_install PERL_INSTALL_ROOT=/home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/bin/pg-rex_archivefile_delete
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/bin/pg-rex_primary_start
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/bin/pg-rex_standby_start
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/bin/pg-rex_stop
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/bin/pg-rex_switchover
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/share/perl5/PGRex/common.pm
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/share/perl5/PGRex/command.pm
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/share/perl5/PGRex/Po/en.pm
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/share/perl5/PGRex/Po/ja.pm
Installing /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/share/man/man1/pg-rex_tools_manual-ja.html
+ find /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64 -type f -a '(' -name perllocal.pod -o -name .packlist -o '(' -name '*.bs' -a -empty ')' ')' -exec rm -f '{}' ';'
+ find /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64 -type d -depth -exec rmdir '{}' ';'
+ chmod -R u+w /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr
+ for brp in /usr/lib/rpm/redhat/brp-compress /usr/lib/rpm/brp-compress
+ '[' -x /usr/lib/rpm/redhat/brp-compress ']'
+ for brp in /usr/lib/rpm/redhat/brp-compress /usr/lib/rpm/brp-compress
+ '[' -x /usr/lib/rpm/brp-compress ']'
+ /usr/lib/rpm/brp-compress
+ break
+ find /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64 -type f
+ sed 's@^/home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64@@g'
++ /usr/bin/perl -V:archname -V:installsitelib -V:installvendorlib -V:installprivlib
+ eval 'archname='\''x86_64-linux-thread-multi'\'';' 'installsitelib='\''/usr/local/share/perl5'\'';' 'installvendorlib='\''/usr/share/perl5/vendor_perl'\'';' 'installprivlib='\''/usr/share/perl5'\'';'
++ archname=x86_64-linux-thread-multi
++ installsitelib=/usr/local/share/perl5
++ installvendorlib=/usr/share/perl5/vendor_perl
++ installprivlib=/usr/share/perl5
+ for d in $installsitelib $installvendorlib $installprivlib
+ '[' -z /usr/local/share/perl5 -o /usr/local/share/perl5 = UNKNOWN -o '!' -d /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/share/perl5 ']'
+ find /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/local/share/perl5/PGRex -type d
+ grep -v '/x86_64-linux-thread-multi\(/auto\)\?$'
+ sed 's@^/home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64@%dir @g'
+ for d in $installsitelib $installvendorlib $installprivlib
+ '[' -z /usr/share/perl5/vendor_perl -o /usr/share/perl5/vendor_perl = UNKNOWN -o '!' -d /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/share/perl5/vendor_perl ']'
+ continue
+ for d in $installsitelib $installvendorlib $installprivlib
+ '[' -z /usr/share/perl5 -o /usr/share/perl5 = UNKNOWN -o '!' -d /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/share/perl5 ']'
+ continue
++ cat perl-pg-rex_operation_tools-13.1-8-filelist
+ '[' '/usr/local/bin/pg-rex_archivefile_delete
/usr/local/bin/pg-rex_primary_start
/usr/local/bin/pg-rex_standby_start
/usr/local/bin/pg-rex_stop
/usr/local/bin/pg-rex_switchover
/usr/local/share/man/man1/pg-rex_tools_manual-ja.html
/usr/local/share/perl5/PGRex/Po/en.pm
/usr/local/share/perl5/PGRex/Po/ja.pm
/usr/local/share/perl5/PGRex/common.pm
/usr/local/share/perl5/PGRex/command.pm
%dir /usr/local/share/perl5/PGRex
%dir /usr/local/share/perl5/PGRex/PoX' = X ']'
+ /usr/lib/rpm/find-debuginfo.sh -j4 --strict-build-id -m -i --build-id-seed 13.1-8 --unique-debug-suffix -13.1-8.x86_64 --unique-debug-src-base perl-pg-rex_operation_tools-13.1-8.x86_64 --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 -S debugsourcefiles.list /home/foo/rpmbuild/BUILD/pg-rex_operation_tools-13.1
+ /usr/lib/rpm/check-buildroot
+ /usr/lib/rpm/redhat/brp-ldconfig
/sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /etc/ld.so.conf: No such file or directory
+ /usr/lib/rpm/brp-compress
+ /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip
+ /usr/lib/rpm/brp-python-bytecompile '' 1
+ /usr/lib/rpm/brp-python-hardlink
+ PYTHON3=/usr/libexec/platform-python
+ /usr/lib/rpm/redhat/brp-mangle-shebangs
ファイルの処理中: perl-pg-rex_operation_tools-13.1-8.noarch
実行中(%doc): /bin/sh -e /var/tmp/rpm-tmp.WydlKS
+ umask 022
+ cd /home/foo/rpmbuild/BUILD
+ cd pg-rex_operation_tools-13.1
+ DOCDIR=/home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/share/doc/perl-pg-rex_operation_tools
+ export LC_ALL=C
+ LC_ALL=C
+ export DOCDIR
+ /usr/bin/mkdir -p /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/share/doc/perl-pg-rex_operation_tools
+ cp -pr LICENSE /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64/usr/share/doc/perl-pg-rex_operation_tools
+ exit 0
Provides: perl-pg-rex_operation_tools = 13.1-8
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
パッケージに含まれないファイルの検査中: /usr/lib/rpm/check-files /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64
書き込み完了: /home/foo/rpmbuild/RPMS/noarch/perl-pg-rex_operation_tools-13.1-8.noarch.rpm
実行中(%clean): /bin/sh -e /var/tmp/rpm-tmp.69jKHS
+ umask 022
+ cd /home/foo/rpmbuild/BUILD
+ cd pg-rex_operation_tools-13.1
+ rm -rf /home/foo/rpmbuild/BUILDROOT/perl-pg-rex_operation_tools-13.1-8.x86_64
+ exit 0
実行中(--clean): /bin/sh -e /var/tmp/rpm-tmp.IFjryT
+ umask 022
+ cd /home/foo/rpmbuild/BUILD
+ rm -rf pg-rex_operation_tools-13.1
+ exit 0
$
Comments [0] | Trackbacks [0]
 1  |  2  |  3  |  4  |  5  | All pages