Jeen - Yet anothere techlog

STFUAWSC

A Usecase of App::Fatpacker - Nagios Plugin

최근 업무때문에 Nagios Plugin 을 만져야 하는 일들이 빈번하게 있었고, 앞으로도 발생할 소지가 상당히 높습니다. 이런 Nagios Plugin 을 만들거나 기존에 만들어 진 것들을 간편하게 다른 복수의 서버에 배포하는 일도 필요합니다.

Nagios Plugin 이야 굳이 언어를 가리지 않는다고 치더라도, 언어의 특정 라이브러리에 의존을 가지는 경우가 많습니다. MongoDB 용 Nagios Plugin 에는 Python 의 pymongo 라이브러리를 설치해야하는 경우가 있지요.

일례로 Redis 용 Nagios Plugin 을 설치할 시에는 Redis CPAN 모듈을 필요로 합니다. 그런데 Redis 서버가 여러대이고, 이 여러대의 서버에 매번 Redis 모듈을 깔고, Redis 모니터링용 Nagios Plugin 도 설치를 해야하는 경우가 있습니다. 그냥 뭐 시간을 좀 허비해서라도 그렇게 번거로운 일을 하면 일이야 끝나겠지만, 현인(@aer0 님)의 조언을 빌어서 App::FatPacker 를 사용해서 단일 스크립트에 우겨넣는 방향으로 돌리도록 합니다.

우선은 App::FatPacker 를 설치하면 fatpack 이라는 커맨드를 사용할 수 있습니다.

Nagios Exchange 에서 찾아낸 check_redis 중에 check_redis.pl 파일이 위에 말한대로 Redis 모듈에 의존이 걸린 상황입니다.

그럼 우선 fatpack 커맨드로 다음과 같이 입력을 합니다.

bash $ fatpack trace check_redis.pl check_redis.pl syntax OK

결과 syntax OK 가 뜨고 해당 디렉토리에 fatpacker.trace 라는 파일이 생성됩니다.

bash $ cat fatpacker.trace IO/Handle.pm List/Util.pm Getopt/Long.pm SelectSaver.pm IO/Socket.pm Fcntl.pm Text/ParseWords.pm Symbol.pm Scalar/Util.pm IO/Socket/INET.pm Errno.pm fields.pm warnings/register.pm Encode/Alias.pm Time/HiRes.pm Encode/Config.pm Encode/Encoding.pm Redis.pm Encode.pm base.pm Config.pm IO.pm IO/Socket/UNIX.pm Carp.pm bytes.pm Exporter/Heavy.pm vars.pm constant.pm Socket.pm Try/Tiny.pm IO/Select.pm overload.pm lib.pm DynaLoader.pm Data/Dumper.pm

내용을 보면 말 그대로 해당 모듈이 가지고 있는 의존 모듈이 좌르르륵 표시됩니다. 물론 걔중에는 Core 모듈도 있기도 합니다.

일단 App::FatPacker SYNOPSIS 대로 진행을 해보면…

bash $ fatpack packlists-for cat fatpacker.trace > packlists

위 결과로 생긴 packlists 는 파일은 다음과 같은 내용을 가집니다.

bash $ cat packlists /home/jeen/perl5/perlbrew/perls/perl-5.14.0/lib/5.14.0/x86_64-linux-thread-multi/auto/Time/HiRes/.packlist /home/jeen/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux-thread-multi/auto/Redis/.packlist /home/jeen/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux-thread-multi/auto/Try/Tiny/.packlist

각 의존 모듈 위치에 맞춰서 .packlist 파일이 생성되고, 그 내용은…

bash $ cat /home/jeen/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux-thread-multi/auto/Redis/.packlist /home/jeen/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/Redis.pm /home/jeen/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/Redis/Hash.pm /home/jeen/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/Redis/List.pm /home/jeen/perl5/perlbrew/perls/perl-5.14.0/man/man3/Redis.3 /home/jeen/perl5/perlbrew/perls/perl-5.14.0/man/man3/Redis::Hash.3 /home/jeen/perl5/perlbrew/perls/perl-5.14.0/man/man3/Redis::List.3

위와 같습니다.

그리고 다음 커맨드를 입력해봅니다.

bash $ fatpack tree cat packlists

그 결과 현재 디렉토리에서 fatlib 이라는 디렉토리가 생성되고 그 안에 관련 의존모듈들이 복사됩니다.

bash $ tree … ├── fatlib │   ├── Redis │   │   ├── Hash.pm │   │   └── List.pm │   ├── Redis.pm │   ├── Try │   │   └── Tiny.pm │   └── x86_64-linux-thread-multi │   ├── Time │   │   └── HiRes.pm │   └── auto │   └── Time │   └── HiRes │   ├── HiRes.bs │   └── HiRes.so …

그럼 다음 커맨드를 입력해보면…

bash $ (fatpack file; cat check_redis.pl ) > check_redis.packed.pl Can’t stat /home/jeen/fp/tt/lib: 그런 파일이나 디렉터리가 없습니다 at /home/jeen/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/App/FatPacker.pm line 200 BEGIN failed—compilation aborted at /home/jeen/perl5/perlbrew/perls/perl-5.14.0/bin/fatpack line 3.

제대로 동작하지 않습니다. 에러가 발생하네요. 정답은 에러메시지에 있습니다. App::FatPacker 자체는 Perl Library 규칙에 정형화된 디렉토리 구조를 가정하고 있습니다. 즉 lib 디렉토리가 존재하지 않기 때문에 발생하는 것이죠. 뭐 물론 다운받은 check_redis.pl 파일 하나만 있는 데 lib 디렉토리를 가지고 뭐 더 넣고 자시고 할 것도 아닌데…, 그래도 뭐 일단 사태해결을 위해서 아무것도 없어도 그냥 lib 디렉토리 하나는 만들어 줍니다.

그리고 다시 실행해보면 check_redis.packed.pl 이라는 파일이 생성됩니다.

~~~ perl # This chunk of stuff was generated by App::FatPacker. To find the original # file’s code, look for the end of this BEGIN block or the string ‘FATPACK’ BEGIN { my %fatpacked;

$fatpacked{“Redis.pm”} = <<‘REDIS’; package Redis;

# ABSTRACT: Perl binding for Redis database our $VERSION = ‘1.955’; # VERSION our $AUTHORITY = ‘cpan:MELO’; # AUTHORITY … ~~~

일단 Nagios Plugin 은 기본 실행권한을 가지는 파일로 해두는 것이 여러모로 편합니다. 한가지 주의할 점은 일단 위처럼 생성된 파일에서 shebang line 이 존재하지 않기때문에 shebang line 을 추가해주면 됩니다. :–)

perl #!/usr/bin/env perl

위의 내용을 check_redis.packed.pl 파일의 첫째줄에 추가해줍니다.

그리고 완성된 파일들을 Redis 서버에 붙여서 check_nrpe 등으로 동작을 확인하고 설정에 추가하는 것으로 관련된 작업은 끝이 났습니다.

파일 중앙배포와 관련해서도 다양한 이슈가 있지만 이에 관련해서는 추후 Rex 를 다루면서 이야기를 계속할 까 합니다.

다 쓰고 나서 검색을 해보니 예전에 @aer0 님께서 작성하신 블로그 기사가 있군요.

덩달아서 같이 참고하시면 좋을 것 같습니다.

Comments