团队中的小队

我们应该提到,我们最终在这个 sprint 中组成了三个小队

  • Sockets & Services 小队,致力于正确支持 systemd sockets 以及其他与 systemd 相关的任务(当然,都在 YaST 的上下文中)。
  • Qt and UI 小队,致力于用户界面相关的工作,例如向软件包选择界面添加一个新视图,以显示由服务管理的软件包,以及一些控制中心改进。
  • Bug Fighting 小队,处理每天涌入以及我们待办事项列表中的 bug。

修复了大于 8EiB 的磁盘问题

你家里不太可能有一个大于 8EiB(八 exbibytes,263)的磁盘存储。但在企业或云环境中,这可能是可能的。

事实证明,YaST 包管理器无法很好地处理如此大的磁盘。在开始时,你可能会看到这个错误的错误消息

问题

有两个问题

  • 磁盘上肯定有很多可用空间,错误提示用户空间不足,只是在说谎。
  • 磁盘大小显示为错误的负值。

事实证明,问题是由使用有符号 64 位整数数据类型引起的,该类型对于大于 8EiB 的值会溢出,并且数字变为负数。

修复

我们不得不修复几个地方,每个地方都需要不同的解决方案。

  • 尽可能使用无符号 64 位整数,这显然可以避免溢出。
  • libzypp 中的数字使用 KiB 单位,在某些地方我们需要将该数字转换为 MiB。但首先,我们将转换为纯字节(通过乘以 1024),然后除以 1MiB。而这个第一步乘法运算可能会导致溢出。相反,我们直接通过除以 1024 将 KiB 转换为 MiB,而无需在中间出现溢出风险。
  • 使用浮点 double 数据类型将值转换为人类可读的文本或百分比。 double 具有更宽的范围,并且在这些情况下我们不需要精确的精度,因此浮点运算中的舍入无关紧要。
  • 忽略空闲空间检查中的负数。在某个地方,该值通过 YaST 组件系统,该系统使用有符号整数,这很难更改。在这种情况下,我们将负的空闲空间视为足以安装任何软件包,超过 8EiB 的空闲空间应该足以安装任何软件包™。

大型数字仍然存在一些小问题。支持的最高单位是 TiB,因此即使是非常大的数字也以 TiB 单位显示,如上面的屏幕截图所示。该修复计划作为维护更新发布,并且此更改将破坏向后兼容性,因此我们将在以后改进它,但仅限于将来的版本。

测试

但是,如何测试这种行为是一个问题?你可以在代码中伪造一些数字,但为了进行全面测试或 QA 验证,最好在真实的磁盘上进行测试。但你通常没有这么大的存储用于测试…

幸运的是,在 Linux 中,可以使用 稀疏文件loop 设备 相当容易地伪造如此大的文件系统。这是一个简短的教程

# create two big sparse files
truncate -s 6E /tmp/huge_file1
truncate -s 6E /tmp/huge_file2

# create block devices via loopback
losetup -f /tmp/huge_file1
losetup -f /tmp/huge_file2

# get the loop back device names, the names might be different
# if the system already uses some other loop back devices
losetup -a
/dev/loop1: [0056]:1171324 (/tmp/huge_file2)
/dev/loop0: [0056]:1171323 (/tmp/huge_file1)

# create a btrfs file system over both "disks"
mkfs.btrfs -K /dev/loop0 /dev/loop1

# mount it on /mnt2 (or whatever else, do not use /mnt, that is ignored by libzypp!)
mkdir /mnt2
mount /dev/loop0 /mnt2

# verify the size
df -h /mnt2
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0       12E   17M   12E   1% /mnt2
# voila! you have a 12EiB file system! enjoy

注意:显然,即使你有一个 12EiB 的文件系统,你也无法在下面的真实文件系统(在本例中为 /tmp)中保存更多数据。如果你尝试,你会得到写入错误,没有永动机…

加速 yast2-storage-ng 中的单元测试和 Travis 构建

新的 yast2-storage-ng 包具有相当大量的单元测试。这很好,它可以减少错误代码并确保功能按预期工作。

另一方面,缺点是运行测试需要太长时间。如果你必须在代码中的任何小更改后等待 3 或 4 分钟,那么你就会浪费太多时间,或者根本不运行测试。所以我们研究了如何加速测试。

并行运行测试

主要问题是所有测试都是按顺序一个接一个地执行的。即使你有一个多 CPU 系统,也只有一个处理器被使用。事实证明,使用 parallel_test Ruby gem 可以轻松地并行运行测试,从而利用所有可用的处理器。

唯一可能的问题是测试之间不能有任何依赖关系或冲突,否则并行运行测试将会失败。幸运的是,yast2-storage-ng 测试中只有一个小问题,我们可以毫不费力地启用并行测试。

并行运行 Travis 作业

Travis 作业也花费了相当多的时间。并行运行测试在 Travis 上有帮助,但仍然不够好。

幸运的是,Travis 允许并行运行多个作业。因此,我们将运行测试、构建包、运行语法检查等的单个 CI 作业拆分为三个独立的组,这些组可以并行启动。

文档

如果你对细节感兴趣,可以查看我们更新的 Travis 文档并行测试文档。或者查看 公告 在 YaST 邮件列表中。

结果

这里有一些真实的数据来查看加速效果

  • 本地运行测试套件 (rake test:unit):从 2:44 到 0:38(在启用超线程的四核 CPU 上加速 4.3 倍)
  • 本地构建包 (rake osc:build):从 137s 到 49s(使用缓存的 RPM 包,但包括 chroot 安装)
  • OBS 中的包构建:从 323s-505s 到 102s-235s(它高度依赖于所用工作者的速度)
  • Travis 加速:从 8-10 分钟到 3-4 分钟(使用并行 Travis 作业和并行测试)

这使我们能够继续向包中添加更多的测试。 :smiley:

产品扩展/模块提供的软件包是什么?

在软件管理模块中,我们有一个“存储库”视图,你可以在其中查看按提供它们的存储库分组的软件包。但这对于查看产品扩展模块提供的软件包没有太大帮助,因为每个产品模块由多个存储库组成:最初发布的软件包、更新、源代码、调试信息。

幸运的是,每个产品模块的存储库都组合在一个存储库服务中,并且我们已向软件管理添加了一个服务过滤器。

Qt 服务过滤器

ncurses 服务过滤器

(参考:Feature #320573)