cloud-init代碼調試方法


新做的centos7.4鏡像的cloud-init安裝好之后,修改密碼失敗,但是同樣的配置文件在7.2上的是正常的,對比了一下版本,centos7.4上的是0.7.9,7.2上的是0.7.5,經過調試發現是0.7.9版本的cloud-init有bug導致的,發現問題之后通過降級到0.7.5版本解決。之前也加斷點調試過幾次,但沒有記錄下來,這里記錄下調試方法,因為默認直接加pdb斷點是沒法調試的。

首先要知道如何手工運行cloud-init工具,可以命令行執行: cloud-init -h ,看到有多個命令供選擇,但我們只需要執行 cloud-init init 命令和 cloud-init init --local 命令即可,這兩個命令就是開機自啟動服務中會執行的,差異就是 --local 僅讀取本地數據源(如config drive數據源),不加這個參數,可能嘗試讀取EC2等網絡數據源(http://169.254.169.254)。

執行的時候要注意,cloud-init很多操作都是默認僅第一次開機的時候執行的(once-per-instance),也就是說默認情況下,每個雲主機僅在第一次創建后啟動的時候執行一次初始化操作,后面無論你怎么重啟都不會執行的(當然不是全部初始化操作都不執行,要看具體的配置,但絕大部分操作都是once-per-instance)。所以為了保證每次手工執行的時候,都執行所有初始化操作,可以手工刪除cloud-init的緩存目錄,cloud-init是根據緩存中的雲主機id(instance-id,一般就是雲主機uuid)和數據源中獲取的id來對比,確認是否是新建雲主機第一次啟動的。該緩存目錄一般位於(/var/lib/cloud),直接刪除整個目錄即可清空緩存,調試過程中每次執行cloud-init命令前都需要刪除一次。

直接加pdb斷點到源碼里是無法調試的,因為cloud-init會重定向標准輸入stdin,所以還要注釋掉這行代碼才行:

 try:
174         LOG.debug("Closing stdin")
175         #util.close_stdin()       ########### 注釋掉這行
176         (outfmt, errfmt) = util.fixup_output(init.cfg, name)
177     except Exception:
178         util.logexc(LOG, "Failed to setup output redirection!")
179         print_exc("Failed to setup output redirection!")

上面是cloud-init init命令需要注釋掉代碼的示例(基於0.7.9版本源碼,0.7.5版本的入口在/usr/bin/cloud-init或者/bin/cloud-init,可使用 which cloud-init 命令查看具體路徑,需要在這個文件里注釋掉這行代碼),如果你要調試其他命令如cloud-init modules還有其他地方需要注釋:

$:/usr/lib/python2.7/site-packages/cloudinit/cmd# grep -rn stdin main.py
### (基於0.7.9版本,0.7.5的是/usr/bin/cloud-init)
174:        LOG.debug("Closing stdin")
175:        util.close_stdin()
356:        LOG.debug("Closing stdin")
357:        util.close_stdin()
419:        LOG.debug("Closing stdin")
420:        util.close_stdin()

之后在main_init方法的入口處加入斷點(0.7.5的不加會進入不了調試模式,0.7.9的可以不加,為了保險,可以加上,然后執行c命令跳到你真正想調試的斷點處即可),然后再在你想要的任何地方加斷點即可調試。

170     # Stage 2
171     outfmt = None
172     errfmt = None
173     import pdb;pdb.set_trace()    ### 加入pdb斷點
174     try:
175         LOG.debug("Closing stdin")
176         #util.close_stdin()            ########### 注釋掉這行
177         (outfmt, errfmt) = util.fixup_output(init.cfg, name)
178     except Exception:
179         util.logexc(LOG, "Failed to setup output redirection!")
180         print_exc("Failed to setup output redirection!")

 


免責聲明!

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



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