官网 第 9 章 使用 anaconda 安装
Anaconda是Fedora,Red Hat Enterprise Linux及其衍生产品中使用的操作系统安装程序。它由Python模块和脚本以及一些其他文件组成,如Gtk小部件(用C编写),systemd单元和dracut库。它们共同构成了一个工具,允许用户设置生成(目标)系统的参数,然后在机器上安装设置的系统。安装过程有四个主要步骤:
Anaconda提供三种方法控制安装程序并指定安装选项。
注意
:另一个Anaconda的字面含义:是一个用于python/R科学计算和机器学习的开源工具(也称为Python的一种发行版),支持 Linux, macOS, Windows, 包含了conda等众多工具包及其依赖项,提供了包管理与环境管理的功能,可以很方便地解决多版本python并存、切换以及各种第三方包安装问题。请不要混淆!
Anaconda是由Python模块、shell脚本和几个外部包和库组成。此工具集的主要组件包括以下几块:
安装过程中数据的生命周期很简单。如果提供了Kickstart文件,它将由pykickstart模块处理并作为树状结构导入到内存中。如果未提供Kickstart文件,则会创建一个空的树状结构。如果安装是交互式的(并非所有必需的Kickstart命令都已使用),则会根据用户在交互式界面中做出的选择更新结构。完成所有必需的选择后,安装过程开始,结构中存储的值用于确定安装的参数。这些值也写为Kickstart文件,保存在/root
已安装系统的目录中; 因此,可以通过重用此自动生成的Kickstart文件自动安装。
树状结构的元素由pykickstart包定义,但其中一些可以通过pyanaconda.kickstart模块中的修改版本覆盖。管理此行为的一个重要规则是没有存储配置数据的位置,并且安装过程是数据驱动的,并且尽可能地依赖于事务。所以必须拥有以下功能:
安装是数据驱动的事实,意味着安装和配置逻辑位于树状结构中的项的方法内。setup如果需要,设置每个项目(方法)以修改安装的运行时环境,然后执行(该execute方法)以在目标系统上执行更改。
在Fedora的早期版本中,安装程序的界面遵循向导设计模式,包括多个线性屏幕,偶尔嵌套模式弹出对话框。(参见下图)虽然使用向导作为设计模式并不存在任何问题,但安装程序所需的大量屏幕使其变得笨拙。你可以在这个过程中结束几个屏幕,并且需要返回并在之前的屏幕上更改某些内容,需要大量点击和屏幕翻转才能返回并返回到离开的位置。多个模态嵌套对话窗口有时使得与某些屏幕交互,特别是与分区相关的屏幕相混淆。
为了解决这些问题和其他问题,安装程序开发团队将UI模型从基于线性向导的模型更改为中心辐射模型。基本上,安装程序UI已被提炼为两个主菜单,您可以从中选择访问各种选项屏幕。每个菜单都列出了每个子屏幕,并总结了为每个子屏幕选择的选项,因此您可以跳过不需要配置的屏幕(如果您愿意)。请参阅下图,了解中心和辐条模型的工作原理。
Hub&Spoke模型中提供的新安装程序解决了旧代码库中难以解决的许多问题:
线程和通信
在安装过程中需要执行的某些操作(例如扫描现有分区的磁盘或下载程序包元数据)可能需要很长时间。为了防止等待并尽可能保持响应,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用作传送安装进度更新的介质。基于文本的界面也需要这些机制情况更复杂; 文本模式中没有主循环,而是在此模式下的大部分时间都花在等待键盘输入上。
anaconda 启动首先初始化线程,为启动 Gtk 做准备,然后设置 flags 准备初始化日志记录。导入系统安装的设置模块 vnc, kickstart, ntp, keyboard, display, startup_utils, rescue, geoloc 等,然后设置各种信号处理程序,加载 DBus ,获取并读取 (不执行) 提供或者默认的 kickstart 配置文件,获取当前位置,以便设置时区, 设置语言, 初始化网络, 准备启动 UI, 通过 UI 进行配置并将更新的内容写回 kickstart 文件中, 最后根据设置安装程序。
源码目录结构及简单解析
pyanaconda/ui/
gui/
:图形界面接口实现代码。tui/
:字符界面及命令行界面实现代码。init.py
及 common.py
:定义了gui和tui通用的基类(base class)communication.py
:负责UI中类的通信。包含用于在UI中的对象之间进行通信的常量和方法。pyanaconda/vnc.py
: 此文件控制在安装期间请求时设置VNC.这些是anaconda支持的接口的主要UI文件:图形,文本和命令行(实际上只是一种特殊形式的文本)。每个都由它自己的目录实现。对于图形安装程序,glade接口文件位于同一位置。对于文本安装程序,这还包括执行面向行的输入/输出所需的代码。这里有一个定义良好的API,允许添加额外的接口并使用新屏幕扩展现有接口.
glade/
及python/
:让用户接口构建器知道组件的存在及实现python的自省。这两个目录是支持文件。glade子目录包含帮助glade理解这些新窗口小部件的代码,以便可以在界面构建器中使用它们。python子目录包含允许以更原生的Python方式通过gobject-introspection使用小部件的代码。src/
:实现各组件。这是自己实现小部件的代码。每个窗口小部件类有一个标头和一个源代码文件。Glade是RAD (快速应用开发)工具,用于创建基于GTK 工具包和GNOME桌面。 其界面是类似于GIMP,可以进行定制,甚至嵌入到Anjuta。Glade包括一些接口模块,如文本框,对话框标签,数字输入,复选框,菜单,使界面的开发更快。界面设计存储为XML格式,从而使这些设计可以方便地与外部接口结合。安装Glade也很简单。例如,在Fedora中,您可以敲入命令yum安装glade3。Glade没有Anjuta一样的强大的项目管理,但您可以创建,编辑和保存项目。
通过导入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 设备根据需要进行逻辑卷创建等操作,并进行分区
pyanaconda/bootloader.py
新版本已经将此模块拆分成一个package,此文件夹下的文件控制配置和写入引导加载程序到已安装的系统。每种类型的机器都有自己的引导加载程序方式(引导加载程序支持哪些类型的设备和文件系统,配置文件的语法等)。因此有创建自己的类。此文件还可以处理内核命令行参数。
class Arguments
- 获取特定的ip
class 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): 添加非默认的其他的系统引导
pyanaconda/desktop.py
- 桌面配置
pyanaconda/keyboard.py
- 设置键盘
pyanaconda/localization.py
- 获取位置
pyanaconda/network.py
- 设置网络
pyanaconda/ntp.py
- 配置ntp
pyanaconda/timezone.py
- 时区设置
pyanaconda/users.py
- 设置用户
这些文件包含通过界面或kickstart输入的配置设置。在某种程度上,它们会影响安装(例如,语言和键盘设置在anaconda中使用)。但是,主要目的是在安装结束时将这些内容写入已安装的系统。
pyanaconda/payload/
dnfpayload.py
和livepayload.py
。每个后端都提供了选择和删除环境,组和包的方法; 配置回购以在安装期间和安装后使用; 报告进展; 等等。这里有一个定义良好的API,允许添加额外的后端。安装类定义形成一种安装配置文件的设置。这包括显示和跳过的步骤,产品名称,安装方法,启用的存储库,配置设置等。主要使用它来创建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
Kickstart是一种自动化安装的方法,它为anaconda提供了一个文件,其中包含用户必须通过UI提供的所有数据。此文件是pykickstart包中的解析器和anaconda内部之间的接口。它主要提供了一种在anaconda期望的地方保存设置的方法,帮助UI在内存中构造了一个kickstart数据对象。
data/liveinst/
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报告问题的地方。
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更新。
平台配置
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通信以及许多其他任务。它们还包含不适合其他任何地方的方法。
这是在系统启动结束时通过systemd调用的主要anaconda程序。它处理大量环境设置,启用更新(如果存在),读取任何kickstart文件,设置VNC以及其他任务。完成所有这些操作后,它将控制权交给UI,后者又驱动安装的其余部分。
data/systemd/
- 用于系统启动时的服务脚本
dracut/
升级工具
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年投入使用以来,它还没有更新过.