# yum使用tips

## 找到系统尚未安装的工具命令属于哪个rpm包

经常会在需要使用某个工具软件的时候，不知道应该安装哪个rpm软件包。虽然 [rpm.pbone.net](http://rpm.pbone.net/) 提供了在线搜素软件包的功能，不过，对于使用YUM管理的服务器，实际上可以通过`yum provides`命令来找到对应软件包，或者使用`yum whatprovides`命令。

以下举例寻找哪个软件包提供了命令`lssubsys`

```bash
yum provides pstack

yum whatprovides pstack
```

输出显示

```bash
Loaded plugins: branch, fastestmirror
Loading mirror speeds from cached hostfile
alios.7u2.base.x86_64/x86_64/filelists_db      | 6.7 MB  00:00:00
ops.7.noarch/7/filelists_db                    | 182 kB  00:00:00
ops.7.x86_64/7/x86_64/filelists_db             | 309 kB  00:00:00
taobao.7.noarch.stable/filelists_db            |  48 kB  00:00:00
taobao.7.x86_64.stable/filelists_db            |  11 MB  00:00:00
gdb-7.6.1-80.1.alios7.x86_64 : A GNU source-level debugger for C, C++, Fortran, Go and other languages
Repo        : alios.7u2.base.x86_64
Matched from:
Filename    : /usr/bin/pstack
```

可以看到`gdb`软件包提供了该`pstack`工具命令。

> 参考[How to find out which package a file belongs to?](http://unix.stackexchange.com/questions/4705/how-to-find-out-which-package-a-file-belongs-to)

## yum使用代理服务器

有时候需要使用[polipo](/cloud-atlas-draft/service/proxy/polipo.md)这样的代理服务器访问internet资源，如果偶尔使用yum安装软件包，可以设置**当前用户**环境变量`http_proxy`来实现安装：

```bash
export http_proxy="http://PROXY_IP:8123"
yum upgrade
yum install XXXX
```

如果要一直使用代理服务器方式，则修改`/etc/yum.conf`配置文件，添加：

```bash
# The proxy server - proxy server:port number
proxy=http://PROXY_IP:8123
# The account details for yum connections
proxy_username=yum-user
proxy_password=qwerty
```

> 参考[Using yum with a Proxy Server](https://www.centos.org/docs/5/html/yum/sn-yum-proxy-server.html)

## 查看软件包属于哪个仓库

* `yum list 软件包`可以显示软件包的详细版本，并且可以显示软件包属于哪个软件库

在[部署oVirt](/cloud-atlas-draft/iaas/ovirt/deploy_ovirt.md) v3.6 的时候，在engine关机控制台添加host后，软件包安装到node节点的时候出现报错：

```bash
RuntimeError: Cannot locate gluster packages, possible cause is incorrect channels
2016-06-10 11:38:59 ERROR otopi.context context._executeMethod:165 Failed to execute stage 'Setup validation': Cannot locate gluster packages, possible cause is incorrect channels
```

我检查了是可以安装`glusterfs`和`glusterfs-cli`软件包的，但是`yum search vdsm`却只有`vdsm-jsonrpc-java.noarch`，不像以前安装的ovrit节点有大量的`vdsm`软件包。[Ovirt 3.5 problem adding GlusterFS servers](http://permalink.gmane.org/gmane.comp.emulators.ovirt.user/26370) 提示需要检查服务器即诶单是否有`vdsm-gluster`软件包。

检查 `/usr/share/ovirt-host-deploy/plugins/ovirt-host-deploy/gluster/packages.py` 果然有：

```python
    def _validation(self):
        if not self.packager.queryPackages(patterns=('vdsm-gluster',)):
            raise RuntimeError(
                _(
                    'Cannot locate gluster packages, '
                    'possible cause is incorrect channels'
                )
            )
        self._enabled = True

    @plugin.event(
        stage=plugin.Stages.STAGE_PACKAGES,
        condition=lambda self: self._enabled,
    )
    def _packages(self):
        self.packager.installUpdate(('vdsm-gluster',))
```

那么究竟是谁提供了这个软件包？在节点上使用命令`yum list vdsm-gluster`发现是最早安装的`ovirt-3.5`提供了这个软件包（后来又升级到ovirt-3.6反而没有这个软件包）

```bash
vdsm-gluster.noarch                                              4.16.26-0.el6                                               @ovirt-3.5
```

检查 <http://resources.ovirt.org/pub/ovirt-3.5/rpm/el6Server/noarch/> 果然有这个软件包，而且版本要高于EPEL提供的版本。所以删除掉EPEL仓库，添加 `@ovirt-3.5` 仓库，即再增加 `/etc/yum.repos.d/ovirt-3.5.repo` （和`ovirt-3.6.repo`并存，内容是从`ovirt-3.6.repo`复制并修改版本号成`3.5`）。这样就可以使用`ovirt 3.5`仓库中的软件包，同时由于`ovirt 3.6`中相关软件版本较新，也不会错误覆盖

```bash
[ovirt-3.5]
name=Latest oVirt 3.5 Release
#baseurl=http://resources.ovirt.org/pub/ovirt-3.5/rpm/el$releasever/
mirrorlist=http://resources.ovirt.org/pub/yum-repo/mirrorlist-ovirt-3.5-el$releasever
enabled=1
skip_if_unavailable=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-ovirt-3.5
```

> 总之，使用`yum list 软件包`名字可以找寻出对应的软件仓库，也就可以进一步排查问题的原因

## 避免升级部分软件包

如果由于一些原因需要保持系统中某些软件包不升级，如兼容性，特定测试，则可以通过在`/etc/yum.conf`中添加 `exclude=`配置行来跳过：

```
## Exclude following Packages Updates ##
exclude=perl php python
```

举例，如果要过滤掉所有32位软件包:

```
exclude=*.i?86 *.i686
```

命令行也可以传递给yum需要屏蔽的软件包，例如:

```
yum --exclude=glibc\* update
```

就不会升级 glibc。并且 `--exclude=` 参数也可以使用 `-x` 来代替，上述命令就是

```
yum -x 'glibc\*' update
```

要传递多个不包含的包

```
yum --exclude=glibc\* --exclude=cloud-init\* update
```

如果要比较好地管理不包含的软件包，则可以用分开的配置版本，例如 `/etc/yum.repos.d/mongodb.repo` 包含mangodb的管理配置

```
exclude=mongo*
```

如果要临时关闭exclude，可以使用命令

```
yum --disableexcludes=all update
```

或者

```
yum --disableexcludes=mongodb update
```

### yum versionlock插件

* 可以通过 `yum-versionlock` 实现版本锁定：

```
yum install -y yum-versionlock
```

* 然后检查 `/etc/yum/pluginconf.d/versionlock.conf` 有内容

```
[main]
enabled = 1
locklist = /etc/yum/pluginconf.d/versionlock.list
#  Uncomment this to lock out "upgrade via. obsoletes" etc. (slower)
# follow_obsoletes = 1
```

* 在 `/etc/yum/pluginconf.d/versionlock.list` 添加要锁定的版本:

```
kernel-3.10.0-693.2.2.el7
```

## 关闭repo仓库升级

* 检查当前仓库

```
yum repolist
```

* 关闭某个仓库升级

```
yum --disablerepo=reponame update
```

当然也可以直接编辑仓库配置文件，将配置文件修改成 `enabled=0` 也就关闭了该仓库使用。

## `yum update`和`yum upgrade`的差别

> 参考 [yum update和upgrade的区别？](https://segmentfault.com/q/1010000008228111)

`yum update`和`yum upgrade`的功能是一样的，都是将需要更新的package更新至软件源中的最新版。唯一不同是：`yum upgrade`会删除旧版本的package，而`yum update`则会保留。

注意！如果你的某些软件依赖旧版本的package，请使用`yum update`。

在[yum equivalent to apt-get upgrade vs apt-get dist-upgrade?](https://serverfault.com/questions/298146/yum-equivalent-to-apt-get-upgrade-vs-apt-get-dist-upgrade/298158#298158)有详细说明：

`yum update`只是升级软件包到新版本。例如，`foo-awesome`淘汰替换了`foo`，但是`yum update`不会将`foo`更改升级成`foo-awesome`。必须加上`--obsoletes`这个开关这样`yum update`才会进行扩展检查来提供更新路径。

而`yum upgrade`则相当于`yum --obsoletes update`，也就是可以直接将旧软件包体换成新的软件包，这样`foo`就会被升级体换成`foo-awesome`。通常，由于某些软件依赖旧版本软件包来运行，则应该使用`yum update`，如果没有这种旧版兼容要求，则可以使用`yum upgrade`，以便能够使用最新的软件体系。

> 在线维护的服务器，通常求稳定，可能使用`yum update`较安全一些。此外，需要做好完整的兼容稳定性测试。

如果希望`yum update`时避免更新内核，可以使用`yum --exclude=kernel* update`。见前述**避免升级部分软件包**，通过配置文件`yum.conf`也可以达到相同效果。

## 参考

* [CentOS / RHEL : How to exclude kernel or other packages from getting updated using YUM Versionlock Plugin](https://www.thegeekdiary.com/centos-rhel-how-to-exclude-kernel-or-other-packages-from-getting-updated-using-yum-versionlock-plugin/)
* [How to lock a specific package version using yum](https://support.datastax.com/hc/en-us/articles/360020652451-How-to-lock-a-specific-package-version-using-yum)
* [How to Exclude Specific Packages from Yum Update](https://linoxide.com/linux-how-to/exclude-specific-packages-yum-update/)
* [10 Yum Exclude Examples to Skip Packages for Linux Yum Update (How to Yum Exclude Kernel Updates)](https://www.thegeekstuff.com/2014/11/yum-exclude-examples/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://huataihuang.gitbook.io/cloud-atlas-draft/os/linux/redhat/package/yum_tips.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
