mixer

mixer 是 Clear Linux* OS 团队用于生成官方更新内容和版本的工具。mixer 生成的更新内容随后会在下游客户端上供 swupd 使用。该 mixer 工具也可以成为 Clear Linux OS 功能,用来创建自己的定制更新内容和版本。

描述

mixer 使用以下源作为输入,生成更新内容:

  • 带相应 RPM 包的上游 Clear Linux OS bundle 文件
  • 带相应本地 RPM 包的本地定义的 bundle 文件
  • 带上游 RPM 包的本地定义的 bundle 文件

使用 mixer 工具,可以选择将来自这些源的哪些内容纳入更新。可以从这些源选择内容,从而为定制更新内容创建独特的功能组合(即组合)。

mixer 生成的更新内容包括各种操作系统内容、更新元数据和完整映像。操作系统内容包括所有更新文件,以及用于提升更新性能的零包和增量包。作为清单存储的更新元数据则描述了更新的所有 bundle 文件信息。mixer 生成的更新内容随后会发布到 Web 服务器,然后由客户端通过 swupd 使用。请参阅 swupd,了解有关更新和更新内容的其他信息。

工作原理

了解 mixer 工具的设置和工作流。

必备条件

  • mixer bundle 文件

    通过 mixer bundle 文件添加 mixer 工具。请参阅 swupd,了解有关安装 bundle 文件的更多信息。

  • Docker* 容器

    默认情况下,mixer 会在 Docker 容器中运行所有构建命令,确保使用正确的工具版本。此外,此操作还会在上游发布新的时间戳时允许定制组合自动执行下游时间戳转换。请参阅 Format version,了解有关时间戳转换的其他信息。

    请参阅 Configure and enable Docker,查看相关说明。

  • Docker 代理(可选)

    如果使用代理服务器,则须设置代理环境变量并为 Docker 守护程序和容器创建代理配置文件。

    如果使用了公司代理服务器,则请咨询 IT 部门以获取正确的值。

    请参阅 Configure Docker proxy info,查看相关说明。

  • 更新内容和映像的存储位置

    为了让 swupd 使用您的组合,组合的更新内容需在 Web 服务器上存储。此组合会配置更新位置 URL,而 swupd 则会用其拉取更新。

    请参阅 为 mixer 设置 Nginx Web 服务器,查看设置更新位置的简单示例。

组合设置

请按以下步骤创建和初始化 mixer 工作区。创建组合前,请先完成设置。

  1. 创建工作区。

    mixer 工具使用简易工作区包含基本目录结构中的所有输入和输出。此工作区只是一个空文件夹,可以在此文件夹中执行 mixer 命令。每个组合均使用自己的独立工作区。

  2. 初始化工作区和组合。

    创建组合前,必须显式初始化 mixer 工作区。初始化期间,系统将配置 mixer 工作区并定义组合基础。默认情况下,组合以最新的上游版本为基础创建,一开始只包含最少的 bundle 文件。第一个定制组合版本号以 10 开始。也可以选择要从中启动的其他版本或 bundle 文件集。

    初始化操作会在工作区中创建目录结构并添加 builder.conf 文件,而此文件将用于配置 mixer 工具。

    查看 mixer.init man page,了解有关 mixer 初始化的更多信息。

    查看适合从中进行组合的 releases 列表。

  3. 编辑 builder.conf。

    mixer 工具根据 builder.conf 知道如何配置组合。例如,可以配置 mixer 输出的所在位置以及 swupd 更新内容的所在位置。

    至少需要设置更新服务器的 URL,以便定制操作系统知道从何处获取更新内容。

    请参阅 builder.conf 部分,了解更多信息。

创建组合

创建组合的步骤如下:

  1. 添加定制 RPM 并设置本地存储库(可选)。

    如果要在组合中添加定制 RPM,则须将 RPM 添加到组合工作区并设置相应的本地存储库。

    转到 autospec 指南,了解如何从头构建 RPM。如果未在 Clear Linux OS 上构建 RPM,则请确保配置和工具链会为 Clear Linux OS 正确构建 RPM,否则便无法保证其兼容。

    请参阅 autospec 指南,了解使用 autospec 来构建 RPM 的更多信息。

  2. 更新和构建 bundle 文件。

    添加、编辑或删除将纳入内容的 bundle 文件并对其进行构建。更新组合中的 bundle 文件时,mixer 会自动更新 mixbundles 文件。

    查看 mixer.bundle man page,了解配置组合中的 bundle 文件的更多信息。

    查看 mixer.build man page,了解有关构建 bundle 文件的更多信息。

    查看 Bundles 部分,了解有关 mixer 如何管理 bundle 文件的更多信息。

  3. 创建更新内容。

    mixer 会通过此步骤创建更新内容。零包是自动创建的,也可以同时创建增量包(适用于版本 0 之后的所有内部版本)。

    零包是从组合版本 0(无)变为刚刚为其构建内容的组合版本所需的全套内容。

    增量包可提供 PAST_VERSIONMIX_VERSION 之间的增量内容,允许从一个组合版本变为另一版本。

    查看 swupd,了解有关更新内容的更多信息。

  4. 创建映像。

    mixer 使用 ister.py image builder 工具从更新后的内容创建可引导映像。在此步骤中,可以指定要在映像中预安装的 bundle 文件。随后,用户可以安装组合中的其他 bundle 文件。

  5. 推出更新。

    将更新内容和映像部署到更新服务器。

    查看 Example 3: Deploy updates to target,了解简单的部署场景。

保持或修改组合

按照创建组合的步骤,将内容更新或修改为新版本。为下一组合递增组合版本号。

示例

以下示例旨在按顺序协同工作。这些示例采用:

  • Clear Linux OS 的原有安装。
  • Clear Linux OS 随附用于存储内容更新的 Web 服务器。
  • 一台根据例 2 中创建的本地生成内容进行更新的简易虚拟机。

在使用这些示例之前,请先满足所有 Prerequisites

例 1:组合设置

本例介绍了第一次为新组合设置 mixer 的基本步骤。

  1. 创建一个空目录,用作 mixer 的工作区:

    mkdir ~/mixer
    
  2. 在 mixer 工作区中,根据最新的上游 Clear Linux OS 版本生成初始组合,包含最少的 bundle 文件。在初始化输出中,请注意初始组合版本已设为 10,添加了最少的 bundle 文件。

    cd ~/mixer
    mixer init
    
  3. 编辑 builder.conf,将 CONTENTURL 和 VERSIONURL 的值设为在前提条件 为 mixer 设置 Nginx Web 服务器 中所设 nginx* 服务器的 IP 地址。例如:

    CONTENTURL="http://192.168.25.52"
    VERSIONURL="http://192.168.25.52"
    

例 2:创建简单组合

本例介绍如何使用上游内容创建简单的定制组合。我们要为 QEMU 虚拟机创建映像,方便以后进行组合测试。

我们可以使用初始化期间添加的默认 bundle 文件,但其中包括 native-kernel bundle 文件,而此 bundle 文件主要用于裸机系统而非虚拟机。因此,我们要修改默认的 bundle 文件集,缩小内核映像,提高加载速度。

  1. 更新组合中的 bundle 文件:

    mixer bundle remove kernel-native
    mixer bundle add kernel-kvm
    
  2. 在此情况下,我们将添加来自上游的 editors bundle,但会移除 joe 编辑器。

    mixer bundle add editors
    mixer bundle edit editors
    
  3. 使用一个编辑器,从 bundle 定义中手动移除 joe

    $EDITOR ./local-bundles/editors
    
  4. 在 mix 中再次列出 bundles 以确认移除。

    mixer bundle list  --tree
    
  5. 构建 bundle 文件:

    mixer build bundles
    

    build 命令完成后,在 ~/mixer/update/image/<mix version>/full 中查找完整 chroot。

  6. 构建更新内容。浏览到 http://localhost 站点,您会看到网页现已打开,但没有更新内容。构建更新内容:

    mixer build update
    

    刷新 http://localhost 站点。此时,您便可看到组合版本 10 的更新内容。

    查找 ~/mixer/update/www/<mix version>,在工作区中查看更新内容。

  7. 配置映像。编辑映像的 ister 配置文件,包含要在映像中预安装的所有 bundle 文件。如果是首次创建映像,则需首先获取 release-image-config.json 模板文件的副本:

    curl -O https://raw.githubusercontent.com/bryteise/ister/master/release-image-config.json
    

    在本例中,编辑 release-image-config.json,使 root 分区的大小为 “5G”,同时将 “kernel-native” bundle 文件更换为 “kernel-kvm”。

    {
      "DestinationType" : "virtual",
      "PartitionLayout" : [ { "disk" : "release.img", "partition" : 1, "size" : "32M", "type" : "EFI" },
                            { "disk" : "release.img", "partition" : 2, "size" : "16M", "type" : "swap" },
                            { "disk" : "release.img", "partition" : 3, "size" : "5G", "type" : "linux" } ],
      "FilesystemTypes" : [ { "disk" : "release.img", "partition" : 1, "type" : "vfat" },
                            { "disk" : "release.img", "partition" : 2, "type" : "swap" },
                            { "disk" : "release.img", "partition" : 3, "type" : "ext4" } ],
      "PartitionMountPoints" : [ { "disk" : "release.img", "partition" : 1, "mount" : "/boot" },
                                 { "disk" : "release.img", "partition" : 3, "mount" : "/" } ],
      "Version": "latest",
      "Bundles": ["kernel-kvm", "os-core", "os-core-update"]
    }
    
  8. 构建映像。

    sudo mixer build image
    

    此步骤的输出为实时映像 release.img

  9. 创建下一组合。为接受更新的实时映像创建组合新版本。组合版本以 10 为因子递增:

    mixer versions update
    

    重置执行步骤 1-3,将上游 curl bundle 文件添加到组合中:

    mixer bundle add curl
    mixer build bundles
    mixer build update
    

    构建可选增量包,有助于缩短客户端更新时间:

    mixer build delta-packs --from 10 --to 20
    

    刷新 http://localhost 站点,查看组合版本 20 的更新内容。

    查找 ~/mixer/update/www/<mix version>,在工作区中查看更新内容。

例 3:将更新部署到目标位置

在例 2 中创建的映像可以在 QEMU 中直接引导。在本例中,我们会引导例 2 中的映像,对其进行验证,然后将映像从组合版本 10(原始映像)更新到组合版本 20。

  1. 设置 QEMU 环境。

    kvm-host bundle 文件安装到 Clear Linux OS:

    sudo swupd bundle-add kvm-host
    

    获取虚拟 EFI 固件,下载映像启动脚本,将其转换为可执行文件:

    curl -O https://download.clearlinux.org/image/OVMF.fd
    curl -O https://download.clearlinux.org/image/start_qemu.sh
    chmod +x start_qemu.sh
    
  2. 启动虚拟机映像(例 2 中创建):

    sudo ./start_qemu.sh release.img
    
  3. 以 root 用户身份登录,设置密码

  4. 试用此组合。

    查看组合中安装的默认 bundle 文件:

    swupd info
    swupd bundle-list
    swupd bundle-list -a
    
  5. 现在我们将添加修改的 editors bundle。

    swupd bundle add editors
    
  6. 尝试启动 joe 编辑器。它应该不会出现,因为我们已将它从原 editors bundle 中移除。

  7. 下一步,我们将从版本 10 更新至版本 20,以获取新的可用 bundles。使用 swupd 更新您的 mix:

    swupd check-update
    swupd update
    swupd bundle-list -a
    
  8. 此时,组合应为版本 20 且 curl 可用。试用 curl。由于尚未安装 curl,因此此操作会失败:

    curl: command not found
    To install curl use: swupd bundle-add curl
    

    将更新服务器上的新 bundle 文件添加到虚拟机上。再次试用 curl。操作成功!

    swupd bundle-add curl
    curl -O https://download.clearlinux.org/image/start_qemu.sh
    

    关闭虚拟机:

    poweroff
    

参考

参考 mixer man page,了解有关 mixer 命令和选项的详细信息。

builder.conf

mixer 初始化过程中会创建 builder.conf。文件中包含 mixer 工具的基本配置。其中的主要项目为 CONTENTURL 和 VERSIONURL。系统会根据定制内容使用这些项目。

#builder.conf

#VERSION 1.0

[Builder]
  CERT = "/home/clr/mix/Swupd_Root.pem"
  SERVER_STATE_DIR = "/home/clr/mix/update"
  VERSIONS_PATH = "/home/clr/mix"
  YUM_CONF = "/home/clr/mix/.yum-mix.conf"

[Swupd]
  BUNDLE = "os-core-update"
  CONTENTURL = "<URL where the content will be hosted>"
  VERSIONURL = "<URL where the version of the mix will be hosted>"

[Server]
  DEBUG_INFO_BANNED = "true"
  DEBUG_INFO_LIB = "/usr/lib/debug"
  DEBUG_INFO_SRC = "/usr/src/debug"

[Mixer]
  LOCAL_BUNDLE_DIR = "/home/clr/mix/local-bundles"
  LOCAL_REPO_DIR = ""
  LOCAL_RPM_DIR = ""
  DOCKER_IMAGE_PATH = "clearlinux/mixer"

表 1 提供了 builder.conf 中变量的附加说明。

变量 说明
CERT

设置 mixer 存储证书文件的路径。该文件用于签署内容并进行验证。如果不提供现有证书文件的路径,mixer 则会自动生成证书,同时会签署 Manifest.MoM 文件,为创建的更新内容提供安全保障。

chroot-builder 使用此证书文件签署 Manifest.MoM root 文件,为内容验证提供安全保障。

swupd 使用此证书验证 Manifest.MoM 文件的签名。

目前,极力建议不要修改此变量,因为 swupd 必须要有配置十分具体的证书,才能正确签署和验证。

CONTENTURLVERSIONURL

将这些变量设置为存储更新内容的 Web 服务器的 IP 地址。

VERSIONURL 是 swupd 客户端希望确定是否存在新版本的 IP 地址。

CONTENTURL 是 swupd 从中拉取内容更新的位置。

如果 Web 服务器与 SERVER_STATE_DIR 目录位于同一计算机上,则可在 Web 服务器的文档根目录中创建符号链接,轻松存储内容。

这些 URL 嵌入 mixer 所创建的映像中。

DOCKER_IMAGE_PATH 设置 mixer 通过拉取在适当容器中运行内部版本的 docker 映像的基本名称。
LOCAL_BUNDLE_DIR 设置 mixer 存储本地 bundle 定义文件的路径。bundle 定义文件包括用户创建的所有原创新 bundle 文件,还有上游 bundle 文件的编辑版本。
SERVER_STATE_DIR 设置 mixer 输出内容的目标路径。默认情况下,mixer 会自动设置此路径。
VERSIONS_PATH 设置组合版本以及上游版本的两个状态文件的路径:mixversionupstreamversion。设置工作区时,mixer 会为您创建这两个文件。
YUM_CONF

设置 mixer 自动生成 .yum-mix.conf 文件所在的路径。

yum 配置文件将 chroot-builder 指向 RPM 的存储位置。

表 1:builder.conf 中的变量

Format 版本

操作系统的兼容版本通过操作系统兼容性时间戳进行跟踪。某一时间戳的各版本操作系统均完全兼容,并可更新到该时间戳中的任意其他版本。兼容性时间戳在 mixer.state 文件中作为 Format 变量进行设置。mixer.state 中的变量由 mixer 在执行间隔使用,且不应手动更改。

format bump 会改变 house 的基础,创建一个新层级。如果 Format 递增至新的阶段( “format bump”),操作系统会以这种方式发生改变:从 format X 构成的 build A 更新至 format Y 构成的 build B 将无法完成。

在如下情况中,将需要 format bump:

  • 软件更新器 swupd 或软件不再兼容以前的更新模式
  • 一个 package 从更新流中移除后,该更新必须确保从系统中移除与该 package 相关的文件

使用 Format 增量可以确保必需进行的更改和同时需要进行的更改以正确的顺序进行。除非使用命令行标志覆盖,否则更新后的客户端只会更新采用各自时间戳格式版本的最新版本。如此一来,便可确保所有客户端均更新采用给定时间戳格式的最终版本。

给定时间戳格式必须包含理解以下一个时间戳格式构建的内容所需的所有更改。仅当达到采用旧时间戳格式的最终版本后,客户端才能继续更新到采用新时间戳格式的版本。

仅当出现兼容性破坏问题时,才会递增时间戳格式版本。正常更新(如更新软件包)无需时间戳格式增量。

bundle 文件

mixer 将有关 bundle 文件的信息存储在名为 mixbundles 的平面文件中。此文件所在的路径是通过文件 builder.conf 中的 VERSIONS_PATH 变量设置的。启动组合时会自动创建 mixbundles。每次更改组合中的 bundle 文件时,mixer 均会刷新此文件。

bundle 文件可以包括其他 bundle 文件。嵌套的 bundle 文件自身可以包含其他 bundle 文件。如果在组合中发现不应该纳入的 bundle 文件,则可能是先前显式添加的一个 bundle 文件中的嵌套 bundle 文件。

bundle 文件分为两大类:上游或本地。上游 bundle 文件是 Clear Linux OS 提供的 bundle 文件。本地 bundle 文件则要么是修改后的上游 bundle 文件,要么是新的本地 bundle 文件。

上游 bundle 文件

mixer 会自动下载和缓存上游 bundle 定义文件。这些定义文件存储在工作区的 upstream-bundles 目录中。请勿修改此目录中的文件。此目录只是供 mixer 使用的镜像。如果必须下载新版本,mixer 则会在动态重新填充之前自动删除该目录的内容。

mixer 工具会自动缓存在 upstreamversion 文件中配置的 Clear Linux OS 版 bundle 文件。此外,mixer 还会在旧版本无需再使用后立即将其清除。

本地 bundle 文件

本地 bundle 文件是您创建的 bundle 文件,或是上游 bundle 文件的编辑版本。本地 bundle 定义文件存储在工作区的 local-bundles 目录中。此目录的路径是通过 builder.conf 文件中的 LOCAL_BUNDLE_DIR 变量设置的。

mixer 始终会先检查本地 bundle 文件,然后再检查上游 bundle 文件。 因此,local-bundles 目录中的 bundle 文件始终优先于同名的上游 bundle 文件。利用此优先特性,可以将上游 bundle 文件复制到本地,然后进行编辑,变为本地 bundle 文件。

bundle 文件配置

mixer 提供命令来配置组合的 bundle 文件,例如将 bundle 文件添加到组合中,为组合创建新的 bundle 文件,或从组合中删除 bundle 文件。查看 mixer.bundle man page,获取完整的命令列表,了解配置组合中的 bundle 文件的更多信息。

编辑现有本地 bundle 文件就像在心仪的编辑器中打开 bundle 定义文件、执行所需编辑以及保存更改一样简单。

注解

从组合中删除 bundle 文件:默认情况下,删除 bundle 文件只会从组合中删除 bundle 文件。本地 bundle 定义文件仍会保留。要彻底删除 bundle 文件(包括它的本地 bundle 定义文件),请使用 --local 标志。

如果删除组合中上游 bundle 文件的本地编辑版本的 bundle 定义文件,该组合则会重新引用此 bundle 文件的原始上游版本。

配置和启用 Docker

通过以下步骤为 mixer 工具启用 Docker。如有必要,请务必先 Configure Docker proxy info

  1. 启动 Docker 守护程序:

    sudo systemctl start docker
    sudo chmod 777 /var/run/docker.sock
    sudo docker info
    
  2. 将用户添加到 docker 组

    sudo usermod -G docker -a <username>
    

手动拉取 Docker 容器(可选)

默认情况下,如果没有 Docker 容器,mixer 则会自动拉取 Docker 容器以创建组合。如需对 mixer 容器进行故障排除,则可尝试手动拉取 mixer Docker 容器。

mixer Docker 容器的版本可在 Docker Hub 上的 clearlinux/mixer repo 标签下找到。每个版本的 mixer Docker 容器均以关联的 Clear Linux OS 上游时间戳格式版本来命名。请参阅 Format version,了解有关上游时间戳格式版本的其他信息。

通过以下步骤手动拉取 mixer Docker 容器:

  1. 查看 Docker Hub 上的 clearlinux/mixer repo 标签,查找所需版本的容器。

  2. 拉取最新容器版本:

    docker pull clearlinux/mixer:<upstream-format-version>
    
  3. 查看本地 docker 映像:

    docker images
    

配置 Docker 代理信息

如有必要,通过以下步骤配置 Docker 代理信息。

  1. 创建 Docker 守护程序代理配置目录:

    sudo mkdir -p /etc/systemd/system/docker.service.d
    
  2. 创建 /etc/systemd/system/docker.service.d/http-proxy.conf 并用自己的代理值添加以下内容:

    [Service]
    Environment="HTTP_PROXY=<HTTP proxy URL>:<port number>"
    Environment="HTTPS_PROXY=<HTTPS proxy URL>:<port number>"
    
  3. 重新加载 Docker 守护程序:

    sudo systemctl daemon-reload
    

配置 Docker 容器代理,将代理设置传递给容器:

  1. 为容器配置创建目录:

    mkdir ~/.docker
    
  2. 创建配置文件 ~/.docker/config.json 并用自己的代理值添加以下条目:

    {
      "proxies":
      {
        "default":
        {
          "httpProxy": "<proxy-url>:<port>",
          "httpsProxy": "<proxy-url>:<port>"
        }
      }
    }
    
  3. 设置 docker 配置目录的所有权和权限:

    sudo chown "$USER":"$USER" /home/"$USER"/.docker -R
    sudo chmod g+rwx "$HOME/.docker" -R
    

配置代理,允许 mixer 从防火墙后访问上游内容。

  1. 打开 $HOME/.bashrc 文件,为以下内容添加代理和端口值:

    export http_proxy="<proxy-url>:<port>"
    export https_proxy="<proxy-url>:<port>"
    export HTTP_PROXY="<proxy-url>:<port>"
    export HTTPS_PROXY="<proxy-url>:<port>"
    export no_proxy="<...>"
    
  2. 注销并再次登录,使代理生效。

为 mixer 设置 Nginx Web 服务器

需有 Web 服务器存储更新内容。在本例中,我们使用 Clear Linux OS 随附的 Nginx Web 服务器。

通过以下步骤为 mixer 设置 Nginx Web 服务器:

  1. 安装 nginx bundle 文件:

    sudo swupd bundle-add nginx
    
  2. 创建 mixer 更新的存储目录:

    sudo mkdir -p /var/www
    
  3. 在工作区更新和本地 Nginx Web 服务器更新之间创建符号链接。在本例中,$HOME/mixer 是组合的工作区。

    sudo ln -sf $HOME/mixer/update/www /var/www/mixer
    
  4. 设置 nginx 配置:

    sudo mkdir -p  /etc/nginx/conf.d
    
  5. 复制默认示例配置文件:

    sudo cp -f /usr/share/nginx/conf/nginx.conf.example /etc/nginx/nginx.conf
    
  6. 配置 mixer 更新服务器。创建以下服务器配置内容并将其添加到 /etc/nginx/conf.d/mixer.conf (需 sudo 权限):

    server {
         server_name localhost;
         location / {
                   root /var/www/mixer;
                   autoindex on;
         }
    }
    
  7. 重新启动守护程序,引导时启用 Nginx,然后启动此服务。

    sudo systemctl daemon-reload
    
    sudo systemctl enable nginx
    
    sudo systemctl start nginx
    
  8. 验证 Web 服务器是否在 http://localhost 上运行。此时不应再出现 “404 Not Found” 消息。