前言

对 bare vm supervisor 了解的不多,而ESXi的安装程序又有些智障,在x86软路由上,这安装程序的问题似乎尤为的突出...

这次折腾ESXi的途中被它坑了两下,这里简单的总结一下遇到的两个坑。

ESXi版本: 6.7.0 (官网 iso 镜像, rufus 写入 U 盘)
硬件: 小马 x86 软路由 V2

坑一

启动安装程序时,显示 Multiboot could not setup the video subsystem

router-esxi-issue-1.jpg

乍一看好像是不兼容显卡,或是缺了显卡驱动,但实际上是 ESXi 的安装程序需要当前显示器的分辨率不小于 1024x768

当 BIOS 的显卡设置为 Legacy 模式时,分辨率会被固定到 800x600,而 UEFI 模式是跟随当前显示器的。

于是我们在 BIOS 中找到显卡设置,把显卡模式改为 UEFI
在我的环境上,这个选项在 CSM Configuration -> Option ROM execution -> Video

router-bios-1.jpg

router-bios-2.jpg

坑二

显卡相关的问题解决了,可是启动安装程序的时候,还是卡在了 Relocating modules and Starting up kernel ...

router-exsi-issue-2.jpg

这同样是安装程序的问题,在检查当前硬件是否为 headless (无显示器) 时卡住了。
我们可以通过给安装程序添加启动参数来跳过 headless 检查。

在安装程序启动后,加载安装文件前(左下角在倒计时 5 秒),按下 Shift+o 编辑启动参数,在后面加上 ignoreHeadless=TRUE 后回车,即可正常进入安装程序。

esxi-installer-loaded.jpg

在安装的最后一步,ESXi安装程序会提醒你移除你用来安装的 U 盘,然后重启,这里我们照做。
但需要注意,headless 检查并不只在安装程序中才有,而是在 ESXi 的每一次启动中都存在。
于是我们在重启之后,准备再一次按 Shift+o 添加 ignoreHeadless=TRUE 来启动到 ESXi 中。

在成功的启动到 ESXi 之后,我们要为 ESXi 永久添加这个跳过 headless 检查的参数,这样就不用每次重启都手动改一遍参数了。

首先在主界面中按 F2
esxi-main-screen

然后使用刚刚安装时设置的密码登录到 root 账户

esxi-login.png

选择 Troubleshooting Options

esxi-troubleshooting-options.png

然后我们打开 ESXi Shell

esxi-enable-shell.png

这时我们按 Alt+F2 进入 Shell,依然是使用 root 登陆

执行 esxcfg-advcfg --set-kernel "TRUE" ignoreHeadless 就可以了

还可以执行 esxcfg-advcfg –get-kernel ignoreHeadless 看看是否正确的设置了参数
如果返回 ignoreHeadless = TRUE 表示一切 OK

然后就可以执行 exit 退出 Shell 了,之后你可以把 ESXi Shell 功能关闭来提升安全性。

参考

http://plain-virt.blogspot.ca/2012/11/vsphere-5x-errors-installing-esxi-5x.html

https://community.spiceworks.com/topic/513331-multiboot-could-not-set-up-the-video-subsystem-esxi-install

1 前言

在测试服务器上想把 tensorflow 相关代码部署一下

却发现 CentOS 6.1 带的 glibclibstdc++ 都太老了,tensorflow跑不起来。

于是想手动升级一下这两个 lib。

2 警告

如果你找到了这篇文章,并且你也想手动升级系统的libc:

“不要做这件蠢事”
“不要做这件蠢事”
“不要做这件蠢事”

太多抄来抄去的文章会教人替换 libc,却不说明任何细节和注意事项。

你需要做的,是使用LD_PRELOAD这个环境变量指定你所要使用的libc.so,而不是直接替换系统自带的 libc

3 如果你真的要这样做

如果你真的要手动升级 libc
并不在乎任何可能出现的兼容性问题,且知道其他可能出现的危害的话。

务必先切换到root账户,再进行libc软链接替换的操作。
否则在执行 sudo rm /lib64/libc.so.6 删除libc的软链接之后,
你会发现 sudo 以及一切 setuid 的程序都是不接受 LD_PRELOAD 参数的,导致你没有权限修复 libc 的软链接。

具体的步骤是:

  1. 编译一个新版的 glibc,并安装到独立的目录
  2. 切换到 root 账户
  3. 删除 /lib64/libc.so.6 这个软链接
  4. 设置 LD_PRELOAD 指定一个可用的 libc 所在目录,使 ln 恢复正常
  5. 使用 ln -s 将新版的 glibc 软链接到原处,也就是 /lib64/libc.so.6

4 如果已经出事了

唯一的方法是通过 livecd / 其他系统 挂载硬盘恢复 libc

5 我最后是如何解决这个问题的

在找虚拟化部门的同事修好了 libc 的软链接后,尝试编译新的 gcc 来获取新版的 libstdc++

手动指定两个新的 lib 后运行 tensorflow 后报错 Illegal instruction.

更换到 CentOS 7 后解决了 tensorflow 无法运行的问题。

0x00 前情提要
-
Python-EngineIO 没有实现 Socket.IO 中 JSONP-Polling 的支持,于是尝试着动态 Patch。
Python 动态 Patch 实战 (1)

0x01 起因
-
真的是没有想到,在给 Python-EngineIO 加上 JSONP-polling 支持之后,这么快就遇到了第二个需要 Patch 的情况...

这次是因为 eventlet 并没有正确处理 WSGI environ string
导致百分号编码 (Percent-encoding) 出现在 URL 中时
可能会导致 wsgi app 崩溃的 bug

0x02 相关
-
Eventlet Issue#468
Patch 代码

0x00 前言
-
其实我也不太清楚这种操作到底该叫什么
不过跟 Monkey patch 似乎是一个用途,就是在运行时修改代码
于是我就先叫他 Dynamic patch

0x01 起因
-
在使用 Flask-SocketIO 的时候,发现其并没有完全实现所有的 socket.io 中的 transport 协议
于是想手动支持一下 JSONP Polling

看着 eventlet 提供的 monkey_patch(),发现我是不是也可以动态 patch 一下他的代码
这样可以最大限度的保持项目的干净,而不用再维护一个库甚至多个库的代码分支

0x02 实战
-
当同时使用 eventlet 和 Pycharm 的 debugger 时,需要注意不能给 thread 打 monkey patch, 否则 debugger 会坏掉。

跟着代码摸了几个小时,再看了看官方 nodejs 版的 server 代码,又给官方 demo 抓了一下包,大概摸清了协议,于是把

engineio.server.Server::_ok()
engineio.payload.Payload::decode()
engineio.payload.Payload::encode()
engineio.server.Server::handle_connect()
engineio.server.Server::_handle_connect()

这五个函数替换掉了,总体思路比较简单,socket.io 协议的 payload 不变,针对请求入口和出口为 JSONP 请求做出相应修改即可。

0x03 相关
-
Patch 代码在 Github Gist
Python-EngineIO 的 Issue

大一刚开始时,因为一点小的契机,开始做一个小的面向校园的项目

在之后过去的三年中,从无到有,一个人把整个开发流程全都体验了下来

分析需求-设计-开发-测试-部署-维护-客服 如此往复....
最要命的是,为了让自己优雅起来,多个平台多个语言的 native 开发,多份代码令人沉醉

全都自己包揽下来,显然是没有沟通成本的,自己决定所有的事情,令人开心

然而纵观整个流程,大量繁琐蛋疼的工作逐渐的让我在意起来:
故障发生后用户反馈才知道-需要监控
Server新代码手动上线十分麻烦,客户端发新版真要命-需要自动化部署
买了个新vps配置半天真要命-需要自动化运维

于是想办法:
运维怎么办?Ansible吧,能实现一点简单的normalize就可以了
监控和部署怎么办?Zabbix+Jenkins? 小项目不想上那么大的东西...
于是代码里TopExceptionHandler一把梭,和Telegram Bot对接实时通知,简陋的监控完成
然后用git push hook做了个简单的服务端部署自动化,给客户端自动更新的接口做了个简单的管理页面。

然而感觉git hook的配置太麻烦,于是又写了个脚本自动配置 hook。
自动配置hook的脚本:https://gist.github.com/StoneMoe/8c897122a32776c1ee0252f605b01e2c

于是简陋又简单的自动化系统搭起来了)

而最近写bot的时候,直接用了Sublime SFTP 的 Mapping 功能,更加的一把梭了)