kettle 執行 kjb 臨時文件夾 /tmp permission denied 問題


編寫完的 kettle job (kjb文件) 放在服務器上執行的時候出現了奇怪的錯誤:

# 執行 kjb
./kitchen.sh -file:/opt/code/ods/ods_inc.kjb

# 錯誤日志
2020/11/10 20:15:40 - TableAccountingState - Running on platform : Linux
2020/11/10 20:15:40 - TableAccountingState - Executing command : /tmp/kettle_72e89b17-234e-11eb-8b7e-49ea52dd39e5shell
2020/11/10 20:15:40 - TableAccountingState - ERROR (version 8.3.0.0-371, build 8.3.0.0-371 from 2019-06-11 11.09.08 by buildguy) : Error running shell [null] : java.io.IOException: Cannot run program "/tmp/kettle_72e89b17-234e-11eb-8b7e-49ea52dd39e5shell": error=13, Permission denied
2020/11/10 20:15:40 - TableAccountingState - ERROR (version 8.3.0.0-371, build 8.3.0.0-371 from 2019-06-11 11.09.08 by buildguy) : java.io.IOException: Cannot run program "/tmp/kettle_72e89b17-234e-11eb-8b7e-49ea52dd39e5shell": error=13, Permission denied
2020/11/10 20:15:40 - TableAccountingState -    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
2020/11/10 20:15:40 - TableAccountingState -    at org.pentaho.di.job.entries.shell.JobEntryShell.executeShell(JobEntryShell.java:595)
2020/11/10 20:15:40 - TableAccountingState -    at org.pentaho.di.job.entries.shell.JobEntryShell.execute(JobEntryShell.java:435)
2020/11/10 20:15:40 - TableAccountingState -    at org.pentaho.di.job.Job.execute(Job.java:686)
2020/11/10 20:15:40 - TableAccountingState -    at org.pentaho.di.job.Job.access$000(Job.java:121)
2020/11/10 20:15:40 - TableAccountingState -    at org.pentaho.di.job.Job$1.run(Job.java:804)
2020/11/10 20:15:40 - TableAccountingState -    at java.lang.Thread.run(Thread.java:748)
2020/11/10 20:15:40 - TableAccountingState - Caused by: java.io.IOException: error=13, Permission denied
2020/11/10 20:15:40 - TableAccountingState -    at java.lang.UNIXProcess.forkAndExec(Native Method)
2020/11/10 20:15:40 - TableAccountingState -    at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
2020/11/10 20:15:40 - TableAccountingState -    at java.lang.ProcessImpl.start(ProcessImpl.java:134)
2020/11/10 20:15:40 - TableAccountingState -    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
2020/11/10 20:15:40 - TableAccountingState -    ... 6 more
2020/11/10 20:15:40 - ods_inc_test - Finished job entry [Flag] (result=[false])
2020/11/10 20:15:40 - ods_inc_test - Finished job entry [Get Date] (result=[false])
2020/11/10 20:15:40 - ods_inc_test - Job execution finished
2020/11/10 20:15:40 - Kitchen - Finished!
2020/11/10 20:15:40 - Kitchen - ERROR (version 8.3.0.0-371, build 8.3.0.0-371 from 2019-06-11 11.09.08 by buildguy) : Finished with errors
2020/11/10 20:15:40 - Kitchen - Start=2020/11/10 20:15:35.801, Stop=2020/11/10 20:15:40.738
2020/11/10 20:15:40 - Kitchen - Processing ended after 4 seconds.

關鍵錯誤在於

Error running shell [null] : java.io.IOException: Cannot run program "/tmp/kettle_72e89b17-234e-11eb-8b7e-49ea52dd39e5shell": error=13, Permission denied

可以看出錯誤在於沒有權限執行/tmp/kettle_72e89b17-234e-11eb-8b7e-49ea52dd39e5shell,這個文件是 kettle 在執行腳本的時候生成的臨時文件,但是沒有權限執行。

首先嘗試給用戶賦予 /tmp 文件夾的可執行權限,但是仍然相同的報錯。

一番查閱資料后發現是由於/tmp文件系統的屬性被設置了noexec導致該目錄下的程序無法執行。noexec表示對應文件系統不允許執行可執行程序,即使文件具有可執行過權限。通常是考慮安全原因會這么設置。

那么方法有兩個:

  1. 移除/tmpnoexec 屬性,但是可能會導致安全隱患
  2. 更改 kettle 生成臨時文件的目錄,讓其在一個有執行權限的文件中生成臨時文件。

第一個方法可能會有安全隱患,/tmp 文件夾是很容易遭受攻擊的地方,而且修改了 /etc/fstab 中的配置后需要對 /tmp 進行重新掛在,這時可能有很多程序在使用這個目錄,需要停掉使用的服務,一些服務甚至需要重啟,在生產環境中不好執行。

那就想辦法修改 kettle 的臨時文件目錄。

首先搜索了 kettle 的幫助使用手冊和幫助文檔,並沒有發現有提供對應的入口。

但是 kettle 是跑在 JVM 上的 java 程序,那么理論上應該可以修改 JVM 啟動參數達到目的。

我們使用 kitchen 執行 kjb 文件(kettle job)實際上就是執行這個 job 中的 kettle transformation,而 kettle transformation 是用 spoon 程序執行的,那么就看一看 spoon.sh(Linux環境下,Windows下則是 spoon.bat)

在 spoon.sh 中發現這么一段代碼:

# **********************************************************************
# ** Set java runtime options
# ** Change 2048m to higher values in case you run out of memory
# ** or set the PENTAHO_DI_JAVA_OPTIONS environment variable
# **********************************************************************
 
if [ -z "$PENTAHO_DI_JAVA_OPTIONS" ]; then
    PENTAHO_DI_JAVA_OPTIONS="-Xms1024m -Xmx2048m"
fi
 
OPT="$OPT $PENTAHO_DI_JAVA_OPTIONS 
-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 
-Djava.library.path=$LIBPATH 
-Djava.endor sed.dirs=$JAVA_ENDORSED_DIRS 
-DKETTLE_HOME=$KETTLE_HOME 
-DKETTLE_REPOSITORY=$KETTLE_REPOSITORY 
-DKETTLE_USER=$KETTLE_USER 
-DKETTLE_PASSWORD=$KETTLE_PASSWORD 
-DKETTLE_PLUGIN_PACKAGES=$KETTLE_PLUGIN_PACKAGES 
-DKETTLE_LOG_SIZE_LIMIT=$KETTLE_LOG_SIZE_LIMIT 
-DKETTLE_JNDI_ROOT=$KETTLE_JNDI_ROOT"

框框的注釋中說得很清楚了,這里就是設置 runtime options 的地方,那么我們在 OPT 后面加上 -Djava.io.tmpdir=/opt/code/kettle_tmp 試試。

java.io.tmpdir 是配置 JVM 默認臨時文件輸出目錄的參數。

再次執行 ./kitchen.sh -file:/opt/code/ods/ods_inc.kjb 出現一下日志輸出:

2020/11/10 20:22:04 - TableAccountingState - Running on platform : Linux
2020/11/10 20:22:04 - TableAccountingState - Executing command : /opt/code/kettle_tmp/kettle_577843c5-234f-11eb-b308-d38e88d4b1fdshell

證明 -Djava.io.tmpdir=/opt/code/kettle_tmp 生效了,並且沒有再報相同的權限錯誤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM