Embulkは必要なプラグインをインストールして使用するのは周知のことだと思いますが、そのときプラグインを普通にインストールするだけだと、デフォルトではログインユーザのユーザフォルダ配下にインストールされるようになっています。
Embulkを実行するユーザとログインユーザが一致していれば問題ないですが、専用のユーザで実行させたい場合、ログインユーザフォルダ配下にインストールされても権限の関係で読み込みができずエラーになることがあります。
なので、今回は全ユーザがアクセス可能な場所にインストールする方法を試したいと思います。
手順的には以下のURLの『Using plugin bundle』の部分になります。
github.com
実施作業
準備
Embulkのインストールは以前の記事で既にやっているので割愛します。
capybara-engineer.hatenablog.com
インストールができたら、プラグインをインストールするフォルダを適当な場所に作成し移動します。
プラグインインストール
以下のコマンドでbundleディレクトリとプラグイン管理用の初期ファイルが作成されます。
インストールしたプラグインはこのフォルダ配下に格納され、実行時にはこのbundleフォルダを指定して実行します。
# embulk mkbundle .\[bundle名]
コマンドの実行結果は以下のようになります。
作成したbundleフォルダ配下には1つのファイルと2つのフォルダが作成されており、インストールするプラグインはこのGemfileを使用して指定します。
Gemfileの中身はこのようになっています。
source 'https://rubygems.org/' # No versions are specified for 'embulk' to use the gem embedded in embulk.jar. # Note that prerelease versions (e.g. "0.9.0.beta") do not match the statement. # Specify the exact prerelease version (like '= 0.9.0.beta') for prereleases. gem 'embulk' # # 1. Use following syntax to specify versions of plugins # to install this bundle directory: # #gem 'embulk-output-mysql' # the latest version #gem 'embulk-input-baz', '= 0.2.0' # specific version #gem 'embulk-input-xyz', '~> 0.3.0' # latest major version #gem 'embulk-output-postgresql', '>= 0.1.0' # newer than specific version # #gem 'embulk-output-awesome', git: 'https://github.com/you/embulk-output-awesome.git', branch: 'master' # # # 2. When you modify this file, run following command to # install plugins: # # $ cd this_directory # $ embulk bundle # # # 3. Then you can use plugins with -b, --bundle BUNDLE_PATH command: # # $ embulk guess -b path/to/this/directory ... # $ embulk run -b path/to/this/directory ... # $ embulk preview -b path/to/this/directory ... #
このファイルの中で『gem 'embulk'』と記載されている箇所があるので、その下にインストールしたいプラグインを同じように書きます。
今回は簡単に検証したいので、Filterプラグインを1つだけ追加します。
~省略~ gem 'embulk' gem 'embulk-filter-column' ~省略~
※プラグインはこちら
出力するカラムにフィルターをかけて必要なカラムだけ出力するようにします。
github.com
Gemfileに追加出来たら以下のコマンドを実行します。
この時に作成したbundleフォルダに移動するのを忘れないでください。
# cd .\test_bundle\ # embulk bundle
結果はこのようになります。
embulk-filter-columnがインストールされていることがログからわかります。
Embulkサンプルファイル実行
では、インストールができたので実際に実行していきます。
実行は以前の記事を参考にして、Embulk標準で準備されているサンプルファイルを使用します。
capybara-engineer.hatenablog.com
以下のコマンドでサンプルファイルを作成します。
# cd .. # embulk example ./example
ファイルがいくつか作成されます。
Embulkに読み込まれるseed.ymlファイルを以下のように書き換えます
内容としては、出力するカラムをidとaccountのみにフィルターします。
in: type: file path_prefix: 'C:\work\embulk_sample\.\example\csv\sample_' filters: - type: column columns: - {name: id, type: long} - {name: account, type: long} out: type: stdout
以下のコマンドを実行して定義ファイルを生成します。
この時『-b』オプションを指定して、インストールしたbundleフォルダを指定しておきます。
# embulk guess ./example/seed.yml -o config.yml -b .\test_bundle
正常に終わるとconfigファイルが作成されます。
Java HotSpot(TM) Client VM warning: TieredCompilation is disabled in this release. 2020-07-09 13:02:58.276 +0000: Embulk v0.9.23 2020-07-09 13:02:59.401 +0000 [WARN] (main): DEPRECATION: JRuby org.jruby.embed.ScriptingContainer is directly injected. 2020-07-09 13:03:02.104 +0000 [INFO] (main): BUNDLE_GEMFILE is being set: "C:\work\embulk_sample\.\test_bundle\Gemfile" 2020-07-09 13:03:02.119 +0000 [INFO] (main): Gem's home and path are being cleared. 2020-07-09 13:03:03.604 +0000 [INFO] (main): Started Embulk v0.9.23 2020-07-09 13:03:03.713 +0000 [INFO] (0001:guess): Listing local files at directory 'C:\work\embulk_sample\.\example\csv' filtering filename by prefix 'sample_' 2020-07-09 13:03:03.713 +0000 [INFO] (0001:guess): "follow_symlinks" is set false. Note that symbolic links to directories are skipped. 2020-07-09 13:03:03.713 +0000 [INFO] (0001:guess): Loading files [C:\work\embulk_sample\.\example\csv\sample_01.csv.gz] 2020-07-09 13:03:03.729 +0000 [INFO] (0001:guess): Try to read 32,768 bytes from input source 2020-07-09 13:03:04.026 +0000 [INFO] (0001:guess): Loaded plugin embulk (0.9.23) 2020-07-09 13:03:04.041 +0000 [INFO] (0001:guess): Loaded plugin embulk (0.9.23) 2020-07-09 13:03:04.088 +0000 [INFO] (0001:guess): Loaded plugin embulk (0.9.23) 2020-07-09 13:03:04.119 +0000 [INFO] (0001:guess): Loaded plugin embulk (0.9.23) in: type: file path_prefix: C:\work\embulk_sample\.\example\csv\sample_ decoders: - {type: gzip} parser: charset: UTF-8 newline: LF type: csv delimiter: ',' quote: '"' escape: '"' null_string: 'NULL' trim_if_not_quoted: false skip_header_lines: 1 allow_extra_columns: false allow_optional_columns: false columns: - {name: id, type: long} - {name: account, type: long} - {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'} - {name: purchase, type: timestamp, format: '%Y%m%d'} - {name: comment, type: string} filters: - type: column columns: - {name: id, type: long} - {name: account, type: long} out: {type: stdout} Created 'config.yml' file.
configファイルが作成できたら、同じく『-b』オプションを付けて以下のコマンドを実行します。
うまくいけば正常終了して、特定のカラムのデータのみ出力されるはずです。
# embulk run .\config.yml -b .\test_bundle
指定したカラムのみが表示されたので、filter-columnのプラグインも正常に動作していました。
余談
ちなみに先ほどの実行コマンドに『-b』オプションを付けずに実行するとどうなるかというと、以下のようにそんなプラグインがないとエラーになります。
2020-07-09 13:06:23.463 +0000: Embulk v0.9.23 2020-07-09 13:06:24.870 +0000 [WARN] (main): DEPRECATION: JRuby org.jruby.embed.ScriptingContainer is directly injected. 2020-07-09 13:06:27.839 +0000 [INFO] (main): Gem's home and path are set by default: "C:\Users\Administrator\.embulk\lib\gems" 2020-07-09 13:06:28.854 +0000 [INFO] (main): Started Embulk v0.9.23 org.embulk.config.ConfigException: FilterPlugin 'column' is not found. org.jruby.proxy.org.embulk.config.ConfigException$Proxy1: Unknown filter plugin 'column'. embulk/filter/column.rb is not installed. Run 'embulk gem search -rd embulk-filter' command to find plugins. at org.embulk.plugin.PluginManager.buildPluginNotFoundException(PluginManager.java:75) at org.embulk.plugin.PluginManager.newPluginWithoutWrapper(PluginManager.java:61) at org.embulk.plugin.PluginManager.newPlugin(PluginManager.java:28) at org.embulk.spi.ExecSession.newPlugin(ExecSession.java:162) at org.embulk.spi.util.Filters.newFilterPlugins(Filters.java:31) at org.embulk.exec.BulkLoader$ProcessPluginSet.<init>(BulkLoader.java:429) at org.embulk.exec.BulkLoader.doRun(BulkLoader.java:502) at org.embulk.exec.BulkLoader.access$000(BulkLoader.java:35) at org.embulk.exec.BulkLoader$1.run(BulkLoader.java:353) at org.embulk.exec.BulkLoader$1.run(BulkLoader.java:350) at org.embulk.spi.Exec.doWith(Exec.java:22) at org.embulk.exec.BulkLoader.run(BulkLoader.java:350) at org.embulk.EmbulkEmbed.run(EmbulkEmbed.java:242) at org.embulk.EmbulkRunner.runInternal(EmbulkRunner.java:291) at org.embulk.EmbulkRunner.run(EmbulkRunner.java:155) at org.embulk.cli.EmbulkRun.runSubcommand(EmbulkRun.java:431) at org.embulk.cli.EmbulkRun.run(EmbulkRun.java:90) at org.embulk.cli.Main.main(Main.java:64) Suppressed: org.embulk.plugin.PluginSourceNotMatchException at org.embulk.plugin.InjectedPluginSource.newPlugin(InjectedPluginSource.java:53) at org.embulk.plugin.PluginManager.newPluginWithoutWrapper(PluginManager.java:49) ... 16 more Suppressed: org.embulk.plugin.PluginSourceNotMatchException at org.embulk.plugin.maven.MavenPluginSource.newPlugin(MavenPluginSource.java:68) at org.embulk.plugin.PluginManager.newPluginWithoutWrapper(PluginManager.java:49) ... 16 more Suppressed: org.embulk.plugin.PluginSourceNotMatchException: org.jruby.embed.InvokeFailedException: org.jruby.proxy.org.embulk.config.ConfigException$Proxy1: Unknown filter plugin 'column'. embulk/filter/column.rb is not installed. Run 'embulk gem search -rd embulk-filter' command to find plugins. at org.embulk.jruby.JRubyPluginSource.newPlugin(JRubyPluginSource.java:63) at org.embulk.plugin.PluginManager.newPluginWithoutWrapper(PluginManager.java:56) ... 16 more Caused by: org.jruby.embed.InvokeFailedException: org.jruby.proxy.org.embulk.config.ConfigException$Proxy1: Unknown filter plugin 'column'. embulk/filter/column.rb is not installed. Run 'embulk gem search -rd embulk-filter' command to find plugins. at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.call(EmbedRubyObjectAdapterImpl.java:322) at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.callMethod(EmbedRubyObjectAdapterImpl.java:159) at org.jruby.embed.ScriptingContainer.callMethod(ScriptingContainer.java:1459) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.embulk.jruby.ScriptingContainerDelegateImpl.callMethod(ScriptingContainerDelegateImpl.java:634) at org.embulk.jruby.LazyScriptingContainerDelegate.callMethod(LazyScriptingContainerDelegate.java:129) at org.embulk.jruby.JRubyPluginSource.newPlugin(JRubyPluginSource.java:61) ... 17 more Caused by: org.jruby.proxy.org.embulk.config.ConfigException$Proxy1: Unknown filter plugin 'column'. embulk/filter/column.rb is not installed. Run 'embulk gem search -rd embulk-filter' command to find plugins. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at org.jruby.javasupport.proxy.JavaProxyConstructor.newInstanceImpl(JavaProxyConstructor.java:119) at org.jruby.javasupport.proxy.JavaProxyConstructor.newInstance(JavaProxyConstructor.java:205) at org.jruby.javasupport.Java$JCreateMethod.call(Java.java:618) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200) at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:739) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:278) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:79) at org.jruby.java.proxies.ConcreteJavaProxy$InitializeMethod.call(ConcreteJavaProxy.java:48) at org.jruby.ir.runtime.IRRuntimeHelpers.instanceSuper(IRRuntimeHelpers.java:984) at org.jruby.ir.instructions.InstanceSuperInstr.interpret(InstanceSuperInstr.java:69) at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:360) at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74) at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:84) at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:179) at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:165) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:328) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:165) at org.jruby.RubyClass.newInstance(RubyClass.java:1001) at org.jruby.RubyClass$INVOKER$i$newInstance.call(RubyClass$INVOKER$i$newInstance.gen) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200) at org.jruby.java.proxies.ConcreteJavaProxy$NewMethod.call(ConcreteJavaProxy.java:158) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:318) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:155) at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:315) at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74) at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:84) at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:179) at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:165) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:318) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:155) at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:315) at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74) at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:90) at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:214) at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:200) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:208) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:338) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:183) at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:324) at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74) at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:109) at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:95) at org.jruby.RubyClass.finvoke(RubyClass.java:522) at org.jruby.RubyBasicObject.send19(RubyBasicObject.java:1684) at org.jruby.RubyBasicObject$INVOKER$i$send19.call(RubyBasicObject$INVOKER$i$send19.gen) at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:278) at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:79) at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:432) at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:360) at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74) at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:109) at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:95) at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:174) at org.jruby.RubyClass.finvoke(RubyClass.java:899) at org.jruby.runtime.Helpers.invoke(Helpers.java:430) at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.callEachType(EmbedRubyObjectAdapterImpl.java:356) at org.jruby.embed.internal.EmbedRubyObjectAdapterImpl.call(EmbedRubyObjectAdapterImpl.java:309) ... 26 more Error: FilterPlugin 'column' is not found. org.jruby.proxy.org.embulk.config.ConfigException$Proxy1: Unknown filter plugin 'column'. embulk/filter/column.rb is not installed. Run 'embulk gem search -rd embulk-filter' command to find plugins.
以下のコマンドを実行するとfilter-columnのプラグインはインストールされていないことがわかります。
# embulk gem list
出力内容の「Gem plugin path」にもありますが、デフォルトはログインユーザ(=実行ユーザ)のユーザフォルダ配下を参照していることがわかります。
感想及び所感
以上、Embulkのプラグインをデフォルトフォルダ以外の場所にインストールする方法をやってみました。
Embulkを使い始めた時は特に気にしていなかったですが、インストール先によってアクセス権がなくてエラーが発生して...というのがあったので調べて初めてこの機能の存在を知りました。
もっと早く気づけばよかったです。。