> For the complete documentation index, see [llms.txt](https://handbook.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://handbook.bsdcn.org/di-27-zhang-freebsd-geng-xin-yu-sheng-ji/27.7.-pkgbase.md).

# 27.7.使用软件包更新 FreeBSD

从 14.0-RELEASE 开始，FreeBSD 项目使用 [pkg(8)](https://man.freebsd.org/cgi/man.cgi?query=pkg\&sektion=8\&format=html) 发布了基本系统的软件包。pkg 的便利性不再局限于 FreeBSD ports 集合。现在，FreeBSD 本身也可以使用 [pkg(8)](https://man.freebsd.org/cgi/man.cgi?query=pkg\&sektion=8\&format=html)。基本系统的软件包及其使用方式传统上称为 *pkgbase*。

官方软件包的发布始于 [2023 年 10 月](https://lists.freebsd.org/archives/freebsd-pkgbase/2023-October/000221.html)。在 FreeBSD 14 中使用它们目前仍属实验性质。

从 15.0-RELEASE 开始，[freebsd-base(7)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-base\&sektion=7\&format=html) 将以技术预览（tech preview）的形式支持：

* 安装
* 小版本升级
* 大版本升级

freebsd-base 最终将取代：

* 诸如 `base.txz`、`kernel.txz` 这样的 tarball 分发集，它们过去用于通过 [bsdinstall(8)](https://man.freebsd.org/cgi/man.cgi?query=bsdinstall\&sektion=8\&format=html) 安装操作系统
* [freebsd-update(8)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-update\&sektion=8\&format=html) 用于系统更新

当前的计划是让 `freebsd-update` 与 pkg 协同工作。

> **警告**
>
> 分发集的替换仍需要一些时间，直到 freebsd-base 完全稳定！

基本系统的软件包补充了从源代码构建和安装的方式（[文档链接](/di-27-zhang-freebsd-geng-xin-yu-sheng-ji/27.6.-cong-yuan-dai-ma-geng-xin-freebsd.md)），对于希望构建定制内核或用户空间的用户，这条路径依然可用。用户也可以从本地源代码构建自定义的基本系统软件包，或只依赖官方提供的软件包。

## 27.7.1. 将主机转换为使用 freebsd-base

FreeBSD 14.0-RELEASE 或之后的版本可以转换为使用基本系统的软件包。更早的版本必须先使用 `freebsd-update` 升级，然后才能转换。

在转换过程中，推荐使用 FreeBSD 基金会赞助的 [pkgbasify](https://github.com/FreeBSDFoundation/pkgbasify) 工具。请按照其中给出的说明操作。

[freebsd-update(8)](https://man.freebsd.org/cgi/man.cgi?query=freebsd-update\&sektion=8\&format=html) 将得到增强，使其能与 pkg 和 pkgbasify 协同工作。

> **警告**
>
> 请注意，此迁移过程需要最多 5 GiB 的额外可用空间，用于下载、解包并重新放置所有冲突的文件。pkgbasify 工具不会检查磁盘空间，因此用户有责任在运行迁移前确保有足够空间。

[pkgbasify(8)](https://man.freebsd.org/cgi/man.cgi?query=pkgbasify\&sektion=8\&format=html)（或 [D51594](https://reviews.freebsd.org/D51594) 或 [port request](https://wiki.freebsd.org/WantedPorts#O-P) 的最终产物）执行六项主要任务：

* 使用 [bectl(8)](https://man.freebsd.org/cgi/man.cgi?query=bectl\&sektion=8\&format=html) 创建一个备份引导环境（仅适用于 ZFS）
* 创建新的软件包存储库配置文件
* 升级现有系统组件，如 base、kernel、lib32、debug
* 合并现有与新的配置文件
* 更新 passwd 和 capabilities 数据库
* 立即重启 sshd

## 27.7.2. 使用 freebsd-base 升级主机

> **警告**
>
> 这部分仍在开发中，因此请务必小心，尤其是在将现有系统转换为使用 freebsd-base 时。

如果还没有自定义 pkg 存储库配置文件的文件夹，请创建一个：

```sh
# mkdir -p /usr/local/etc/pkg/repos/
```

为了使用 freebsd-base 存储库，创建名为 `FreeBSD-base.conf` 的 pkg 存储库配置文件：

```sh
FreeBSD-base {
    url = "pkg+https://pkg.freebsd.org/${ABI}/base_release_${VERSION_MINOR}";
    mirror_type = "srv";
    signature_type = "fingerprints";
    fingerprints = "/usr/share/keys/pkg";
    enabled = yes;
}
```

关于具体配置选项的更多信息，请参见 [pkg.conf(5)](https://man.freebsd.org/cgi/man.cgi?query=pkg.conf\&sektion=5\&format=html)。

可以选择不同的分支（相应修改 `url`）：

**表 2. 基本系统软件包分支**

| 分支          | 更新频率                      | URL                                                 |
| ----------- | ------------------------- | --------------------------------------------------- |
| main        | 每天两次 —— 12:00 与 00:00 UTC | `pkg+https://pkg.freebsd.org/${ABI}/base_latest`    |
| main        | 每周一次 —— 周日 12:00 UTC      | `pkg+https://pkg.freebsd.org/${ABI}/base_weekly`    |
| stable/14   | 每天两次 —— 12:00 与 00:00 UTC | `pkg+https://pkg.freebsd.org/${ABI}/base_latest`    |
| stable/14   | 每周一次 —— 周日 12:00 UTC      | `pkg+https://pkg.freebsd.org/${ABI}/base_weekly`    |
| releng/14.3 | 每天两次 —— 12:00 与 00:00 UTC | `pkg+https://pkg.freebsd.org/${ABI}/base_release_3` |
| releng/15.0 | 每天两次 —— 12:00 与 00:00 UTC | `pkg+https://pkg.freebsd.org/${ABI}/base_release_0` |
| stable/15   | 每天两次 —— 12:00 与 00:00 UTC | `pkg+https://pkg.freebsd.org/${ABI}/base_latest`    |
| stable/15   | 每周一次 —— 周日 12:00 UTC      | `pkg+https://pkg.freebsd.org/${ABI}/base_weekly`    |

要升级系统，根据所需的发行版本修改配置文件，然后运行：

```sh
# pkg update -r FreeBSD-base
# pkg upgrade -r FreeBSD-base
```

检查这些软件包是否正确，并接受更改。

使用以下命令重启系统：

```sh
# shutdown -r now
```

### 27.7.2.1. 大版本升级

如果使用 ZFS，引导环境能让升级在不打断运行中软件的情况下完成。如果系统的根分区不使用 ZFS：升级前请做好备份。

#### 27.7.2.1.1. 准备工作

将 **/usr/local/etc/pkg/repos/FreeBSD-base.conf** 修改为目标主版本，例如对 15.0-RELEASE 使用 `base_release_0`，使其如下所示：

> **警告**
>
> 这个文件后续可能会在 RELEASE 中以不同路径出现。

```sh
FreeBSD-base {
    url = "pkg+https://pkg.freebsd.org/${ABI}/base_release_0";
    mirror_type = "srv";
    signature_type = "fingerprints";
    fingerprints = "/usr/share/keys/pkg";
    enabled = yes;
}
```

> **警告**
>
> 由于 FreeBSD 14 的 pkgbase 仍处于实验阶段，因此从 14 到 15 的 pkgbase 大版本升级同样属于实验性质。撰写本文时，在一些极端情况下大版本升级会移除 pkg，从而导致 pkg 段错误。这是 15.0-RELEASE 的 [已知问题](https://github.com/freebsd/pkg/issues/2475)。权宜之计：在升级前锁定 pkg：
>
> ```sh
> # pkg -c /mnt/upgrade lock pkg
> ```
>
> 从 FreeBSD 14 实验性升级到 15（或 16.0-CURRENT）之后，应安装元包 `FreeBSD-set-minimal`。

保存非基本系统软件包的列表，以备后用：

```sh
pkg prime-origins | sort -u > /var/tmp/pkg-prime-origins.txt
```

#### 27.7.2.1.2. 大版本升级（根分区使用 ZFS）

使用 [bectl(8)](https://man.freebsd.org/cgi/man.cgi?query=bectl\&sektion=8\&format=html) 创建引导环境，并按目标版本命名：

```sh
# bectl create 15.0-RELEASE
```

创建目录，再将新的引导环境挂载到该目录，以便通过 [chroot(8)](https://man.freebsd.org/cgi/man.cgi?query=chroot\&sektion=8\&format=html) 与 pkg 和 rootdir 配合使用：

```sh
# mkdir /mnt/upgrade
# bectl mount 15.0-RELEASE /mnt/upgrade
```

接下来的步骤会将引导环境升级到指定版本。

> **警告**
>
> 此步骤可能会移除非基本系统的软件包，其中也可能包括正在运行的桌面环境。

设置环境变量 ABI 来执行大版本升级（将 amd64 替换为对应架构，将 15 替换为目标版本）。将 pkg-static 的 chroot 目录指定为引导环境的挂载点：

```sh
# env ABI=FreeBSD:15:amd64 pkg-static -c /mnt/upgrade upgrade -r FreeBSD-base
```

将会出现提示，询问是否忽略版本不匹配，如下所示：

```sh
Newer FreeBSD version for package FreeBSD-zoneinfo:
To ignore this error set IGNORE_OSVERSION=yes
- package: 1500058
- running userland: 1500000
Ignore the mismatch and continue? [y/N]:
```

检查并确认。

要检查升级是否成功，`chroot` 到该引导环境的挂载点并运行 `freebsd-version -ku`：

```sh
# chroot /mnt/upgrade
# freebsd-version -ku
# exit
```

临时激活该引导环境，然后重新启动系统：

```sh
# bectl activate -t 15.0-RELEASE
# shutdown -r now
```

如果系统运行不正常：重新启动系统即可停止使用临时激活的引导环境，下一次开机将回到升级前的环境。

如果系统在重启后稳定运行，请不要忘记永久激活此引导环境，以避免意外引导到旧系统：

```sh
# bectl activate 15.0-RELEASE
```

#### 27.7.2.1.3. 大版本升级（根分区未使用 ZFS）

设置环境变量 ABI 来升级大版本（将 amd64 替换为对应架构，将 15 替换为目标版本）。

```sh
# env ABI=FreeBSD:15:amd64 pkg-static upgrade -r FreeBSD-base
```

将会出现提示，询问是否忽略版本不匹配，如下所示：

```sh
Newer FreeBSD version for package FreeBSD-zoneinfo:
To ignore this error set IGNORE_OSVERSION=yes
- package: 1500058
- running userland: 1500000
Ignore the mismatch and continue? [y/N]:
```

检查并确认。

要检查升级是否成功，运行 `freebsd-version -ku`。

然后重启。

#### 27.7.2.1.4. 升级后的任务

如果在更新过程中将 pkg 锁定作为权宜之计，可按如下方式移除锁：

```sh
# pkg unlock pkg
```

在升级到新的大版本之后，可能需要更新并升级已安装的软件包，使之与 ABI 版本匹配。

```sh
# pkg upgrade
```

如遇到问题，可以考虑向 [FreeBSD 支持](https://www.freebsd.org/support/) 寻求帮助。

## 27.7.3. 手动构建 pkgbase 并发布到本地网络

在构建自定义 pkgbase 软件包时，先克隆 FreeBSD 源码树：

```sh
# cd /usr/src
# git clone https://github.com/freebsd/freebsd-src.git /usr/src
```

检出要构建软件包所对应发行版的分支：

```sh
# git checkout releng/14.3
```

开始构建过程，根据可用资源，这可能需要一些时间。根据 CPU 核心数量设置并行进程数。

此示例面向 8 核 CPU：

```sh
# make -j8 buildworld && make -j8 buildkernel && make -j8 packages
```

如果构建频繁，可以考虑使用 [devel/ccache](https://cgit.freebsd.org/ports/tree/devel/ccache/) 利用缓存加快后续构建。

构建完成后，软件包将保存到 **/usr/obj/usr/src/repo/FreeBSD:14:amd64/14.3p2** 或类似目录，具体取决于构建的版本。

要将这些软件包发布到网络，设置 nginx 服务，并在 HTTP 服务器配置中使用如下位置：

```sh
location /FreeBSD:14:amd64 {
   alias /usr/obj/usr/src/repo/FreeBSD:14:amd64/;
   autoindex on;
 }
```

然后重新加载 nginx 服务。

在未使用 https 的情况下，在客户端使用简短的配置文件来指定刚构建的 pkgbase 版本，编辑 **/usr/local/etc/pkg/repos/upgrade.conf**：

```sh
upgrade: {
	url         = http://ip.of.the.server/FreeBSD:14:amd64/14.3p2
	enabled     = yes
}
```

并按照上文所述使用它（但使用 `-r upgrade` 而不是 `FreeBSD-base`）。
