Jenkins有一個內(nèi)置的命令行界面,允許用戶和管理員從腳本或shell環(huán)境訪問Jenkins。這對于日常任務(wù)的腳本編寫,批量更新,故障排除等都是很方??便的。
命令行界面可以通過SSH或Jenkins CLI客戶端進行訪問,這是Jenkins .jar發(fā)布的一個文件。
不建議使用與Jenkins 2.53及更早版本Jenkins 2.5.3及更早版本配合使用的CLI客戶端,因為安全原因:雖然目前還存在未知的漏洞,但是有幾個已經(jīng)被報告和修補過,而Jenkins Remoting協(xié)議使用本身就容易受到遠(yuǎn)程代碼執(zhí)行錯誤的影響,甚至是“預(yù)認(rèn)證”漏洞(由能夠物理訪問Jenkins網(wǎng)絡(luò)的匿名用戶)。
Jenkins 2.54和更新版本的Jenkins LTS 2.46.2和更新版本的客戶端在其默認(rèn)(-http)或-ssh模式下被認(rèn)為是安全的,正如使用標(biāo)準(zhǔn)ssh命令一樣
在新的Jenkins安裝中,默認(rèn)情況下禁用SSH服務(wù)。管理員可以選擇設(shè)置特定端口,或者請求Jenkins在“ 配置全局安全性”頁面中選擇一個隨機端口。為了確定隨機分配的SSH端口,請檢查Jenkins URL上返回的標(biāo)頭,例如:
% curl -Lv https://JENKINS_URL/login 2>&1 | grep 'X-SSH-Endpoint'
< X-SSH-Endpoint: localhost:53801
%
使用隨機SSH端口(53801在本示例中)和身份驗證 配置,任何現(xiàn)代SSH客戶端都可以安全地執(zhí)行CLI命令。
用于與Jenkins主機進行身份驗證的用戶必須具有訪問 CLI 的 Overall/Read權(quán)限。根據(jù)執(zhí)行的命令,用戶可能需要額外的權(quán)限。
認(rèn)證依賴于基于SSH的公鑰/私鑰認(rèn)證。要為適當(dāng)?shù)挠脩籼砑覵SH公鑰,請導(dǎo)航 https://JENKINS_URL/user/USERNAME/configure并將SSH公鑰粘貼到相應(yīng)的文本區(qū)域中。
Jenkins有許多內(nèi)置的CLI命令,可以在每個Jenkins環(huán)境中找到,例如build或list-jobs。插件還可以提供CLI命令; 為了確定給定Jenkins環(huán)境中可用的命令的完整列表,請執(zhí)行CLI help命令:
% ssh -l kohsuke -p 53801 localhost help
以下命令列表并不全面,但它是Jenkins CLI使用的有用起點。
CLI命令中最常用和最有用的命令之一是build允許用戶觸發(fā)他們有權(quán)限的任何作業(yè)或pipeline。
最基本的調(diào)用將簡單地觸發(fā)作業(yè)或pipeline并退出,但是使用附加選項,用戶也可以傳遞參數(shù),輪詢SCM,甚至跟隨觸發(fā)構(gòu)建或pipeline運行的控制臺輸出。
% ssh -l kohsuke -p 53801 localhost help build
java -jar jenkins-cli.jar build JOB [-c] [-f] [-p] [-r N] [-s] [-v] [-w]
Starts a build, and optionally waits for a completion. Aside from general
scripting use, this command can be used to invoke another job from within a
build of one job. With the -s option, this command changes the exit code based
on the outcome of the build (exit code 0 indicates a success) and interrupting
the command will interrupt the job. With the -f option, this command changes
the exit code based on the outcome of the build (exit code 0 indicates a
success) however, unlike -s, interrupting the command will not interrupt the
job (exit code 125 indicates the command was interrupted). With the -c option,
a build will only run if there has been an SCM change.
JOB : Name of the job to build
-c : Check for SCM changes before starting the build, and if there's no
change, exit without doing a build
-f : Follow the build progress. Like -s only interrupts are not passed
through to the build.
-p : Specify the build parameters in the key=value format.
-s : Wait until the completion/abortion of the command. Interrupts are passed
through to the build.
-v : Prints out the console output of the build. Use with -s
-w : Wait until the start of the command
% ssh -l kohsuke -p 53801 localhost build build-all-software -f -v
Started build-all-software #1
Started from command line by admin
Building in workspace /tmp/jenkins/workspace/build-all-software
[build-all-software] $ /bin/sh -xe /tmp/hudson1100603797526301795.sh
+ echo hello world
hello world
Finished: SUCCESS
Completed build-all-software #1 : SUCCESS
%
同樣有用的是console命令,它檢索指定生成或pipeline運行的控制臺輸出。當(dāng)沒有提供編號時,該 console命令將輸出最后完成的版本的控制臺輸出。
% ssh -l kohsuke -p 53801 localhost help console
java -jar jenkins-cli.jar console JOB [BUILD] [-f] [-n N]
Produces the console output of a specific build to stdout, as if you are doing 'cat build.log'
JOB : Name of the job
BUILD : Build number or permalink to point to the build. Defaults to the last
build
-f : If the build is in progress, stay around and append console output as
it comes, like 'tail -f'
-n N : Display the last N lines
% ssh -l kohsuke -p 53801 localhost console build-all-software
Started from command line by kohsuke
Building in workspace /tmp/jenkins/workspace/build-all-software
[build-all-software] $ /bin/sh -xe /tmp/hudson1100603797526301795.sh
+ echo hello world
yes
Finished: SUCCESS
%
該who-am-i命令有助于列出用戶可用的當(dāng)前用戶的憑據(jù)和權(quán)限。當(dāng)調(diào)試缺少CLI命令時,由于缺少某些權(quán)限,這將非常有用。
% ssh -l kohsuke -p 53801 localhost help who-am-i
java -jar jenkins-cli.jar who-am-i
Reports your credential and permissions.
% ssh -l kohsuke -p 53801 localhost who-am-i
Authenticated as: kohsuke
Authorities:
authenticated
%
盡管基于SSH的CLI速度快,涵蓋了大部分需求,但可能會出現(xiàn)與Jenkins分發(fā)的CLI客戶端更適合的情況。例如,CLI客戶端的默認(rèn)傳輸是HTTP,這意味著在防火墻中不需要打開額外的端口供其使用。
該CLI客戶端可以直接從Jenkins管理在URL下載 /jnlpJars/jenkins-cli.jar,在效果 https://JENKINS_URL/jnlpJars/jenkins-cli.jar
雖然CLI .jar可以針對不同版本的Jenkins使用,但如果在使用過程中出現(xiàn)任何兼容性問題,請.jar 從Jenkins管理重新下載最新的文件。
調(diào)用客戶端的一般語法如下:
java -jar jenkins-cli.jar [-s JENKINS_URL] [global options...] command [command options...] [arguments...]
有三種基本模式,其中可以使用本2.54+ / 2.46.2+客戶端,通過全局選項可選擇的: -http; -ssh; 和-remoting。
這是2.54和2.46.2的默認(rèn)模式,盡管-http為了清楚起見,您可以明確地傳遞選項。
認(rèn)證最好有一個-auth
選項,它需要一個username:apitoken
參數(shù)。獲取您的API令牌/me/configure
:
java -jar jenkins-cli.jar [-s JENKINS_URL] -auth kohsuke:abc1234ffe4a command ...
(也接受實際的密碼,但不鼓勵)。
您還可以在參數(shù)之前@從文件加載相同的內(nèi)容:
java -jar jenkins-cli.jar [-s JENKINS_URL] -auth @/home/kohsuke/.jenkins-cli command ...
通常,不需要特殊的系統(tǒng)配置來啟用基于HTTP的CLI連接。如果您在HTTP(S)反向代理之后運行Jenkins,請確保它不緩沖請求或響應(yīng)體。
驗證是通過SSH密鑰對。您還必須選擇Jenkins用戶ID:
java -jar jenkins-cli.jar [-s JENKINS_URL] -ssh -user kohsuke command ...
在這種模式下,客戶端的行為基本上就像一個本機ssh命令。
默認(rèn)情況下,客戶端將嘗試連接到同一主機上的SSH端口JENKINS_URL。如果Jenkins位于HTTP反向代理之后,這通常不起作用,因此運行Jenkins與系統(tǒng)屬性-Dorg.jenkinsci.main.modules.sshd.SSHD.hostName=ACTUALHOST 來定義SSH端點的主機名或IP地址。
這是從2.54 / pre-2.46.2之前的Jenkins服務(wù)器(在引入該-remoting選項之前)下載的客戶端支持的唯一模式。由于安全性和性能原因,它的使用已被棄用。也就是說,某些命令或命令模式只能在Remoting模式下運行,這通常是因為命令功能涉及在客戶機上運行服務(wù)器提供的代碼。
在2.54+和2.46.2的新安裝中,服務(wù)器端禁用此模式。如果您必須使用它并接受風(fēng)險,則可能會在配置全局安全性中啟用。
驗證最好通過SSH密鑰對。一個login命令和--username/ --password命令(注意:不是全球性)選項也可用; 這些是不鼓勵的,因為它們無法使用基于非密碼的安全領(lǐng)域,如果匿名用戶缺少整體或作業(yè)讀取訪問權(quán)限,某些命令參數(shù)將無法正確解析,并且將保存用于腳本的人為選擇的密碼視為不安全。
請注意,有兩種可用于此模式的傳輸:通過HTTP或?qū)S肨CP套接字。如果TCP端口啟用并且可以工作,客戶端將使用此傳輸。如果TCP端口被禁用,或者這樣的端口被通告但不接受連接(例如因為您使用帶有防火墻的HTTP反向代理),客戶端將自動回退到效率較低的HTTP傳輸。
運行CLI客戶端時可能會遇到一些常見的問題。
如果您在服務(wù)器上使用防火墻,請檢查是否打開HTTP端口或TCP端口。您可以在Jenkins配置中配置其值。默認(rèn)設(shè)置為使用隨機端口。
% java -jar jenkins-cli.jar -s JENKINS_URL help
Exception in thread "main" java.net.ConnectException: Operation timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:189)
at hudson.cli.CLI.<init>(CLI.java:97)
at hudson.cli.CLI.<init>(CLI.java:82)
at hudson.cli.CLI._main(CLI.java:250)
at hudson.cli.CLI.main(CLI.java:199)
轉(zhuǎn)到管理Jenkins > 配置全局安全性,并在JNLP代理的TCP端口下選擇“固定”或“隨機” 。
java.io.IOException: No X-Jenkins-CLI2-Port among [X-Jenkins, null, Server, X-Content-Type-Options, Connection,
X-You-Are-In-Group, X-Hudson, X-Permission-Implied-By, Date, X-Jenkins-Session, X-You-Are-Authenticated-As,
X-Required-Permission, Set-Cookie, Expires, Content-Length, Content-Type]
at hudson.cli.CLI.getCliTcpPort(CLI.java:284)
at hudson.cli.CLI.<init>(CLI.java:128)
at hudson.cli.CLIConnectionFactory.connect(CLIConnectionFactory.java:72)
at hudson.cli.CLI._main(CLI.java:473)
at hudson.cli.CLI.main(CLI.java:384)
Suppressed: java.io.IOException: Server returned HTTP response code: 403 for URL: http://citest.gce.px/cli
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1840)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
at hudson.cli.FullDuplexHttpStream.<init>(FullDuplexHttpStream.java:78)
at hudson.cli.CLI.connectViaHttp(CLI.java:152)
at hudson.cli.CLI.<init>(CLI.java:132)
... 3 more
更多建議: