\documentclass{utart}

\usepackage{hyperref}
\usepackage{enumitem}
\usepackage{plantuml}

\author{yanbowen}
\title{Rootfs Repo 构建}

\begin{document}
\utMakeTitle{}{1.0.0}{2022-01-20}
\utMakeChangeLog{
  1.0.0 & 创建 & 闫博文 & 2022-01-20 \\
  \hline
}
\utMakeTOC

\section{概述}
\subsection{目的}
本文档是针对 Rootfs Repo 构建工具的概要设计文档，在本文档中，将给出 Rootfs Repo 构建工具的设计原则、结构设计、关键流程设计等内容。

本文档的适用读者为 Rootfs Repo 构建工具的设计人员、开发人员、测试人员以及后续维护人员。

\subsection{术语说明}
\begin{itemize}[leftmargin=4em]
\item rootfs：根文件系统，包含操作系统启动和运行所需的必要文件；
\item repo：仓库，存储和管理文件，支持文件历史版本的恢复；
\item ostree：是一个面向操作系统文件的版本管理系统，可将文件的每次变更标记为不同的版本，并支持回滚文件到任一版本；
\item debootstrap：是一个 debian 构建基础系统的工具；
\end{itemize}

\subsection{参考资料}
\begin{itemize}[leftmargin=4em]
\item \href{https://ostreedev.github.io/ostree/}{ostree}
\item \href{https://wiki.debian.org/Debootstrap}{debootstrap}
\end{itemize}

\section{系统设计}
\subsection{设计原则}
Rootfs Repo 构建工具采用管道/过滤器的架构设计风格，每个过滤器作为一个构件，亦称为模块。开发时应遵循以下原则：
\begin{itemize}[leftmargin=4em]
\item 模块应是同类功能的集合，提供明确的对外接口，高内聚；
\item 模块之间不允许存在循环依赖，低耦合；
\item 模块内部的错误不应导致崩溃，应对外返回，由调用者处理；
\item 模块只应在执行成功后，才对数据作出实际的修改；
\item 模块应实现日志记录功能，并在 debug 时提供更加详细的日志；
\item 源码目录结构要清晰，模块和公用代码要明确分离；
\end{itemize}

\subsection{主要模块设计}
\subsubsection{结构设计}
Rootfs Repo 构建工具根据需求，主要由以下模块组成：
\begin{itemize}[leftmargin=4em]
\item debootstrab 模块

  构建核心的 rootfs ，需要传入核心包列表、 rootfs 路径、 deb cache 目录和日志记录者，输出为 rootfs 数据、错误信息及日志。
\item chroot 模块

  chroot 到 rootfs 执行指定的命令，需要传入 rootfs 目录、命令列表和日志记录者，输出为 rootfs 数据、错误信息及日志。
\item hooks 模块

  收集需要执行的 hooks 列表，并执行。 hooks 分为 before、chroot、after 三个阶段。
  需要传入 rootfs 目录、hook 目录、hook 阶段和日志记录者，输出为 rootfs 数据、错误信息及日志。
\item repo 模块

  提交 rootfs 数据到 repo ，需要传入 \texttt{os\_desc.xml} 、 rootfs 目录和日志记录者，输出为错误信息及日志。
  若 repo 不存在，则自动创建。
\end{itemize}

构建主程序通过对这些模块的调用，完成 rootfs 的构建，总体结构如下：
\begin{center}
  \begin{adjustbox}{scale=0.8}
    \begin{plantuml}
      @startuml
      package builder {
        [main] ..> [deboostrap] : core list
        [main] ..> [chroot] : extra list
        [main] ..> [hooks] : pre,chroot,post hooks
        [main] ..> [repo] : init,commit
        [hooks] ..> [chroot] : run hooks
      }
      @enduml
    \end{plantuml}
  \end{adjustbox}

  图 2.1 构建工具结构
\end{center}

\subsubsection{debootstrap}
debootstrap 模块用来构建核心的 rootfs ，以此为基础安装扩展软件列表、运行 hooks 等，从而完成 rootfs 的构建。

debootstrap 模块调用时需要传入：
\begin{itemize}[leftmargin=4em]
\item core list
\item rootfs dir
\item log writer
\end{itemize}

执行完成后，返回是否存在错误。

\subsubsection{chroot}
chroot 模块用来在 rootfs 中执行指定的命令，在此模块中安装扩展软件、执行 hooks 等。

chroot 模块调用时需要传入：
\begin{itemize}[leftmargin=4em]
\item rootfs dir
\item command list
\item log writer
\end{itemize}

执行完成后，返回是否存在错误。

\subsubsection{hooks}
hooks 模块用来生成 hook 命令列表，并在 rootfs 中执行。hook 的执行时通过 flag 来指明是否需要 chroot rootfs 。

hooks 模块调用时需要传入：
\begin{itemize}[leftmargin=4em]
\item rootfs dir
\item hook dir
\item need chroot
\item log writer
\end{itemize}

执行完成后，返回是否存在错误。

\subsubsection{repo}
repo 模块用来创建 repo 、提交 rootfs 数据，也包括 \texttt{os\_desc.xml} 的提交。

repo 模块调用时需要传入：
\begin{itemize}[leftmargin=4em]
\item rootfs dir
\item os desc xml
\item repo dir
\item log writer
\end{itemize}

执行完成后，返回是否存在错误。

\subsection{关键流程设计}
\subsubsection{整体流程}
\begin{center}
  \begin{adjustbox}{scale=1.0}
    \begin{plantuml}
      @startuml
      main -> debootstrap : 根据 core list 构建 rootfs
      debootstrap --> main : rootfs
      main -> chroot : 根据 extra list 构建 rootfs
      chroot --> main : rootfs
      main -> hooks : 执行 chroot hooks
      hooks -> chroot : command list
      chroot --> hooks
      hooks --> main
      main -> hooks : 执行无需 chroot 的 hooks
      hooks --> main
      main -> repo : 提交 rootfs 和 os_desc.xml
      repo --> main
      @enduml
    \end{plantuml}
  \end{adjustbox}

  图 2.2 构建流程
\end{center}

\subsubsection{chroot 流程}
\begin{center}
  \begin{adjustbox}{scale=1.0}
    \begin{plantuml}
      @startuml
      :main;
      :call chroot;
      :mount /proc,/sys,/dev,/dev/pts;
      while (遍历 command list)
      :执行 command;
      if (执行失败?) then (Y)
      break
      endif
      endwhile
      :umount /proc,/sys,/dev;
      @enduml
    \end{plantuml}
  \end{adjustbox}

  图 2.3 chroot 流程
\end{center}

\subsubsection{repo commit 流程}
\begin{center}
  \begin{adjustbox}{scale=1.0}
    \begin{plantuml}
      @startuml
      :main;
      :call repo commit;
      if (repo 是否存在?) then (N)
      :创建 repo;
      endif
      :checkout META-INF 到 rootfs;
      :复制 os_desc.xml 到 META-INF;
      :commit rootfs/usr;
      @enduml
    \end{plantuml}
  \end{adjustbox}

  图 2.4 commit 流程
\end{center}

\section{附录}
\begin{itemize}[leftmargin=4em]
\item \href{https://gitlabwh.uniontech.com/wuhan/v23/atomic/uos-upgrade-manager/-/tree/master/docs}{原子更新文档}
\end{itemize}

\end{document}
