私フィックスポイントの冨と申します。
Kompiraシリーズのエバンジェリストですとか、教育マーケ担当でございます。
本日のテーマは三つございまして、Kompira Enterpriseジョブフロー言語超入門ということで、これからジョブフローを作っていこうという方々に、どんな風にして実装していけばいいかというイメージを持っていただければと思います。
二つ目がジョブフロー言語の落とし穴ということで、セミナーをやっているなかで、皆さんがハマりやすいポイントがありますので、そういうところをご紹介していこうと思います。
最後は、知っていると便利な機能ということで、ジョブフロー言語の関数や機能などをご紹介します。
Part-1: Kompira Enterpriseのジョブフロー言語の超入門
まず最初はKompira Enterpriseのジョブフロー言語の超入門ということでお話しさせていただきます。
Kompira Enterpriseのジョブフロー言語には大きく三つ基本がございます。
一つ目はコマンド文字列をカッコで括るという書き方をします。通常をターミナルで打っている ps ですとかhostname とか、そういったコマンドを書いていただいて、かっこでくくるといった形で処理を書いていきます。
(二つ目は)そのコマンドの標準出力は、$RESULTという変数に格納されますので、例えばprintで出力したり、その出力するべき文字列をパースして次の処理につなげることをやって頂きます。
3つ目は、カッコで括った処理ですとかジョブフロー言語に用いられている標準関数を、処理と処理の間を矢印で繋ぐという表記をします。これも後で具体的にご紹介します。
皆さんが作業される際には手順書に従ってコマンドをターミナルに打ち込んでいくという形を取られると思うんですが、この手順書の例といたしまして、また自分のどういう環境で作業しているのかというのを確認する手順ですね、例えばdateコマンドだとかid、pwdで、現在のディレクトリはどこにいるかということを確認していくような手順になっています。
これをジョブフローにいたしますと、先ほど書きましたdateですとかidといったコマンドにつきましては、鍵括弧でくくっていくといった形でコマンドを記述していきます。
このdateコマンドの結果は$RESULTという変数に格納されますので、print関数でコンソールに表示するとか、この$RESULTの文字列の解析をして次の処理に繋げるとか、そういったことをやっています。
id、pwd、uname -aですとか、この形でコマンドを次々と書いていきますが、その鍵括弧付きのコマンドですとか標準関数ですとか、こういった一連の処理の間を矢印でつないでいくといった形、これがジョブフロー言語の特徴になっております。
この他のジョブフロー言語の特徴と致しましては、forとかwhileなどの繰り返し文がございます。同じような処理を複数台のマシンに適用するような場合。そういった場合は繰り返し処理を行ったり、if文を使って特定の作業を成功したか失敗したかというのを判定して、失敗した場合にはロールバック処理をさせるなどが可能です。
オブジェクトを利用した各種情報の確認とありますけれども、具体的には接続先ホストのIPアドレスとか認証情報とかを格納することができますし、例えばサーバーに含まれているモジュールとかパッチのバージョンですとか、そういうのを格納することができるようになっています。
またKompiraの標準言語に備わっている標準関数以外にも、Python言語を使ってライブラリを作ることが可能になっています。またそれぞれのジョブフローやオブジェクトにつきましてはLinuxライクなユーザー/グループによって参照権限、実行権限などを個別に付与することができるようになっています。
またKompira言語につきましては、今見ていただいた通りテキストベースでプログラムを書いていただくということになります。最近で言えばRPAツールのように、いわゆる部品をつなげてビジュアルプログラミングをされるような形は非常に増えているんですが、テキストベースでジョブフローを実装していくというメリットはございます。
エンジニア向けのもので、大体の人は何かプログラムを作ったことがあると思いますので、馴染みがあるツールかなと思います。一般的なプログラム方法論ということで、例えばdiffみたいな差分管理をしたり、gitを使ってリポジトリに登録したりだとか、プログラム開発の支援ツールが使えるということですね。
またネットワーク機器ですとか、サーバーOSのバージョン違いで微妙な挙動の差を起こすことがありますが、そういったところを全て吸収できるように細かく記述することができるようになっています。
Part-2: Kompiraジョブフローの落とし穴
2番目のテーマであるKompiraジョブフローの落とし穴として、5題ほど質問させて頂こうかなと思います。
一つ目、このジョブフローの何が問題でしょうかということで、print(“hello, world”) を四つ並べております。ジョブフロー言語を書かれている方はプログラムを書いた後保存ボタンを押して行きますけれども、保存ボタンを押した後でプログラムにバグがありますと、このようなSyntax Errorとかアラートが出てきます。今回もSyntax Errorが出てるんですけれども、これ一見すると普通に見えますよね。
なんで、ここでエラーが出ているんでしょうかという話になります。
この答えなんですけれども、全角スペースが混ざるとエラーを起こすということがございます。
例えばこのprint(“hello, world”) の後にスペースが空いてるんですけれども、全角のスペースが混ざってますとSyntax Error: Illegal characterで全角スペースがありますと表示されます。
全角スペースがありますと、一見よさげに見えるんですけれども、文法エラーということでSyntax error がでてきます。これは、矢印の間とかそういったところに使う分には問題なんですけれども、いわゆる文字列中の全角スペースとして使うには特に問題ございません 。
続いて2番目の問題でありますけれども、このジョブフロー何が問題でしょうか。
あるジョブフローから別のジョブフローを呼び出すような構文になっています。
その結果を見て if 文でステータスが0であればprint($RESULT)で、elseにしますとprint(“ERROR”)とするという形ですね。これもポイントがいくつかあるんですけれども、いかがでしょうか。
オブジェクト名の前に ./ や ../ が必要になります。これはジョブフローを呼び出す際にこういう風に同じように鍵括弧でくくって書いていくんですけれども、 ./ + 呼び出すジョブフローということで、同じディレクトリにジョブフローがあるという前提であります。
./ がない場合ですね。こんな形でジョブフローを書いていただきますと、一つ目の ./ 付きから呼び出すジョブフローは”Hello world”と出てくるんですけれども、2番目のジョブフローで./がない呼び出しをすると、実行時エラーが出てきます。(ジョブフロー名が)変数とみなされてエラーが起こっているという事になります。
ということで、Kompiraの中から別のオブジェクト(ジョブフローや色々なリソースがあります)を呼び出す際には ./ とか ../ または、トップディレクトリの / から始まる絶対パスの、いずれかの形で書いていただく必要がございます。
3番目の問題ですけれども、このジョブフロー何が問題でしょうかということですが、先ほどと同じようなジョブフローになっております。いかがでしょうか。
これの答えですが、オブジェクト名を “ で囲わないという制約がございます。
こちらも ./ +呼び出すジョブフローで、二番目に “ 付きで書いてありますけれども、同じ ./ 付きであるんですが、” 付きで書いてあげますと、2回目で実行する際に(エラーメッセージに) “While executing ./呼び出すジョブフロー”というような形で、” でくくるとコマンドとみなされてしまうということでエラーになってしまう。
ジョブフローから別のオブジェクトを参照させる場合、これは別のジョブフローを呼び出す場合もそうですし、別のノード情報ですとかアカウント情報、そういったオブジェクトを参照させる際には、まず ./ ですとか ../ ですとか絶対パスで単純に名前だけではなくて、階層を含めた形で書いてあげる必要がある。あと ” で括って文字列化しないということに、気をつけていただければと思います。
4番目になりますけれどもこのジョブフローの何が問題でしょうか。 pi = 3.1415、円周率を代入してプリントをします。単純なジョブフローですけれども何が問題でしょうか。
これの答えなんですけれども、実数の直接代入はできないという制限がございます。
今のジョブフローの例ですと、例えばpi = を “ でくくって ”3.1415” というふうに文字列化してあげますと、ここは特に問題なく表示されます。下のようにpi = 3.1415という形で普通の実数として代入しようとするとエラーになります。
これを強引にpi に文字列化した”3.1415” を float 関数で実数にキャストしてあげて、代入してあげると無事に表示されるといったところです。
print(pi) とprint(type(pi)) とありますけれども、これの型は何かという事です。これは3.1415と出てきますし、”float”という型がございます。変数自体に実数型の値を格納することは特に問題なくできるんですけれども、直接代入させようとするとエラーが出てきます。これはこのKompira言語のパーサーの問題でもあるんですが、こういった制約があることをご留意ください。
最後5問目になりますけれども、このジョブフローの何が問題でしょうかということで、param1 で数字の123、param2で文字列の”456”とあります。そして、print( param1 + param2) としています。
これの答えなんですけれども、型が違うものを演算ができないことで、例えばこのジョブフローなんですけれども、param1では123という数字で、param2が”123”という文字列代入したという想定です。
一つ目の型(type(param1))と二つ目の型(type(param2))。あと、param1+param2と、足し算した結果です。
それを見ますと1つ目はIntegerになります。二つ目はStringになってます。整数と文字列という型の異なる値を足し算すると “Failed to execute binary operation: unsupported operand type(s) for +: int and unicode”というエラーが表示されます。
こちらもどうしたらいいのという話なんですが、123と456という数字と文字なんですが、一つの解としましては、例えば整数にキャストしてあげるという手があります。例えば int という関数を使ってあげますと、それぞれ123、456が整数になりますので、123と456の足し算ということであれば579という風に出てきます。
それぞれを文字列として扱いたいという場合、例えば123という整数を123という文字列として扱う場合、その時は stringという関数を使ってあげると ”123” という文字列になります。文字列と文字列の + になりますので、文字列を結合するといった操作になります。 ”123456” と言った文字列になって表示されるようになります。
Part-3: ジョブフロー開発の便利な機能
最後に、3番目のジョブフロー開発の便利な機能ということで、皆さんご存知の常套手段のものから、こんなのあるんだというトリビアチックなものまでご紹介していきたいと思います。
一つ目が Try 文というのがございます。プログラムよく書かれている方はKompiraにもあるのねという話だと思うんですけれども、処理が失敗した時に例外処理を記述するということになっており、Try 文で波括弧 { } でくくって、tryして失敗する可能性がある処理を並べていただいて、その後 if 文でステータスが0じゃないよという話になるんですね。
エラーが起こっているので、ロールバック処理と書いてある。こんな書き方ができるようになります。
これがないと基本的に(処理を)矢印で繋いでいて、ある処理が落ちた段階で、ジョブフローも基本的には止まります。止まってしまうのでリカバリ処理ができないよという話になります。
これもif文を使ってゴリゴリ書くこともできるんですが、 try 文を使って結構簡単に、例外が発生した時に通知書類だとかそういうものを簡単に書くことができるようになっています。
続いてchoice文というものがございます。これはチャネルを使って外部とのインターフェースを取る際に、複数のチャネルから選択的に受信ができるということを書けます。ジョブフローを書かれる方。こんなチャネルを使って、外部から何かシグナルが届くということを待たせることをやるんですけれども、こういった複数のチャネルを同時に受け入れの状態にしといて、チャネル1、チャネル2どちらかにメッセージが届いたら処理を継続する、といったことを書くことができます。
これがないとチャネル1、チャネル2が独立して受信待機となりますので、チャネル1で何かメッセージが来るのをひたすら待つといった動きです。チャネル1で何かメッセージが届いた後でチャネル2に何か届いたという風に、直列に書くことはできるんですけれども、こういった形で同時に受信させるといった記述が可能です。
次は API 経由のジョブフローの実行ということで、外部の監視サーバー、例えばzabbixみたいなものからエラーが見つかった場合、それに対するジョブフローを直接起動するといったことが可能になっています。
典型的な書き方と致しましては、先ほどご紹介しましたチャンネルを使って、チャンネルにメッセージを投げ込んで、Kompira側はその受け取ったメッセージを解析してその内容にしたがって、何かジョブを動かすといった処理を書くのが、典型的な書き方ではあるんですけれども、見ていただいた通りKompiraサーバーのジョブフローをパスに .executeメソッド関数を使っていきますと、直接ジョブフローを起動することができます。
この例ですと、例えば /root/sampleというジョブフローを使ってprint(“hello world”) という簡単なジョブフローがありますけれども、これを外部からRESTクライアントで、/root/sampleというジョブフローに、 .executeをつけて、この認証トークンをつけて実行してあげますと “hello world”を表示して、プロレス一覧を見ますと「完了」している。
このように、外部からジョブフローを直接 API を通じて起動するといったことが可能になっています。
続いてステップ実行なんですが、ジョブフロー実行の際にソースを見ているタブの横に、「設定」タブというものがございます。
こちらのステップモードという所にスイッチをつけて実行ボタンを押してあげますと、括弧内[ ] の処理を始める直前で、ジョブフローが一時的にサスペンドします。その後で「続行」というボタンがありますので、これを押すと改めて処理が再開します。
実際に、どのステップまで動いており、次にどんな操作をするのかということを、逐一確かめながらフローを確認するということが可能です。
続いてリポジトリ型のオブジェクトの話になりますけれども、これはGitとかMercurialの外部のリポジトリを使って、ジョブフローなどのオブジェクトの変更管理をすることが可能です。
リポジトリ型のオブジェクトを使って、外部の URLですとかリポジトリの種別ですね。GitとMerucurialを指定することになります。あと接続ですとか認証情報を書いてあげて、最後のディレクトリというのがありますけれども、これはKompira上のディレクトリの名前になります。
ここでは例えば /root/seminarとありますけれども、この /root/seminarの以下に配置されているオブジェクトについてです。Github に対して pullしたりとか pushしたり、そういったことができるということです。
例えば pushしてあげると github の画面ではこんな感じでジョブフローですとか各種オブジェクトを保存しといて、差分管理をすることができますし、別のKompiraサーバーに対して pullで、こういった形で、全てのオブジェクトをローカルのKompiraサーバーに側にダウンロードしてくるといったことが可能になっています。
ライブラリ型のsafe_sourceというものがありますけれども、Kompira言語ではPython言語を使ってライブラリを作ることができるようになっています。その際にライブラリを作ったことがある方はご存知かと思いますが、通常作っていますと「ライブラリ種別」というのが右下に出てきまして、通常source型ということになっています。
これでadminアカウントを使って属性変更することができるんですけれども、その際に種別をsafe_sourceに切り替えることができます。このように切り替えたライブラリにつきましては、通常のアカウントでログインしてこれを触ろうとすると、編集ができなくなります。勝手にライブラリの中身を書き換えたりすることが、一般ユーザの権限ではできないようになります。
また、このsafe_sourceで保存されているライブラリですが、右上のPythonで書いたソースのところになりますけれども、あるオブジェクトを渡して引数を表示し、引数の型(type) を表示します。繰り返し要素があれば、全部個別に表示をしていく、そのようなライブラリ関数になっています。
この同じソースを、sourceとsafe_sourceの種別で、それぞれ別で保存してあげるということをやっています。safe_lib でobject_namesという関数と、 souce_libで同じくobject_namesという関数を入れてあげて、(引数として)カウントディレクトリ ./ を渡しています。
その実行結果が下になるんですけれども、safe_sourceで渡したものについては ./ とかディレクトリーとして渡っています。型を見ますとディレクトリ型で渡って行って、繰り返し表示をしていきますと、カレントディレクトリの中に入っているオブジェクトの一覧をこのような形で表示するという操作になっています。
これをsourceで保存されているライブラリの関数として呼び出すと、./ という引数が “/root/moduletypes” というパス名(ディレクトリ名)で渡されるといった差が出てきます。
これsafe_sourceの場合はオブジェクトそのものがディレクトリ型として渡っているんですけれども、普通のsourceで保存されているライブラリを参照する場合にはパス名が入ってきます。 Unicode とありますけれども、いわゆるStringで渡されているということになりますので、繰り返し1文字ずつ表示をしているといった形で、sourceで保存した場合とsafe_source型で保存した場合、ライブラリ関数の表示で若干差が出る場合がございますのでご注意ください。
参考リソース
参考のリソースと致しましてはkompira.jp が製品サイトになっています。
Kompira Enterpriseのジョブフロー言語を作る際に参考にして頂ける技術情報を、kompira.jpサイトにコラムとして、スタートガイドなどを載せています。いろんな記事がございますのでそちらをご参考にさせてしていただければと思います。
Kompiraジョブフロー言語の仕様につきましてはKompiraの画面の右上にヘルプボタンがありますので、そちらをクリックして頂けますと公式のドキュメントが出てきます。こちらを参照いただければと思います。