本文发布于Cylon的收藏册,转载请著名原文链接~


rpm与fpm

软件的安装方式

  • 编译安装:优点是可以定制化安装目录、按需开启功能等,缺点是需要查找并实验出适合的编译参数,诸如MySQL之类的软件编译耗时过长
  • yum安装:优点是全自动化安装,不需要为依赖问题发愁,缺点是自主性太差,软件的功能、存放位置都已经固定好了,不易变更。
  • 编译源码:根据自己的需求做成 RMP包 ==> 搭建yum仓库 ==> yum安装。结合前两者的优点,暂未发现什么缺点。可能的缺点就是RPM包的通用性差,一般人不会定制RPM包。

RPM概述

RPM全称是Red Hat Package Manager(RedHat包管理器)。几乎所有的Linux发型版本都使用这种形式的软件包管理安装、更新和卸载软件。

rpm命令有5种基本功能(不包括创建软件包):安装、卸载、升级、查询和验证。

关于rpm命令的使用可以用rpm –help来获得

rpmbuild

rpmbuild是reahat系的原声打包命令,这个命令的使用难点主要在于spec文件编写,一个类似于kickstart的ks.cfg文件。

作为一个使用工具,种种繁琐,在没有替代品时还能存活。当有了其他简易工具时,他就到了完蛋的时候

fpm

fpm 是将一种类型的包转换成另一种类型

支持的源类型包

类型 说明
dir 将目录打包成所需要的类型,可以用于源码编译安装的软件包
rpm 对rpm进行转换
gem 对rubygem包进行转换
python 将python模块打包成相对应的类型
支持目标类型包
rpm 转换为rpm包
deb 转换为deb包
solaris 装环卫solaris包
puppet 转换为puppet模块

fpm安装

fpm是ruby写的,因此系统环境需要ruby,而且ruby版本号大于bshards运行的版本。

yum安装ruby模块

yum install ruby rubygems ruby-devel -y

查看ruby的版本

$ rpm -qa|grep ruby
ruby-libs-1.8.7.374-4.el6_6.x86_64
rubygems-1.3.7-5.el6.noarch
ruby-1.8.7.374-4.el6_6.x86_64
ruby-rdoc-1.8.7.374-4.el6_6.x86_64
ruby-devel-1.8.7.374-4.el6_6.x86_64
ruby-irb-1.8.7.374-4.el6_6.x86_64

替换gem源

ruby中国镜像:https://ruby-china.org/

gem source -a http://gems.ruby-china.org
  • -r remove xx 删除一个gem源列表
  • -l list gem源列表

安装错误

此问题提示 ruby的版本至少要求为1.9.3,在我们yum安装的ruby为1.8.7

$ gem install fpm
Building native extensions.  This could take a while...
Building native extensions.  This could take a while...
ERROR:  Error installing fpm:
        ruby-xz requires Ruby version >= 1.9.3.

解决方法:

  1. 升级ruby版本

  2. 安装低版本fpm

ERROR: Could not find a valid gem 'fpm' (>= 0) in any repository

原因:gem源失效,替换gem源即可

ERROR:  Could not find a valid gem 'fpm' (>= 0) in any repository

升级ruby

  1. 下载rvm
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
curl -sSL https://get.rvm.io | bash -s stable
# 如果上面的连接失败,可以尝试: 
curl -L https://raw.githubusercontent.com/wayneeseguin/rvm/master/binscripts/rvm-installer | bash -s stable

rvm会下载安装到/usr/local/rvm下

  1. 列出已知的ruby版本
$ /usr/local/rvm/bin/rvm list known
# MRI Rubies
[ruby-]1.8.6[-p420]
[ruby-]1.8.7[-head]$  security released on head
[ruby-]1.9.1[-p431]
[ruby-]1.9.2[-p330]
[ruby-]1.9.3[-p551]
...
[ruby-]2.3[.3]
[ruby-]2.4[.0]
ruby-head
...
# IronRuby
ironruby[-1.1.3]
ironruby-head
  1. 按照提示安装ruby1.9.3
/usr/local/rvm/bin/rvm install ruby-1.9.3
  1. 将安装的ruby切换为默认

如果想设置为默认版本,这样一来以后新打开的控制台默认的 Ruby 就是这个版本

错误:RVM is not a function

$ /usr/local/rvm/bin/rvm use 1.9.3 --default
RVM is not a function, selecting rubies with 'rvm use ...' will not work.

You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for an example.

原因:需要添加到系统变量

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" 
source /etc/profile 

安装低版本fpm

指定版本安装

gem install fpm -v 1.4

查看安装完的fpm版本号

$ fpm --version
1.4.0

卸载一个安装版本

rvm remove 1.9.2

https://www.ruby-lang.org/zh_cn/downloads/

编译安装ruby

参考资料:

fpm使用

参数 说明
-s 指定源类型
-t 指定目标类型,即想要制作为什么包
-n 指定包的名字
-v 指定包的版本号
-C 指定打包的相对路径
-d 指定依赖于哪些包
-f 第二次包时目录下如果有同名安装包存在,则覆盖它
-p 输出的安装包的目录,不想放在当前目录下就需要指定
–post-install 软件包安装完成之后所要运行的脚本;同–offer-install
–pre-install 软件包安装完成之前所要运行的脚本;同–before-install
–post-uninstall 软件包卸载完成之后所要运行的脚本;同–offer-remove
–pre-uninstall 软件包卸载完成之前所要运行的脚本;同—before-remove

yum安装是如何解决依赖问题的?

在使用yum安装软件A时,yum会在下载完A的rpm包后,对该rpm包进行检查(rpm包会给出安装该rpm包所依赖的基础库和软件)。如果检查出A的安装还要依赖软件B,那么此时yum就会自动下载并安装B。B安装完毕后,就会继续安装A。如果是内网yum源的话,我们只需要把B放在内网yum源即可。如果检查出A的安装不需要其他软件的支持,那么yum会自动安装A。因此使用rpm -d添加依赖关系

打包fpm

fpm -s dir -t rpm -n sphinx -v 5.5.54 -d 'libaio-devel,ncurses-devel' --post-install /app/mysql.sh /app/mysql

相对路径问题

使用相对路径打包,会直接保存为/目录。这样就不会是我们指定的目录了。

$ rpm -pql sphinx-1.0-1.x86_64.rpm       
/bin/indexer
/bin/indextool
/bin/searchd
...
/var/data/test1stemmed.spp
/var/data/test1stemmed.sps
/var/log

制定依赖包

fpm -d 'libaio-devel,ncurses-devel'

在安装时就会检测依赖包,如无此包就报错

$ rpm -ivh mysql-5.5.54-1.x86_64.rpm 
error: Failed dependencies:
        libaio-devel is needed by mysql-5.5.54-1.x86_64
        ncurses-devel is needed by mysql-5.5.54-1.x86_64

安装完成后指定要执行的脚本

fpm --post-install 'mysql.sh'

本地模拟yum安装自己打包的软件

$ yum localinstall mysql-5.5.54-1.x86_64.rpm 
已加载插件:fastestmirror, security
设置本地安装进程
诊断 mysql-5.5.54-1.x86_64.rpm: mysql-5.5.54-1.x86_64
mysql-5.5.54-1.x86_64.rpm 将被安装
....
....
Non-fatal POSTIN scriptlet failure in rpm package mysql-5.5.54-1.x86_64
useradd: user 'mysql' already exists # 安装后执行脚本中创建的用户,因已创建用户,故提示
warning: %post(mysql-5.5.54-1.x86_64) scriptlet failed, exit status 9

已安装:
  mysql.x86_64 0:5.5.54-1                                                                                       

作为依赖被安装:
libaio-devel.x86_64 0:0.3.107-10.el6   ncurses-devel.x86_64 0:5.7-4.20090207.el6                

作为依赖被升级:
ncurses-base.x86_64 0:5.7-4.20090207.el6  ncurses-libs.x86_64 0:5.7-4.20090207.el6

初始化后启动MySQL并登陆

$ /etc/init.d/mysqld start
Starting MySQL.. SUCCESS! 
$ bin/mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
..
mysql> 

打包错误

原因未知

解决方法:可能是打包时会产生大量的缓存,导致空间不够,删除一些文件后问题再没出现过

$ fpm -s dir -t rpm -n mysqld -v 5.5.54 -f --post-install /app/m.in.sh --post-uninstall /app/un.m.sh /app/mariadb-5.5.54/
Process failed: rpmbuild failed (exit code 1). Full command was:["rpmbuild", "-bb", "--define", "buildroot /tmp/package-rpm-build-2570d4ce573d6b34f9153009975231fe511bee89c64018c2c7e219355d61/BUILD", "--define", "_topdir /tmp/package-rpm-build-2570d4ce573d6b34f9153009975231fe511bee89c64018c2c7e219355d61", "--define", "_sourcedir /tmp/package-rpm-build-2570d4ce573d6b34f9153009975231fe511bee89c64018c2c7e219355d61", "--define", "_rpmdir /tmp/package-rpm-build-2570d4ce573d6b34f9153009975231fe511bee89c64018c2c7e219355d61/RPMS", "--define", "_tmppath /tmp", "/tmp/package-rpm-build-2570d4ce573d6b34f9153009975231fe511bee89c64018c2c7e219355d61/SPECS/mysqld.spec"] {:level=>:error}

YUM

什么是yum

yum主要用于自动安装、升级rpm软件包,他能自动查找并解决rpm包之间的依赖关系。要成功的使用yum工具安装更新软件或系统,就需要有一个包含各种rpm软件包的repository(软件仓库),这个软件仓库我们习惯称为yum源,网络上有大量的yum源,但由于收到网络环境的限制,导致软件安装耗时过长甚至失败。特别是当有大量服务器大量软件包需要安装时,缓慢的进度条令人难以忍受。因此我们在优化系统时,都会更换国内的源。

相比较而言,本地yum源服务器最大优点是局域网的快速网络连接和稳定性。有了局域网中的yum源服务器,即使在internet连接中断的情况下,也不会影响其他yum客户端的软件安装和升级

创建yum源

上传rpm包到此目录,此目录下面还可以包括文件夹

mkdir -p /tools/yum/centos6/x86_64

yum下载的文件缓存在

/var/cache/yum/x86_64/6/base/

安装createrepo工具

yum install -y createrepo

初始化repodata索引文件

$ createrepo -pdo /tools/yum/centos6/x86_64/ /tools/yum/centos6/x86_64/
Spawning worker 0 with 4 pkgs
Workers Finished
Gathering worker results

Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete

$ cd /tools/yum/centos6/x86_64/

$ ls
libaio-devel-0.3.107-10.el6.i686.rpm
libaio-devel-0.3.107-10.el6.x86_64.rpm
ncurses-devel-5.7-4.20090207.el6.i686.rpm
ncurses-devel-5.7-4.20090207.el6.x86_64.rpm
repodata

$ ls repodata/.
1453d96f9216e7c230abfe7921a2fd1dd11541568934832306342c89ad04ff1d-other.sqlite.bz2
2475630f1247fc6ac2b822541d6ad71ed83d733792c7d52de580fdebd3abda2c-filelists.sqlite.bz2
9e22eb60f06501a3f4399dc3c2d3e3858567804e7ab352679fa650b93d279fb9-other.xml.gz
c3ee9c8d8508c55c77f3f058f056bdd617587ee5a906f22bc9a512bc8b950ded-filelists.xml.gz
d9d57f7733cb42831001e915ddd51bb126b67c26bca64bf6c7e7390eed9a54d9-primary.sqlite.bz2
e9616244b93c46350e33dc04d4cb442e49ae375b7400a262bd72e8ba90a1f4a8-primary.xml.gz
repomd.xml

提供yum服务

可以用apache或nginx提供web服务,但用Python的http模块更简单,适用于内网环境。CentOS 6最小化安装后自带python。

  1. 利用python的http模块提供服务
python -m SimpleHTTPServer 80 &>/dev/null
# 提供服务的目录是执行命令时的目录
  1. 利用nginx提供yum源服务
location / {
    root   /tools;
    index  index.html index.htm;
	autoindex on; # 当找不到首页文件时,会展示目录结构,这个功能一般不要用除非有需求。
# 如没有此选项,会报403
}

添加新的rpm包

# 只下载软件不安装
yumdownlocaler pcre-devel openssl-devel

每当该目录新增软件包需要更新源

createrepo --update /tools

本地客户端配置

/etc/yum.repos.d/test.repo
[test]
name=Server
baseurl=http://192.168.2.110
enable=1
gpgchek=0

使用配置的自定义的源安装PHP

yum --enablerepo=test --disablerepo=base,extras,updates install php
# --enbalerepo使用的源
# --disablerepo禁用源

yum命令

选项 说明
install 安装软件包 yum install httpd
list 列出yum仓库内文件 yum list httpd,可搜索带名称的特定软件包
search 不急的软件报的确切名称,可以使用search函数,搜索与指定软件包的名称相匹配的所有可用软件包yum search httpd
provides 查找某个特定文件属于哪个软件包。yum provides /app/apache/confi/http.conf
grouplist 列出所有可用群组
groupinstall 安装群组软件包yum groupinstall develment-tools
repolist 列出启用的软件库
repolist all 列出所有软件库,包括禁用的也列出
–enablerepo 安装来自特定软件库的软件包
–disablerepo 不安装来自指定软件库的软件包yum –enablerepo=test –disablerepo=base,extras… install httpd
chean all 清理yum缓存内容
history 查看yum历史记录

yum源

Yum源分为三大类:

  • Base:就是你下载的光盘镜像里面的DVD1
  • Extra:就是你下载光盘镜像的DVD2
  • Epel:属于额外的,得到Epel官方获取

将光盘挂载到系统上,你会发现里面有个packages目录,里面全是rpm包

$ ls
CentOS_BuildTag  
images                    
...          
Packages                  
RPM-GPG-KEY-CentOS-Security-6

$ ll|wc -l
4186

配置yum源

找一个镜像站点,国内常用镜像站点

系统yum源路径,执行yum时,它只会读取yum.repo.d下这个目录下的所有以.repo结尾的文件。

$ ls /etc/yum.repos.d/
CentOS-Base.repo       
CentOS-fasttrack.repo  
CentOS-Vault.repo  
CentOS-Debuginfo.repo  
CentOS-Media.repo      
epel.repo

repo文件的写入是有其特殊格式的,如下:

[aaa]
name=aaa
baseurl=http://192.168.2.110
enable=1
gpgchek=0
[bbb]
name=bbb
baseurl=http://192.168.2.110
enable=1
gpgchek=0
[ccc]
name=ccc
baseurl=http://192.168.2.110
enable=1
gpgchek=0

所谓的自己配置Yum仓库就是把网上那些程序包全下载下来,在本地(内网)提供Yum。除了epel提供的所有包外,还有镜像光盘DVD1,DVD2!

yum服务配置文件

配置文件分为两部分main和repository

配置本地yum源

禁用默认的yum网络源,将yum网络源配置文件改名为CentOS-Base.repo.bak,否则会现在网络源中寻找适合的包,改名之后直接从本地源读取。也可以向上面一样自己写一个文件。

全局配置文件

main部分定义了全局配置选项,整个yum配置文件应该只有一个main,/etc/yum.conf

# /etc/yum.conf
[main]
# cachedir:yum缓存的目录,yum在此存储下载的rpm包和数据库,一般是/var/cache/yum/$basearch/$releasever。
cachedir=/var/cache/yum/$basearch/$releasever
# 设置 keepcache=1,yum 在成功安装软件包之后保留缓存的头文件 (headers) 和软件包。默认值为 keepcache=0 不保存
keepcache=[1 or 0]
# debuglevel:除错级别,0──10,默认是2 貌似只记录安装和删除记录
debuglevel=2
logfile=/var/log/yum.log
# pkgpolicy: 包的策略。一共有两个选项,newest和last,这个作用是如果你设置了多个repository,而同一软件在不同的repository中同时存 在,yum应该安装哪一个,如果是newest,则yum会安装最新的那个版本。如果是last,则yum会将服务器id以字母表排序,并选择最后的那个 服务器上的软件安装。一般都是选newest。
pkgpolicy=newest
# 指定一个软件包,yum会根据这个包判断你的发行版本,默认是RedHat-release,也可以是安装的任何针对自己发行版的rpm包
distroverpkg=CentOS-release
# tolerent,也有1和0两个选项,表示yum是否容忍命令行发生与软件包有关的错误,比如你要安装1,2,3三个包,而其中3此前已经安装了,如果你设为1,则yum不会出现错误信息。默认是0。
tolerant=1
# exactarch,有两个选项1和0,代表是否只升级和你安装软件包cpu体系一致的包,如果设为1,则如你安装了一个i386的rpm,则yum不会用1686的包来升级。
exactarch=1
# retries,网络连接发生错误后的重试次数,如果设为0,则会无限重试。
retries=20
obsoletes=1
# gpgchkeck= 有1和0两个选择,分别代表是否是否进行gpg校验,如果没有这一项,默认是检查的。
gpgcheck=1
# 该选项用户指定 .repo 文件的绝对路径。.repo 文件包含软件仓库的信息 (作用与 /etc/yum.conf 文件中的 [repository] 片段相同)。
reposdir=[包含 .repo 文件的目录的绝对路径] # 默认是 /etc/yum.repos.d/ 低下的 xx.repo后缀文件
# exclude 排除某些软件在升级名单之外,可以用通配符,列表中各个项目要用空格隔开,这个对于安装了诸如美化包,中文补丁的朋友特别有用。
exclude=xxx

第二部分repoitory

repoitory部分定义了每个源/服务器的具体配置,可以有一到多个,位于/etc/yum.repos.d/目录下的各文件中。这个字段其实也可以在yum.conf里面直接配置

repo文件的格式

# serverid用于区别各个不同的repository,必须有一个独一无二的名称。 重复了前面覆盖后面--还是反过来呢???用enabled 测试是后面覆盖前面
[serverid]
# name是对repository的描述,支持像$releasever $basearch这样的变量; name=Fedora Core $releasever - $basearch - Released Updates
name=Some name for this server
# baseurl是服务器设置中最重要的部分,只有设置正确,才能从上面获取软件。它的格式是:
# 其中url支持的协议有 http:// ftp:// file://三种。baseurl后可以跟多个url,你可以自己改为速度比较快的镜像站,但baseurl只能有一个,也就是说不能像如下格式:
baseurl=url://server1/path/to/repository/
baseurl=url://server2/path/to/repository/
baseurl=url://server3/path/to/repository/
其中url指向的目录必须是这个repository header目录的上一级,它也支持$releasever $basearch这样的变量。
baseurl=url://path/to/repository/
baseurl=url://server1/path/to/repository/
url://server2/path/to/repository/
url://server3/path/to/repository/
# 这一行是指定一个镜像服务器的地址列表,通常是开启的,本例中加了注释符号禁用了,我们可以试试,将$releasever和$basearch替换成自己对应的版本和架构,例如10和i386,在浏览器中打开,我们就能看到一长串镜可用的镜像服务器地址列表。
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$releasever&arch=$basearch
url之后可以加上多个选项,如gpgcheck、exclude、failovermethod等,比如:
# 其中gpgcheck,exclude的含义和[main]部分相同,但只对此服务器起作用
gpgcheck=1
exclude=gaim
# failovermethode 有两个选项roundrobin和priority,意思分别是有多个url可供选择时,yum选择的次序,roundrobin是随机选择,如果连接失 败则使用下一个,依次循环,priority则根据url的次序从第一个开始。如果不指明,默认是roundrobin。
failovermethod=priority
# 当某个软件仓库被配置成 enabled=0 时,yum 在安装或升级软件包时不会将该仓库做为软件包提供源。使用这个选项,可以启用或禁用软件仓库。
# 通过 yum 的 --enablerepo=[repo_name] 和 --disablerepo=[repo_name] 选项,或者通过 PackageKit 的"添加/删除软件"工具,也能够方便地启用和禁用指定的软件仓库
enabled=[1 or 0]

变量

$releasever,发行版的版本,从[main]部分的distroverpkg获取,如果没有,则根据redhat-release包进行判断。
$arch,cpu体系,如i686,athlon等
$basearch,cpu的基本体系组,如i686和athlon同属i386,alpha和alphaev6同属alpha。

本文发布于Cylon的收藏册,转载请著名原文链接~

链接:https://www.oomkill.com/2016/12/fpm/

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。