Anaconda 简要介绍
- 1. Anaconda 简介
- 2. Anaconda 体系结构
- 3. Anaconda 开发模型
- 4. Anaconda 启动概述
- 5. Anaconda 源码
- 1. 接口
- 2. 自定义组件
- 3. 硬盘分区:使用python-blivet包
- 4. Bootloader
- 5. 各个步骤的配置:
- 6. 安装软件包:
- 7. 安装控制: 不同的发行版可以定义不同的安装类。
- 8. 无人值守安装:pyanaconda/kickstart.py
- 9. 通过liveCD安装系统:
- 10. 错误处理/日志:
- 11. 安装控制模块
- 12. 库:提供一些工具如获得用户位置,安装平台等。
- 13. 主程序anaconda:由systemd在系统启动后调用,设置环境、VNC等。
- 14. 系统启动
- 15. 其他
官网 第 9 章 使用 anaconda 安装
1. Anaconda 简介
Anaconda是Fedora,Red Hat Enterprise Linux及其衍生产品中使用的操作系统安装程序。它由Python模块和脚本以及一些其他文件组成,如Gtk小部件(用C编写),systemd单元和dracut库。它们共同构成了一个工具,允许用户设置生成(目标)系统的参数,然后在机器上安装设置的系统。安装过程有四个主要步骤:
- 安装目标准备(通常是磁盘分区)
- 包和数据安装
- 引导加载程序安装和配置
- 新安装的系统的配置
Anaconda提供三种方法控制安装程序并指定安装选项。
- 图形用户界面(GUI)。此接口旨在允许用户在开始安装之前以很少或不需要配置的交互式安装,并且应该涵盖所有常见用例,包括设置复杂的分区布局。图形界面还支持远程访问VNC,即使在没有显卡的系统上也可以使用GUI。
- 文本模式(TUI)。此接口旨在允许用户执行交互式安装。TUI的工作方式类似于单色行式打印机,即在不支持光标移动,颜色和其他高级功能的串行控制台上也能工作。文本模式的局限性在于它只允许您自定义最常用的选项,例如网络设置,语言选项或安装(包)源; 此界面中不提供手动分区等高级功能。
- Kickstart文件安装。一个带有类似shell语法的纯文本文件,它可以定义驱动安装过程的数据。Kickstart文件允许部分或完全自动化安装。配置所有必需区域的某组命令完全自动化安装; 如果缺少一个或多个所需命令,则安装将需要交互。如果存在所有必需的命令,则将以完全自动的方式执行安装,而无需任何交互。Kickstart提供的选项涵盖了TUI和GUI都不覆盖的用例。Kickstart支持Anaconda中的每个功能; 其他接口仅遵循所有可用选项的子集。
注意
:另一个Anaconda的字面含义:是一个用于python/R科学计算和机器学习的开源工具(也称为Python的一种发行版),支持 Linux, macOS, Windows, 包含了conda等众多工具包及其依赖项,提供了包管理与环境管理的功能,可以很方便地解决多版本python并存、切换以及各种第三方包安装问题。请不要混淆!
2. Anaconda 体系结构
Anaconda是由Python模块、shell脚本和几个外部包和库组成。此工具集的主要组件包括以下几块:
- pykickstart 用于解析和验证Kickstart文件,还提供存储驱动安装的值的数据结构
- yum 包管理器,它处理包的安装和解决依赖关系
- blivet 最初从anaconda包拆分为pyanaconda.storage; 用于处理与存储管理相关的所有活动
- pyanaconda 包含用户界面核心和Anaconda独有功能模块的软件包,例如键盘和时区选择,网络配置和用户创建,以及许多实用程序和面向系统的功能
- python-meh 包含一个异常处理程序,它在崩溃的情况下收集并存储其他系统信息,并将此信息传递给libreport库,库本身也是ABRT项目的一部分。
安装过程中数据的生命周期很简单。如果提供了Kickstart文件,它将由pykickstart模块处理并作为树状结构导入到内存中。如果未提供Kickstart文件,则会创建一个空的树状结构。如果安装是交互式的(并非所有必需的Kickstart命令都已使用),则会根据用户在交互式界面中做出的选择更新结构。完成所有必需的选择后,安装过程开始,结构中存储的值用于确定安装的参数。这些值也写为Kickstart文件,保存在/root
已安装系统的目录中; 因此,可以通过重用此自动生成的Kickstart文件自动安装。
树状结构的元素由pykickstart包定义,但其中一些可以通过pyanaconda.kickstart模块中的修改版本覆盖。管理此行为的一个重要规则是没有存储配置数据的位置,并且安装过程是数据驱动的,并且尽可能地依赖于事务。所以必须拥有以下功能:
- Kickstart 必须支持 安装程序的每个功能。
- 在安装过程中有一个明显的点,将更改写入目标系统之前,没有进行持久的更改(例如格式化存储)。
- 在用户界面中手动进行的每个更改都会反映在生成的Kickstart文件中,并且可以生成的Kickstart文件重复使用。
安装是数据驱动的事实,意味着安装和配置逻辑位于树状结构中的项的方法内。setup如果需要,设置每个项目(方法)以修改安装的运行时环境,然后执行(该execute方法)以在目标系统上执行更改。
3. Anaconda 开发模型
在Fedora的早期版本中,安装程序的界面遵循向导设计模式,包括多个线性屏幕,偶尔嵌套模式弹出对话框。(参见下图)虽然使用向导作为设计模式并不存在任何问题,但安装程序所需的大量屏幕使其变得笨拙。你可以在这个过程中结束几个屏幕,并且需要返回并在之前的屏幕上更改某些内容,需要大量点击和屏幕翻转才能返回并返回到离开的位置。多个模态嵌套对话窗口有时使得与某些屏幕交互,特别是与分区相关的屏幕相混淆。
为了解决这些问题和其他问题,安装程序开发团队将UI模型从基于线性向导的模型更改为中心辐射模型。基本上,安装程序UI已被提炼为两个主菜单,您可以从中选择访问各种选项屏幕。每个菜单都列出了每个子屏幕,并总结了为每个子屏幕选择的选项,因此您可以跳过不需要配置的屏幕(如果您愿意)。请参阅下图,了解中心和辐条模型的工作原理。
Hub&Spoke模型中提供的新安装程序解决了旧代码库中难以解决的许多问题:
- 新安装程序是以模块化方式编写的,因此没有多个代码副本可以分散在代码库中。
- 使用安装程序时,可以在后台执行长时间运行的任务。例如,当您首次启动安装程序并登陆第一个屏幕进行语言选择时,安装程序将在后台尝试自动检测您的网络设置并为其设置网络连接。
- 新安装程序的UI编写方式使其在等待CPU和时间密集型任务处理时不会阻塞和冻结。
- 新安装程序主要基于kickstart,无论您是否使用自动和无人参与的kickstart选项进行安装,文本用户界面或图形用户界面。除了实时媒体安装方法之外,这三者共享一个通用代码库,提供跨安装方法的更一致的体验以及更容易维护的代码库。最终,计划是在安装期间自动检测系统可用的任何kickstart文件,并提供使用kickstart中的值预填充UI中的字段以帮助节省用户时间。
- 通过更改为hub-and-spoke模型而不是线性向导模型,新UI允许用户完全跳过他们不感兴趣与之交互的屏幕,将安装过程简化为仅对那些最重要的屏幕安装继续。
- 当Fedora 19完成该功能后,新安装程序将允许您在安装程序下载并安装Fedora到您的计算机时完成firstboot,从而有助于进一步简化安装过程。如果您选择在安装期间未完成firstboot,则在重新引导系统后将显示该引导。
线程和通信
在安装过程中需要执行的某些操作(例如扫描现有分区的磁盘或下载程序包元数据)可能需要很长时间。为了防止等待并尽可能保持响应,Anaconda会在单独的线程中运行这些操作。
- 在基于GTK工具包(GTK+(GIMP Toolkit)是一套源码以LGPL许可协议分发、跨平台的图形工具包。最初是为GIMP写的,已成为一个功能强大、设计灵活的一个通用图形库,是GNU/Linux下开发图形界面的应用程序的主流开发工具之一。)不支持从多个线程元素的变化。Gtk的主事件循环在Anaconda进程本身的主线程中运行,执行涉及GUI的操作的所有代码必须确保这些操作也在主线程中运行。唯一支持的方法是使用GLib.idle_add,这并不总是容易或需要。为了缓解这个问题,
pyanaconda.ui.gui.utils
模块中定义了几个辅助函数和装饰器。其中最有用的是@gtk_action_wait
和@gtk_action_nowait
装饰器。它们以这样一种方式更改装饰函数或方法:当调用此函数或方法时,它会自动排入Gtk的主循环,在主线程中运行,返回值分别返回给调用者或删除。- GIMP 是 GNU 图像处理程序 (GNU Image Manipulation Program) 的缩写。包括几乎所有图象处理所需的功能,号称 Linux 下的 PhotoShop。GIMP 在 Linux 系统推出时就风靡了许多绘图爱好 者的喜爱,它的接口相当轻巧,但其功能却不输于专业的绘图软件;它提供了各种的影像处理工具、滤镜,还有许多的组件模块,对于要制作一个又酷又炫的网页按 钮或网站 Logo 来说是一个非常方便好用的绘图软件,因为它也提供了许多的组件模块,你只要稍加修改一下,便可制作出一个属于你的网页按钮或网站 Logo。
如前所述,使用多个线程的主要原因之一是允许用户配置某些界面,而其他当前正忙的界面(例如下载包元数据时的安装源)自行配置。一旦配置完成,之前忙碌的辐条界面需要宣布它现在已经准备好并且没有被阻止; 这由一个被调用的消息队列处理,该队列hubQ在主事件循环中被定期检查。当辐条变得可访问时,它会向此队列发送一条消息,通知此更改,并且不应再阻止它。这种情况同样适用于辐条需要刷新其状态或完成标志的情况,具有的不同配置和进展称为不同队列progressQ用作传送安装进度更新的介质。基于文本的界面也需要这些机制情况更复杂; 文本模式中没有主循环,而是在此模式下的大部分时间都花在等待键盘输入上。
4. Anaconda 启动概述
anaconda 启动首先初始化线程,为启动 Gtk 做准备,然后设置 flags 准备初始化日志记录。导入系统安装的设置模块 vnc, kickstart, ntp, keyboard, display, startup_utils, rescue, geoloc 等,然后设置各种信号处理程序,加载 DBus ,获取并读取 (不执行) 提供或者默认的 kickstart 配置文件,获取当前位置,以便设置时区, 设置语言, 初始化网络, 准备启动 UI, 通过 UI 进行配置并将更新的内容写回 kickstart 文件中, 最后根据设置安装程序。
5. Anaconda 源码
源码目录结构及简单解析
1. 接口
pyanaconda/ui/
-
gui/
:图形界面接口实现代码。 -
tui/
:字符界面及命令行界面实现代码。 -
init.py
及common.py
:定义了gui和tui通用的基类(base class) -
communication.py
:负责UI中类的通信。包含用于在UI中的对象之间进行通信的常量和方法。 -
pyanaconda/vnc.py
: 此文件控制在安装期间请求时设置VNC.
这些是anaconda支持的接口的主要UI文件:图形,文本和命令行(实际上只是一种特殊形式的文本)。每个都由它自己的目录实现。对于图形安装程序,glade接口文件位于同一位置。对于文本安装程序,这还包括执行面向行的输入/输出所需的代码。这里有一个定义良好的API,允许添加额外的接口并使用新屏幕扩展现有接口.
2. 自定义组件
-
glade/
及python/
:让用户接口构建器知道组件的存在及实现python的自省。这两个目录是支持文件。glade子目录包含帮助glade理解这些新窗口小部件的代码,以便可以在界面构建器中使用它们。python子目录包含允许以更原生的Python方式通过gobject-introspection使用小部件的代码。 -
src/
:实现各组件。这是自己实现小部件的代码。每个窗口小部件类有一个标头和一个源代码文件。
Glade是RAD (快速应用开发)工具,用于创建基于GTK 工具包和GNOME桌面。 其界面是类似于GIMP,可以进行定制,甚至嵌入到Anjuta。Glade包括一些接口模块,如文本框,对话框标签,数字输入,复选框,菜单,使界面的开发更快。界面设计存储为XML格式,从而使这些设计可以方便地与外部接口结合。安装Glade也很简单。例如,在Fedora中,您可以敲入命令yum安装glade3。Glade没有Anjuta一样的强大的项目管理,但您可以创建,编辑和保存项目。
3. 硬盘分区:使用python-blivet包
通过导入blivet包,对所选硬盘进行分区。
pyanaconda/storage/osinstall.py
class StorageDiscoveryConfig
- 用于封装各种检测/初始化参数的类。class FSSet
- 表示文件系统的类,对 FSH 定义的标准文件系统进行配置,同时提供一些必要文件的解析(创建)函数如 /etc/fstab。以及挂载/卸载文件系统选项class Root
- 将要安装的系统路径class BlkidTab
class CryptTab
class InstallerStorage
- 对系统要安装的设备进行检测,创建,设置,并且写入相应信息pyanaconda/storage/autopart.py
对所给 storage 设备根据需要进行逻辑卷创建等操作,并进行分区
4. Bootloader
pyanaconda/bootloader.py
新版本已经将此模块拆分成一个package,此文件夹下的文件控制配置和写入引导加载程序到已安装的系统。每种类型的机器都有自己的引导加载程序方式(引导加载程序支持哪些类型的设备和文件系统,配置文件的语法等)。因此有创建自己的类。此文件还可以处理内核命令行参数。class Arguments
- 获取特定的ipclass BootLoaderImage <- class LinuxBootLoaderImage
- 定义bootloader image 的基本信息,包括返回 kernel 和 initrd 的文件名class BootLoader
- 能够对磁盘进行排序,遍历安装磁盘的信息判断安装磁盘是否适合安装 bootloader,设置将要安装的 boaotloader image 文件,设置 grub 的等待时间。class GRUB
- 对 grub 安装的基本信息进行配置,读取系统信息,对每个系统写入 grub.cfg 等配置文件class GRUB2 继承 class GRUB
- 检测并安装 grub,以及密码设置等- 函数
def writeSysconfigKernel(storage, version, instClass): 根据版本获取默认内核包的名称
def writeBootLoaderFinal(storage, payload, instClass, ksdata): 最后写入引导程序
def writeBootLoader(storage, payload, instClass, ksdata): 添加非默认的其他的系统引导
5. 各个步骤的配置:
pyanaconda/desktop.py
- 桌面配置pyanaconda/keyboard.py
- 设置键盘pyanaconda/localization.py
- 获取位置pyanaconda/network.py
- 设置网络pyanaconda/ntp.py
- 配置ntppyanaconda/timezone.py
- 时区设置pyanaconda/users.py
- 设置用户
这些文件包含通过界面或kickstart输入的配置设置。在某种程度上,它们会影响安装(例如,语言和键盘设置在anaconda中使用)。但是,主要目的是在安装结束时将这些内容写入已安装的系统。
6. 安装软件包:
-
pyanaconda/payload/
这些文件控制以某种格式将文件安装到系统中。anaconda允许多个安装后端,但最常用的是dnfpayload.py
和livepayload.py
。每个后端都提供了选择和删除环境,组和包的方法; 配置回购以在安装期间和安装后使用; 报告进展; 等等。这里有一个定义良好的API,允许添加额外的后端。
7. 安装控制: 不同的发行版可以定义不同的安装类。
安装类定义形成一种安装配置文件的设置。这包括显示和跳过的步骤,产品名称,安装方法,启用的存储库,配置设置等。主要使用它来创建Fedora和RHEL安装之间的差异。其他项目或ISV可以为自己的默认值定义自己的安装类。
pyanaconda/installation_tasks.py
class BaseTask
- 保存任务的详细信息class TaskQueue 继承 class BaseTask
- 任务队列,提供 append(), insert() 等队列操作,拥有 start() 来开始队列中的任务,能够获取任务的执行的信息。class Task
- 仅仅提供单任务执行管理,与上面多个任务执行的队列不同,Task 类只支持单任务执行,同时提供一些运行信息。一个任务只能执行一次,如果需要多次执行,需要多个实例化 Task 类。- pyanaconda/installclass.py
class BaseInstallClass
- 记录将要安装系统的配置信息,并且提供设置系统安装默认信息的函数,如 setDefaultPartitioning(), customizeDefaultPartitioning() 等。class InstallClassFactory
- InstallClass工厂类 pyanaconda/installation.py
doConfiguration()
- 获取系统各种配置(通过用户给的kickstart文件,手动gui界面配置,tui界面配置),如以下代码执行对系统的各种配置进行获取。
...
configuration_queue = TaskQueue("Configuration queue") #创建一个任务队列
# connect progress
reportingconfiguration_queue.queue_started.connect(lambda x:progress_message(x.status_message))
configuration_queue.task_completed.connect(lambda x: progress_step(x.name))# 将任务添加到队列中并且执行。
os_config = TaskQueue("Installed system configuration", N_("Configuring installed system"))
os_config.append(Task("Configure authselect", ksdata.authselect.execute, (storage, ksdata, instClass)))
os_config.append(Task("Configure SELinux", ksdata.selinux.execute, (storage, ksdata, instClass)))
os_config.append(Task("Configure first boot tasks", ksdata.firstboot.execute, (storage, ksdata, instClass)))
os_config.append(Task("Configure services", ksdata.services.execute, (storage, ksdata, instClass)))
os_config.append(Task("Configure keyboard", ksdata.keyboard.execute, (storage, ksdata, instClass)))
os_config.append(Task("Configure timezone", ksdata.timezone.execute, (storage, ksdata, instClass)))
os_config.append(Task("Configure language", ksdata.lang.execute, (storage, ksdata, instClass)))
os_config.append(Task("Configure firewall", ksdata.firewall.execute, (storage, ksdata, instClass)))
os_config.append(Task("Configure X", ksdata.xconfig.execute, (storage, ksdata, instClass)))
configuration_queue.append(os_config)
...
doInstall()
- 对系统进行安装
pyanaconda/product.py
8. 无人值守安装:pyanaconda/kickstart.py
Kickstart是一种自动化安装的方法,它为anaconda提供了一个文件,其中包含用户必须通过UI提供的所有数据。此文件是pykickstart包中的解析器和anaconda内部之间的接口。它主要提供了一种在anaconda期望的地方保存设置的方法,帮助UI在内存中构造了一个kickstart数据对象。
9. 通过liveCD安装系统:
-
data/liveinst/
这些文件通过Live CD实现安装。它们提供了一种特殊的安装方法,一个特殊的软件包安装后端,以及从Live CD桌面启动安装程序所需的一些文件。
10. 错误处理/日志:
- 错误处理:
pyanaconda/rescue.py
- 提供救援模式pyanaconda/errors.py
- 错误pyanaconda/exception.py
- 异常 - 日志记录:
pyanaconda/anaconda_loggers.py
pyanaconda/anaconda_logging.py
这些文件控制着anaconda的所有错误报告。errors.py
与UI结合,控制显示用户可以执行某些操作的错误,或者至少是anaconda可以预期的错误。这是错误消息的中心位置。exception.py
控制anaconda无法预料的错误显示 - 基本上,这是处理未处理的异常的地方。这也是anaconda与libreport接口向Bugzilla报告问题的地方。
11. 安装控制模块
pyanaconda/progress.py
- 控制进度条。pyanaconda/queue.py
- 控制通信队列。pyanaconda/threads.py
- 多线程支持。
这是一个松散的重要文件集合。install.py实际上执行安装步骤,其中包括调用kickstart,anaconda和python-blivet中的方法。progress.py
提供了一种install.py和包后端的方法,用于与UI通信以移动进度条和显示消息。queue.py
是一个支持文件,用于构造通信队列,如progress.py和communication.py中使用的那些队列。最后,threads.py
处理创建和管理线程,anaconda现在广泛用于在后台运行任务,同时仍允许UI更新。
12. 库:提供一些工具如获得用户位置,安装平台等。
- 平台配置
pyanaconda/addons.py
pyanaconda/platform.py
- GeoIP和WiFi定位模块 - 基于IP地址的位置检测,获得所在时区等
pyanaconda/flags.py
pyanaconda/geoloc.py
- 国际化工具
pyanaconda/i18n.py
- find first ISO Image,mount Image
pyanaconda/image.py
pyanaconda/isys/
pyanaconda/iutil.py
pyanaconda/nm.py
pyanaconda/safe_dbus.py
这些文件提供了整个安装程序中使用的各种其他方法。这些功能包括日志记录框架,通过地理位置查找用户的位置,查找有关附加光学安装介质的信息,与NetworkManager通信以及许多其他任务。它们还包含不适合其他任何地方的方法。
13. 主程序anaconda:由systemd在系统启动后调用,设置环境、VNC等。
这是在系统启动结束时通过systemd调用的主要anaconda程序。它处理大量环境设置,启用更新(如果存在),读取任何kickstart文件,设置VNC以及其他任务。完成所有这些操作后,它将控制权交给UI,后者又驱动安装的其余部分。
14. 系统启动
data/systemd/
- 用于系统启动时的服务脚本dracut/
15. 其他
- 升级工具
scripts/makebumpver
scripts/makeupdates
makeupdates是一个用于创建测试anaconda修复程序的更新图像的工具。您可以参考特定标记或提交来调用它,它将构建一个包含自该点以来树的所有更改的图像。 - 默认配置
data/interactive-defaults.ks
data/post-scripts/
鉴于anaconda通过UI在内部构建kickstart文件然后执行它,某些安装任务更容易实现为kickstart脚本。这样做。interactive-defaults.ks是一个kickstart文件,在交互式非kickstart安装开始时插入,该安装包含UI的某些默认设置。 - 安装清理
scripts/anaconda-cleanup
scripts/instperf
scripts/instperf.p
前者是一个程序,用于监视安装期间的内存使用情况,并使用此信息写出/tmp/memory.dat。后者是一个gnuplot脚本,它解释该文件并生成图形。我们使用它来识别内存使用量的峰值。 - 错误报告提交
scripts/restart-anaconda
utils/dd/
utils/handle-sshpw
utils/logpicker
utils/log_picker/
logpicker是一种工具,用于以各种方式从安装环境中发送anaconda日志和其他有用的诊断信息(scp,ftp,Bugzilla …)。它与图形处理有一些重叠,可让您在anaconda崩溃时提交错误报告。自从2010年投入使用以来,它还没有更新过.