• 使用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.

  • 相关阅读:
    [Linux] crontab和shell每天定时备份数据库
    [Go] 实战项目在线客服GO-FLY -在gin框架使用IP识别库转换IP为城市
    [javascript] elementui和vue下复制粘贴上传图片
    [Go] GO-FLY客服项目被公众号 "转角遇到GitHub " 推荐
    [javascript] cdn模式下vue和vue-router实现路由
    [Go] Golang发送http GET请求
    [MySQL] 利用explain查看sql语句中使用的哪个索引
    [Go]GO语言实战-小程序或公众号接口gin框架验证微信服务器消息签名-开源WEB客服
    [Go]GO语言实战-开源WEB客服GO-FLY-gorm下分页的实现
    [前端] 设定为disabled的表单域值不能被提交
  • 原文地址:https://www.cnblogs.com/sixloop/p/7645373.html
Copyright © 2020-2023  润新知