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模块

bash
1
yum install ruby rubygems ruby-devel -y

查看ruby的版本

bash
1
2
3
4
5
6
7
$ 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/

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

安装错误

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

bash
1
2
3
4
5
$ 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源即可

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

升级ruby

  1. 下载rvm
bash
1
2
3
4
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版本
bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ /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
bash
1
/usr/local/rvm/bin/rvm install ruby-1.9.3
  1. 将安装的ruby切换为默认

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

错误:RVM is not a function

bash
1
2
3
4
5
6
$ /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.

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

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

安装低版本fpm

指定版本安装

bash
1
gem install fpm -v 1.4

查看安装完的fpm版本号

bash
1
2
$ fpm --version
1.4.0

卸载一个安装版本

bash
1
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

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

相对路径问题

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

bash
1
2
3
4
5
6
7
8
$ 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

制定依赖包

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

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

bash
1
2
3
4
$ 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

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

bash
1
fpm --post-install 'mysql.sh'

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

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
$ 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并登陆

bash
1
2
3
4
5
6
7
$ /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> 

打包错误

原因未知

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

bash
1
2
$ 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包到此目录,此目录下面还可以包括文件夹

bash
1
mkdir -p /tools/yum/centos6/x86_64

yum下载的文件缓存在

bash
1
/var/cache/yum/x86_64/6/base/

安装createrepo工具

bash
1
yum install -y createrepo

初始化repodata索引文件

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

添加新的rpm包

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

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

bash
1
createrepo --update /tools

本地客户端配置

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

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

bash
1
2
3
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包

bash
1
2
3
4
5
6
7
8
9
$ ls
CentOS_BuildTag  
images                    
...          
Packages                  
RPM-GPG-KEY-CentOS-Security-6

$ ll|wc -l
4186

配置yum源

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

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

bash
1
2
3
4
5
6
7
$ ls /etc/yum.repos.d/
CentOS-Base.repo       
CentOS-fasttrack.repo  
CentOS-Vault.repo  
CentOS-Debuginfo.repo  
CentOS-Media.repo      
epel.repo

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

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[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

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文件的格式

bash
 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
# 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]

变量

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