openSUSE:打包用于事务更新

跳转到:导航搜索



这仅供参考,内容已合并到 原子和镜像更新的打包要求

本文档描述了 RPM 协同事务性更新的要求。

事务性更新

事务性更新是原子的。这意味着,更新要么完全应用且没有错误,要么对系统不作任何更改。 此外,事务性更新不应影响当前正在运行的进程。 在 openSUSE 上,我们通过使用 btrfs 和快照以及回滚来实现这一点。 但不是创建快照、更新当前系统并在发生错误时回滚,而是创建快照、更新该快照,并在没有发生错误时回滚到该快照。 在这种情况下,并非所有数据都可用。 只能访问主 root btrfs 子卷。 所有其他子卷,为了防止它们被回滚而创建,在 RPM 更新期间都无法访问! 这意味着,通常存储在这些子卷中的任何文件都无法访问和修改,或者在更新期间创建的新文件以后在正在运行的系统中不可见。 这尤其包括 /srv、/opt 和 /var 目录。

FHS 3.0 这样描述这些目录

  • /opt 保留用于安装附加应用程序软件包。
  • /srv 包含此系统提供的站点特定数据。
  • /var 包含可变数据文件。 这包括 spool 目录和文件、管理和日志数据以及临时文件。 这里指定是为了能够以只读方式挂载 /usr。 一旦进入 /usr 的所有内容,在系统操作期间写入(与安装和软件维护相反)都必须位于 /var 中。
  • /var/lib 包含与应用程序或系统有关的状态信息。 状态信息是程序在运行时修改的数据,并且与特定的主机有关。 用户绝不能修改 /var/lib 中的文件来配置软件包的操作,并且用于存储数据的特定文件层次结构不得暴露给普通用户。

大多数 openSUSE RPM 都可以正常工作,不会造成任何问题。 其他需要进行调整。 大多数更改不仅需要事务性更新,还需要快照和回滚。

指南

数据和应用程序

用户数据和应用程序需要严格分离。 用户数据应位于与包含应用程序的主 root 子卷不同的子卷中。 应用程序应始终位于主 root 子卷中,而不是其他子卷中。 "/srv" 在这方面是一个真正的噩梦:它包含应用程序、用户数据和配置文件混合在一起。


安装前/安装后脚本

修改安装前/安装后脚本中的数据或配置文件,需要小心数据的位置。 如果数据位于其他子卷中,则应在下次重新启动时进行修改,例如使用 systemd 单元文件。 但请注意,该单元仅在更新后运行一次,而不是每次重新启动都运行。


重启服务

由于新的/更新的应用程序在正在运行的系统中不可用,因此重启任何服务毫无意义,只会中断正在运行的服务并启动旧代码。 标准 systemd 宏可以处理此问题,并且可以正常工作。


目录

如果 RPM 包含位于 root 子卷之外的目录,这些目录也无法访问,对所有权或权限的更改也是如此。 对于 /var 和 /srv,我们有一个工具,它在启动时读取 RPM 数据库并创建缺少的目录。 systemd-tmpfiles 也可以用来创建新目录。


/var 中的文件

RPM 不应将文件打包到 /var 中,因为这些文件无法在软件包的安装、更新或删除期间创建、更新或删除。 更好的解决方案是使用 systemd-tmpfiles 来创建这些文件

  • 将文件存储在 /usr/share 或 /usr/lib 下的目录中
  • 创建一个 /usr/lib/tmpfiles.d/<package>.conf 文件,该文件将文件复制或链接到 /var

一个示例(摘自 ypserv)如下所示

ypserv.conf

  d /var/yp 0755 - - -
  L /var/yp/Makefile - - - - ../../usr/lib/yp/ypMakefile
  L /var/yp/securenets - - - - ../../usr/lib/yp/securenets.example

ypserv.spec

  %post
  %tmpfiles_create ypserv.conf

有关更多信息,请阅读 tmpfiles 配置文件格式的文档