gitlab-runner之build failed with exit status 1問題分析

搶手的哥發表於2019-03-04

前言:

工作需要,原先的一臺專門負責打包的機器要被調走,所以另起爐灶,把需要打包的專案遷移到新機器,本篇文章講述了遷移過程遇到的一些問題以及解決的方法。

1.gitlab-runner

首先還是簡單說一下什麼是gitlab-runner,官網是這麼描述的:

GitLab Runner is the open source project that is used to run your jobs and send the results back to GitLab. It is used in conjunction with GitLab CI, the open-source continuous integration service included with GitLab that coordinates the jobs.

也就是說gitlab-runner是配合gitlab-ci進行使用的。一般地,gitlab裡面的每一個工程都會定義一個屬於這個工程的軟體整合指令碼,用來自動化地完成一些軟體整合工作。
當這個工程的倉庫程式碼發生變動時,比如有人push了程式碼或者分支合併,gitlab就會將這個變動通知gitlab-ci。這時gitlab-ci會找出與這個工程相關聯的runner,並通知這些runner把程式碼更新到本地並執行預定義好的執行指令碼。

2.gitlab-runner安裝和註冊

安裝
註冊
這塊廢話不多說,直接看官方文件,根據系統一次操作一下即可

3.問題描述

新機器到手後,把機器上所有的軟體環境統統更新了個遍,升級到macOS High Sierra,ruby 升級到2.4等等。然後開始安裝gitlab-runner緊接著註冊到gitlab-ci,一切的一切都看似很平靜很正常。

然後開始試跑指令碼,然後莫名其妙的出錯了,log如下:

Running with gitlab-runner 10.3.0 (5cf5e19a)
  on xxx的MacBook pro (0dee7c95)
Using Shell executor...
Running onxxxdeMacBook-Pro.local...
Cloning repository...
Cloning into `/Users/xxx/builds/0dee7c95/0/iOS-Team/xxx-test`...
Checking out 0766deb4 as develop...
Skipping Git submodules setup
ERROR: Job failed: exit status 1
複製程式碼

clone之後立馬出問題,一臉懵逼…這誰看得懂出的啥錯?涼了涼了~

4.問題分析

剛開始以為是clone出問題,開啟build的目錄檔案,裡面所有檔案目錄都是完整的,直接開啟專案工程都能順暢的跑起來。
嘗試用這些log輸出,Google了一下,能搜到好幾個Stack Overflow的結果,但是很遺憾,都未能解決問題。

那麼問題到底出在哪?

首先的換一個思考問題的角度:gitlab-ci上的log看不出,搜不出什麼端倪,那麼gitlab-runner呢?畢竟跑指令碼是gitlab-runner的事情,它自己最清楚了。

於是在打包機器終端裡面輸入gitlab-runner --debug run 這樣runner的每一步操作都能看的到。

Checking for jobs... nothing                        runner=0dee7c95
Feeding runners to channel                          builds=0
Checking for jobs... received                       job=402 repo_url=http://gitlab.xxxx.cn/iOS-Team/xxx-test.git runner=0dee7c95
Failed to requeue the runner:                       builds=1 runner=0dee7c95
Running with gitlab-runner 10.3.0 (5cf5e19a)
  on xxx的MacBook pro (0dee7c95)  job=402 project=47 runner=0dee7c95
Shell configuration: environment: []
dockercommand:
- sh
- -c
- "if [ -x /usr/local/bin/bash ]; then
	exec /usr/local/bin/bash --login
elif [
  -x /usr/bin/bash ]; then
	exec /usr/bin/bash --login
elif [ -x /bin/bash ]; then
	exec
  /bin/bash --login
elif [ -x /usr/local/bin/sh ]; then
	exec /usr/local/bin/sh
  --login
elif [ -x /usr/bin/sh ]; then
	exec /usr/bin/sh --login
elif [ -x /bin/sh
  ]; then
	exec /bin/sh --login
else
	echo shell not found
	exit 1
fi

"
command: bash
arguments:
- --login
passfile: false
extension: ""
  job=402 project=47 runner=0dee7c95
Using Shell executor...                             job=402 project=47 runner=0dee7c95
Waiting for signals...                              job=402 project=47 runner=0dee7c95
WARNING: Job failed: exit status 1                  job=402 project=47 runner=0dee7c95
Submitting job to coordinator... ok                 job=402 runner=0dee7c95
Feeding runners to channel                          builds=0
Checking for jobs... nothing                        runner=0dee7c95
複製程式碼

以上的log是為了復現問題,把相關配置改成問題解決之前,而操作出來的,可能和問題解決之前的log有些出入。根據這些log,再次Google,果然找到了相關資訊:
https://gitlab.com/gitlab-org/gitlab-runner/issues/114
真相大白,原來問題出在RVM上。

RVM相信開發者都不陌生,它是一個便捷的多版本ruby環境的管理和切換工具。有一個注意點,MacOS本身是整合ruby環境的,不同版本的系統預設整合的ruby版本也不一樣。所以日常開發中,我們會根據需要對ruby環境統一管理。這個時候就會用到rvm了。通過rvm可以升級管理ruby。通過which ruby命令可以檢視目前使用的是什麼ruby。比如/Users/xxx/.rvm/rubies/ruby-2.4.1/bin/ruby 輸出的路徑包含了.rvm就說明目前使用的是rvm下的ruby。

到此為止確定了目前使用的是rvm的ruby,在深入定位一下,問題是出在rvm重新定義了cd命令

$ type cd
cd is a function
cd () 
{ 
    __zsh_like_cd cd "$@"
}
$ unset cd
$ type cd
cd is a shell builtin
複製程式碼

所以,clone下來一直出錯的原因是cd命令被重定義了,導致路徑切換的不對,無法執行命令,進而報錯。這就解釋了為什麼gitlab-runner上輸出的log exec /bin/sh --login
else
echo shell not found
exit 1
fi

5.問題解決

知道了原因name如何解決呢?剛剛的問題裡面也給出了方案
.bashrc.bash_profile加上unset cd
操作如下:

1、開啟terminal(終端)
2、cd ~ ( 進入當前使用者的home目錄)
3、open .bash_profile (開啟.bash_profile檔案,如果檔案不存在就  建立檔案:touch .bash_profile  編輯檔案:open -e bash_profile)
4、直接更改彈出的.bash_profile檔案內容
5、command + s 儲存檔案,然後關閉
6、在terminal(終端)中輸入 source .bash_profile (使用剛才更新之後的內容)
複製程式碼

或者直接finder裡面找,用文字編輯器修改一下。

等等.bashrc .bash_profile又是什麼鬼? unset呢?
百度了一下這些得到如下資訊:
profileashrcash_profile之間的區別和聯絡:

/etc/profile 每個使用者,首次登入時被執行;
/etc/bashrc 每個執行bash shell的使用者都執行此檔案,當bsh被開啟時,該檔案被讀取;
~/.bash_profile 專用於本使用者的shell資訊,僅被執行一次;
~/.bashrc 檔案包含本使用者的bsh資訊,登入及每次開啟shell時被讀取。

unset指令:刪除指定的shell變數或函式
【語 法】unset [-fv][變數或函式名稱]
【功能介紹】該指令作用主要是刪除指定的shell變數和函式。

因為gitlab-runner註冊的時候runner executor用的shell,所以shell指令碼的語法是適用的。使用unset cd就意味著把rvm重新定義的cd方法刪除,這樣路徑切換的時候就正常了。gitlab-runner都能正常跑起來了。

6.總結

1.思考問題角度要全面,一套完整的業務流程裡出現問題,可以根據不同角度,不同端想錯誤點靠近,逐個的排查;
2.多關注debug資訊,活用debug輸出的log搜尋資訊,儘量谷歌搜尋,百度太垃圾;
3.shell指令碼是個神奇的東西,工作之餘可以多學習學習。

相關文章