新做的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!")

cloud-init代码调试方法的更多相关文章

  1. 三、K3 Cloud 开发插件《K3 Cloud插件开发新手指导 + K3 Cloud插件开发代码调试》

    案例需求:在销售订单上新增一个按钮,在订单明细中新增一个字段,命名[即时库存]. 点击按钮,弹出“Hello World!”,并获取订单明细物料的即时库存,填入字段[即时库存]. 开发工具:Visua ...

  2. javascript代码 调试方法

    你的代码可能包含语法错误,逻辑错误,如果没有调试工具,这些错误比较难于发现. 通常,如果 JavaScript 出现错误,是不会有提示信息,这样你就无法找到代码错误的位置. 在程序代码中寻找错误叫做代 ...

  3. 初识 Javascript.02 -- Date日期、Math对象、数据类型转换、字符串、布尔Boolean、逻辑运算符、if else 、三元表达式、代码调试方法、

    Date()对象: Date对象用于处理日期和时间. 1.1 Math对象  ◆Math.ceil()   天花板函数    向上取整  只取整数,不足则进1 ◆Math.floor()  地板函数 ...

  4. 2019-11-29-WPF-依赖属性绑定不上调试方法

    原文:2019-11-29-WPF-依赖属性绑定不上调试方法 title author date CreateTime categories WPF 依赖属性绑定不上调试方法 lindexi 2019 ...

  5. 2019-8-2-WPF-依赖属性绑定不上调试方法

    title author date CreateTime categories WPF 依赖属性绑定不上调试方法 lindexi 2019-08-02 19:56:32 +0800 2019-8-2 ...

  6. linux设备驱动程序第四部分:从如何定位oops对代码的调试方法,驱动线

    在一个我们谈到了如何编写一个简单的字符设备驱动程序,我们不是神,编写肯定会失败的代码,在这个过程中,我们需要继续写代码调试.在普通c应用.我们经常使用printf输出信息.或者使用gdb要调试程序,然 ...

  7. linux设备驱动第四篇:从如何定位oops的代码行谈驱动调试方法

    上一篇我们大概聊了如何写一个简单的字符设备驱动,我们不是神,写代码肯定会出现问题,我们需要在编写代码的过程中不断调试.在普通的c应用程序中,我们经常使用printf来输出信息,或者使用gdb来调试程序 ...

  8. alert一般用来调试客户端的javascript代码,以及更好的调试方法

    alert一般用来调试客户端的javascript代码 调试利器--console.log 如今主流浏览器(Chrome,IE8及后续版本,FireFox,Opera等)都支持控制台功能. Chrom ...

  9. CodeBlocks(17.12) 代码调试基础方法&快捷方式

    转载:CodeBlocks(17.12) 代码调试基础方法&快捷方式: https://www.cnblogs.com/DCD112358/p/8998053.html

随机推荐

  1. vuejs父子组件的数据传递

    在vue中,父组件往子组件传递参数都是通过属性的形式来传递的 <div id='root'> <counter :count = '1'></counter> &l ...

  2. 将命令的输出生成一个Web页面

    解决方法: ConvertTo-Html 命令: 生成一个HTML表格来代表命令的输出,为你提供的每个对象创建一行,在每行中,Powershell会创建代表对象属性的值. 实现效果:

  3. 软件架构中的SOA架构有哪些特点?

    面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来.构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互. SOA是一 ...

  4. UTF8与ANSI互转

    在取回的结果中,如果有Unicode字符,用printf来打印的话,则会出现乱码.通过这个方法,可以判断是否为unicode字符,是的话,通过wprintf来打印.1.判断字符串是否为Unicode的 ...

  5. 11、SpringBoot------定时任务

      开发工具:STS 代码下载链接:https://github.com/theIndoorTrain/Springboot/tree/52ef6c0c805913db1e66ed18671c322e ...

  6. 一个老鸟发的公司内部整理的 Android 学习路线图 Markdown 版本

    jixiaohua发了一篇一个老鸟也发了一份他给公司内部小伙伴整理的路线图.另一份 Android 开发学习路线图.可惜不是MarkDown格式的,所以jixiaohua直接上传的截图,在jixiao ...

  7. 出门旅行(tour)

    出门旅行(tour) 题目描述: 在神奇的 oi 国度,有 n 个城市 m 条双向道路,每条道路连接了两个不同的城市.寒假到了,小 S 决定出门旅游一趟.因为以往跟团旅游多了,这次小 S 决定自驾游. ...

  8. spring-IOC底层机制

    JDK与CGLIB的动态代理 JDK动态代理 创建代理的方法 将需要代理的类传入代理类中(通过构造方法) 在代理方法中创建代理实例(需要一个接口和一个实现接口的类): Proxy.newProxyIn ...

  9. Servlet学习笔记05——什么是jsp?

    1. jsp (java server page) (1)jsp是什么? sun公司制订的一种服务器端动态页面技术规范. 注: 因为虽然使用servlet也可以生成动态页面, 但是过于繁琐(需要使用o ...

  10. dts--tests(四)

    unit_tests.py """ DPDK Test suite. This TestSuite runs the unit tests included in DPD ...