热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何repack一个RPM包

最近接到一个需求:通用的支持repack一个RPM包。这个需求乍一看并不困难,但是仔细一想,发现有阴谋的味道^_^先了解下RPM包的基本知识。RPM这种格式的文件最初是Redha

最近接到一个需求:通用的支持 repack 一个RPM包。

这个需求乍一看并不困难,但是仔细一想,发现有阴谋的味道^_^

先了解下RPM包的基本知识。

RPM这种格式的文件最初是Redhat 公司发明的,于1997年,现在使用并不局限于Redhat,其他很多linux发行版本都可以使用甚至Ubuntu。

Build一个RPM 包需要(1)准备.spec文件,(2)使用rpmbuild这个工具

一般的RPM包主要由两部分组成:(1)即将被解压的文件(binary 或者source) (2)脚本(包含Install 和 Uninstall 各自的Pre, post 脚本)


OK, 背景知识介绍完毕,我们正式开始说本次的事情,先说结论:RPM不存在repack只有rebuild。举个repack的例子:

我有个foo.jar, 在windows上我用winrar把它给打开,然后把一个.class文件给拖进去,就讲我把这个foo.jar给repack了。

刚开始,我也想对RPM包如法炮制,解开 --> 改东西 --> 包上 --> 愉快的收工!

当我使用命令rpm2cpio (RPM 打包以后使用cpio格式并且使用gzip压缩)把foo.rpm解开以后,出现的确实是我意料中的东西,一坨按照在spec文件中定义路径摆放的文件,当我愉快的修改完这些文件以后,问题渐渐浮出水面,怎么把这坨文件重新打包?

带着这个问题我请教了万能的google,google不说话并扔给我一个stackoverflow,

Unpacking an RPM file and repacking It

这位仁兄的大概步骤是: 解压 -- 修改 --打包, 这不白说吗,如何打包啊,他给出的打包是写一个“dummy”的spec文件重新build, 这不瞎扯吗? 原本spec文件中那些风骚的scriot,比如%pre, %post, %preun以及%postun不都没了吗,那我这原本的RPM不就废了一半多的功力了,实在是瞎扯。

到这里我们得到了一个结论:RPM没repack,只能rebuild,要build一个跟原本功能一样的RPM,得要原本的spec文件!不错啊不错,事情有点起色了。

但是诸君不要得意的太早,新的问题出现了,要描述这个问题,必须先说下RPM build的一些前置知识。

RPM 打包是需要预先定义的,这个定义文件就是.spec文件,就像是Ant写build.xml, maven写pom, c写makefile一样。

打包RPM有几个重要的步骤需要定义在.spec文件中,分别是:

%prep    解压source package并把它放到BUILD这个文件夹中

%build   在BUILD这个文件夹里面把source code给编译了

%install  把编译好的文件按照期望的安装路径摆好然后放到BUILDROOT这个文件夹中

是不是很简单?其实不是,我只是说了个大概,具体用法请参考阐述RPM 打包的文章,这里安利一篇:

如何建立一个RPM包

好了回到我们的问题:之前说过RPM解压后(使用rpm2cpio)得到的是“一坨按照在spec文件中定义路径摆放的文件”,仔细审视下这个分明就是步骤%install的产出物对吧。

所以如果使用原本的.spec文件那%pre和%build步骤肯定就出错了,没有source文件被你解压,已经是binary了也不用你编译对吧。

那怎么办,聪明的小伙伴肯定已经猜到了,那把%pre, %build 和%install删掉不行了?

是的我也是这么想的,但是在此之前我还挣扎过是否可以跳过以上三个步骤,结果是可以跳过%pre和%build,但是%install是铁定要走的,所以扑街。

好的,至此,我们决定愉快的删掉原本.spec文件的%pre, %build和%install步骤,然后进行rebuild,可是一直报错说是BUILDROOT中啥也没有,这不瞎说吗,我是直接把RPM解压到BUILDROOT这个文件夹的,为啥没有? 仔细查看了RPM build的日志,发现了端倪:

+ rm -rf /root/pengli/foo/foo123/BUILDROOT

干嘛给我删掉,没让删啊,在此请教google,google依然不说话,想我扔了一个Redhat 的bug 页面

为啥删掉我的BUILDROOT

看了以后心凉了,虽然有个小哥相比跟我遭受同样的困扰然后想Redhat报了个bug,但是Redhat认为这不是bug,而是一个正常的行为!

This is indeed the intended behavior not a bug.

摊手,我能说什么呢,只好放弃删除%install 而是将%install下的内容替换为把RPM包解压出的那一坨文件拷贝到BUILDROOT,

这下好了,皆大欢喜。

最后要说的是,如果仅仅是要repack某个RPM包,且是偶发行为,完全可以按照以上思路手动完成,可是如果是common的需求,你就需要一个脚本了。

脚本我已经写好了,隔天上传到github。

github地址:

https://github.com/vincent-pli/my-toolkit 


推荐阅读
author-avatar
CPA娇_588
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有