fightclub

拷贝photon镜像源

缘起

最近刚给vsphere升级了6.5。在6.5中内置了容器集成(VIC)功能。docker已经热了这么久了,苦于实在是没时间折腾。现在也总算找到借口换换口味。

vmware为了降低在虚拟机中运行容器的损耗,特别定制了一个极简的并且针对vmware优化过的linux发行版-photon os。就连6.5中新的vsphere server appliance也是使用该系统的。

这个系统里面只带了一些最基本的工具和命令,其他工具通过内置了一个yum兼容的包管理器tdnf来从vmware的官方源下载。因为我司的特别情况,内外网不能互联,或者说不能直接联通,只能再想办法。

最初的想法

最开始的想法很简单,在通往外部的临界服务器使用wget将整个静态网站的内容都下载下来。再通过web服务器把内容放出来,把photon下面的软件源的内容都替换成自己的web服务器就可以了。

试了下居然只下载了几个index.html。把robots检查关闭了还是如此。仔细看了下报错信息。原来是对面的源为了防止网页爬虫,使用:代替了/,再使用js在点击的时候将:替换回来。好吧,算你厉害。只能换个办法。

要不使用反向代理?

其实这并不是个好办法,因为公司的环境比较忌讳。但是偶尔试试看总还是可以的。
不过出人意料的还是失败。我几经确认链接无误,但是就是404。我对nginx玩的还不是很6,也许是某个地方出了我不知道的问题。而且nginx的debug级别日志只有error才有,看起来也是没什么作用。

这种时候,只能想要万能的办法,用tshark把数据包截获下来再分析。结果数据拿到手才想起来是https加密数据。只有拥有会话密钥才能够读取数据的内容。问题是怎么拿到nginx转发时候的会话密钥呢?查看其中openssl部分的代码也许是个主意,不过有点小题大作。事情实在太多,没时间浪费在这个上面。也许自己写爬虫把网站down下来会更快一点。

再换个办法

我之前用过pyquery,就是python版本的jquery。现在想换个scrapy用用。毕竟现成的爬虫框架会更简单一点。虽然有一定的学习曲线,但是说不定以后还能用上。现在唯一的问题就是如何处理js部分。如果图简单,我可以直接进行手工转换,这样的话只要对方每次更换js我就必须跟在后面重写爬虫,有点蠢。或者python直接解析js后在进行爬虫。据我所知,photomjs就可以做这样的事情。我可以通过selenium和phtomjs再结合scrapy来做。看scrapy的文档,似乎可以通过更换download中间件来实现这个。老实说,我特别讨厌框架。因为虽然很少的代码就能解决问题,但是需要太长的学习曲线了解这些东西的结构。如果没有说明手册,感觉简直糟糕至极。只能通过对自己进行心理暗示,这玩意以后说不定什么时候还用的上做安慰。

可是,我明明不是一个搞前端的啊!唉,不管怎么样,先开工吧。

柳暗花明

正当我在浏览器用F12打开开发者工具准备进行页面检查的时候,奇迹发生了。不知道什么原因,js的部分不见了,页面又变回了普通的html。我不知道发生了什么事,也许有我不知道的事情在发生作用。不过这样一来,wget就又能使用了。果然再使用wget,下载就正常了。

经验总结

很多时候,无论生活还是工作,就像这样,充满了不顺利和不确定性。这些不确定性让人为了一点鸡毛蒜皮的破事绞尽脑汁。如果硬要说能从中学到点什么的话,就是再次知道自己既无知,又愚蠢。这么多年过去了,不管又学会了多少东西,这种无力感始终伴随左右。

photon的镜像暂时搭好了,里面居然还包含了gcc编译器。也许我可以把zabbix客户端编译好放到photon里。md,还得去找header。

后续

wget下载好以后,发现有些文件好像没有。单独找一个文件下了一下。发现是跳转到其他下载域名后文件名过长引起的。这也是为什么反向代理404的原因。其实早该想到的,间歇性智商降低。最后的做法还是最简单的把index下下来用pyquery解析后直接传给wget下载,懒得折腾了。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/usr/bin/env python3
from pyquery import PyQuery as pq
from glob import glob
from urllib.parse import urljoin
import os
import requests
class NetworkError(Exception):
pass
base = 'https://dl.bintray.com/vmware/'
basepath = '/repo/photon/'
repos = ['photon_release_1.0_x86_64/noarch/','photon_release_1.0_x86_64/x86_64/','photon_updates_1.0_x86_64/noarch/','photon_updates_1.0_x86_64/x86_64/','lightwave/x86_64/','photon_extras/noarch/','photon_extras/x86_64/']
def download(repo):
curdir = os.path.join(basepath,repo)
os.chdir(curdir)
current_rpms = set(glob('*.rpm'))
url = urljoin(base,repo)
print(url)
r = requests.get(url)
if r.status_code != 200:
raise NetworkError
else:
d = pq(r.content)
target = set(d('a').text().split()) - current_rpms
for rpm in target:
if not rpm.endswith('.rpm'):
continue
else:
t = urljoin(url,rpm)
os.system('wget -c -t 0 {} -O {}'.format(t,rpm))
def main():
for repo in repos:
download(repo)
if __name__ == "__main__":
main()

我选择了手工建立原数据,如下:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
base=/repo/photon/
repos="/lightwave /photon_extras /photon_release_1.0_x86_64 /photon_updates_1.0_x86_64"
for repo in $repos
do
echo "make repo for photon "${repo}
echo
createrepo -p -d -o ${base}${repo} ${base}${repo}
echo
done