使用fpm创建RPM或deb包

使用fpm创建RPM或deb包

为了实现运维自动化和标准化,我的团队内部自己使用了很多标准配置模板和自定义脚本呢。
为了把这些模板在服务器部署阶段就统一,之前用了kickstart的Post-install脚本完成。

后来发现其实也可以将这些配置和自定义脚本统一打成一个rpm包,加入到自己的源中。
在安装阶段直接安装即可。

打包工具我们选择了fpm,选择的理由就是fpm简单易用,入手极快,下面说说大概。

0.修改rubygems的源

由于国内网络原因,导致 rubygems.org 存放在 Amazon S3 上面的资源文件间歇性连接失败。
所以需要改成taobao提供的源。这是一个完整 rubygems.org 镜像,可以用此代替官方版本,同步频率目前为15分钟一次。

yum install ruby rubygems ruby-dev

或者

apt install ruby rubygems ruby-dev

切换源

gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/

gem sources -l

*** CURRENT SOURCES ***
http://ruby.taobao.org # 请确保只有 ruby.taobao.org

1.安装fpm

gem install fpm

2.fpm的常用命令格式

$ fpm -s -t [options]
source type:dir,rpm,gem,python
target type:rpm,deb,solaris,puppet
常用的options:
-n 生成的package名字
-p 生成的package文件输出位置
-C fpm去哪个目录搜寻文件
-v 生成的package版本
-d 生成的package依赖于什么软件,通常为-d 'name' 或这 -d 'name > version'
-a 系统架构名称,如果是noarch则为'-a all' 或者 '-a native'
--description 软件包描述
--conflicts 与其他什么软件冲突

3.使用示例

我们以一个常见的tar.gz源码包安装的软件作为示例:

常规编译过程

    $ wget http://nodejs.org/dist/v0.6.0/node-v0.6.0.tar.gz
    $ tar -zxf node-v0.6.0.tar.gz
    $ cd node-v0.6.0
    $ ./configure --prefix=/usr
    $ make

将编译好的二进制文件安装到打包临时目录

$ mkdir /tmp/installdir
$ make install DESTDIR=/tmp/installdir

注: 尽管DESTDIR参数是GNU推荐支持的,但仍有部分软件不支持。
例如PHP就不支持,不过一般它们支持INSTALL_ROOT。

创建rpm包,仅包含usr/bin 和 usr/lib目录,依赖于libssl和libstdc++包:

    $ fpm -s dir -t rpm -n nodejs -v 0.6.0 -C /tmp/installdir 
      -p nodejs-VERSION_ARCH.deb 
      -d "libssl0.9.8 (> 0)" 
      -d "libstdc++6 (>= 4.4.3)" 
      usr/bin usr/lib

就这么简单,一个属于我们自己的rpm包就出现了!
不用费劲修改什么SPEC文件!

使用fpm我们还可以将任何指定的目录打成一个rpm包!
例如我们可以将/etc/init.d下的脚本统一打成一个rpm包:

$ fpm -s dir -t rpm -n myinitfiles -v 1.0 -C /etc/init.d
...
Created /home/singer/rpm/myinitfiles-1.0.x86_64.rpm

$ rpm -qp myinitfiles-1.0.x86_64.rpm -l
/etc/init.d
/etc/init.d/.legacy-bootordering
/etc/init.d/NetworkManager.dpkg-backup
...

$ rpm -qp myinitfiles-1.0.x86_64.rpm --provides
myinitfiles = 1.0-1
$ rpm -qp myinitfiles-1.0.x86_64.rpm --requires
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1

4.进阶话题

我们自己定义的rpm需要写入一些注释,还有要创建一些账号,这些可以通过"-e"参数在fpm生成rpm之前编辑。

例如:
$ rpm -qp myinitfiles-1.0.x86_64.rpm --info | grep Summary
Summary : no summary given

$ fpm -s rpm -t rpm -e myinitfiles-1.0.x86_64.rpm

这里会自动打开你系统$EDITOR变量所定义的文本编辑器,我们可以直接编辑fpm自动生成的SPEC文件。
按照SPCE文件的语法,随意添加我们需要的内容,例如: Summary,%pre,%post脚本等。

$ rpm -qp myinitfiles-1.0-1.x86_64.rpm --info | grep Summary
Summary : my /etc/init.d directory

不过fpm提供了更简单的编辑%pre和%post脚本的方法,就是指定如下options:

--after-install FILE a script to be run after package installation
--before-install FILE a script to be run before package installation
--after-remove FILE a script to be run after package removal
--before-remove FILE a script to be run before package removal

举例来说,为了给软件创建一个运行账号,我们可以使用如下脚本:

$ vi ~/addusertorpm.sh

#!/bin/bash
GROUPNAME=demouser
USERNAME=demouser
HOMEDIR=/somewhere
getent group $GROUPNAME >/dev/null || groupadd -r $GROUPNAME
getent passwd $USERNAME >/dev/null || useradd -r -g $GROUPNAME -d $HOMEDIR -s /sbin/nologin -c "Useful comment about the purpose of this account" $USERNAME
exit 0

$ fpm -s dir -t rpm -n myinitfiles -v 1.0 --before-install addusertorpm.sh /etc/init.d

$ rpm -qpl --scripts myinitfiles-1.0-1.x86_64.rpm
preinstall scriptlet (using /bin/sh):

!/bin/bash

GROUPNAME=demouser
USERNAME=demouser
HOMEDIR=/somewhere
getent group $GROUPNAME >/dev/null || groupadd -r $GROUPNAME
getent passwd $USERNAME >/dev/null || useradd -r -g $GROUPNAME -d $HOMEDIR -s /sbin/nologin -c "Useful comment about the purpose of this account" $USERNAME
exit 0
/etc/init.d
/etc/init.d/.legacy-bootordering
/etc/init.d/NetworkManager.dpkg-backup
...

fpm的功能很强大,用法却很简单,如果需要进一步了解,请去其官方主页看详细文档。

用PCRE做个完整过程的示例:

$ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.32.tar.bz2
$ tar xvjf pcre-8.32.tar.bz2
$ ./configure --prefix=/usr 
 --docdir=/usr/share/doc/pcre-8.32
 --enable-utf --enable-unicode-properties
 --enable-pcregrep-libz --enable-pcregrep-libbz2
$ make
$ make check
$ mkdir /tmp/installdir
$ make install DESTDIR=/tmp/installdir
$ fpm -s dir -t rpm -n PCRE -v 8.32 -C /tmp/installdir/usr/
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.zTWxge
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.EN6rDC
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.NXtL00
Processing files: PCRE-8.32-1.x86_64
Wrote: /tmp/package-rpm-build20130108-57455-1xr9udi/RPMS/x86_64/PCRE-8.32-1.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.BK1BRQ
Created rpm {"path":"PCRE-8.32-1.x86_64.rpm"}

再举一个将本地python程序包转成rpm的例子:

$ wget http://parallel-ssh.googlecode.com/files/pssh-2.3.1.tar.gz
$ tar xvzf pssh-2.3.1.tar.gz
$ ls pssh-2.3.1/setup.py
pssh-2.3.1/setup.py
$ fpm -s python -t rpm pssh-2.3.1/setup.py
Created rpm {:path=>"python-pssh-2.3.1-1.noarch.rpm"}

参考文档:

https://github.com/jordansissel/fpm/wiki
http://www.ducea.com/2011/08/31/build-your-own-packages-easily-with-fpm/
https://fedoraproject.org/wiki/Packaging:UsersAndGroups
http://www.semicomplete.com/blog/tags/deb
http://www.lampblog.net/ubuntu/getent命令/
https://lists.berlios.de/pipermail/sorcerer-admins/2010/001769.html

end.

原文地址:https://www.cnblogs.com/sixloop/p/7645373.html