贺州网站制作,建设部网站资质查询6,用vs做的网站怎么打开,门户网站开发维护合同背景#xff1a;
随着业务形态#xff0c;业务种类的不断拓展#xff0c;使用公版 ISO 安装树 与 ISO 镜像存在较大的不便与弊端#xff1b;
存在安装配置不统一#xff0c;溯源难等特点#xff1b;给后期的系统运维带来很高的复杂度
目的#xff1a;
解决业务需要多种不…背景随着业务形态业务种类的不断拓展使用公版 ISO 安装树 与 ISO 镜像存在较大的不便与弊端存在安装配置不统一溯源难等特点给后期的系统运维带来很高的复杂度目的解决业务需要多种不同系统需求版本管理困难溯源难 运维排障复杂度高等痛点问题适应新型态下的多种类装机需求灵活支持便于迭代更新自定义的软件包组设置结合 kickstart 应答控制文件 结合 沙箱技术与 iPXE 技术可以使用大规模自动化装机部署术语与缩写术语名称术语解释RHEL全称为 Redhat Enterprise Linux 为红帽子公司推出的免费开源的 Linux 商业发行版CentOSCentOS 为基于 RHEL 上游释放的源码去掉 RHEL logo 与商业软件后重新编码的再发行版CentOS 社区已被 RHEL 收编目前 CentOS-7 版本于2020年结束主流支持FedoraFedora 目前已被 Redhat 收编红帽子用来实验一些新技术在此发行版稳定后移植到 RHELkickstart红帽系发行版操作系统的自动化部署控制脚本与方法ISO一种文件格式与标准BIOS基本输入输出系统为X86架构的计算机的底层的软件EFI/UEFI统一可扩展固件为全新的一种计算机的底层软件支持多种新处理器架构RPMredhat package management 红帽子包管理系统Anacondaanaconda 为红帽系发行版的 安装器installer程序grub当代 linux 发行版的主流的引导程序xml一种文件格式与标准ddlinux 下的一种操作裸磁盘块的工具yumyellow dog package management 黄狗包管理系统是红帽系自动管理RPM依赖关系自动安装软件包的一种工具python 编写python当代的流行的一种解释性的语言GPL一种开源协议原 CentOS 社区官方基于 RHEL 构建二进制兼容版本的基本流程根据实际需求出发选择基本CentOS 社区版本进行二次定制开发二次定制开发的流程大致如下分析公版 minimal 镜像 ISO 文件结构抽取拷贝原公版 ISO 中的所有文件与目录结构到 二次定制开发路径并需要留意修复抽取 ISO 后部分长文件名文件后缀名丢失的问题根据需求收集需要的 RPM 软件包与依赖包放置在 Packages 目录下根据需求收集需求的 RPM 名字修改适配软件组的主控文件 XML 文件 repodata/cca56f3cffa18f1e52302dbfcf2f0250a94c8a37acd8347ed6317cb52c8369dc-c7-x86_64-comps.xml根据上述修改后的 XML 与 Packages 中的包重新生成 repodatas 中的 ISO RPM包的 repo 数据库定制修改 anaconda installer 安装器。并输出新的 boot.iso 用于替换旧的 ISO 中的 vmlinux initrd.img 以及 suqashfs.img添加需要的额外拷贝的工具或者文件包到 ISO 构建目录修改原生的 BIOS 模式与 UEFI 模式下的 grub 引导配置文件按需修改添加 ks 文件到 ISO 中 可选步骤封装打包为 ISO 镜像为了支持超大单个文件输出为 UDF 格式嵌入 hybrid 启动 与 MD5 指纹到 ISO 中测试安装 ISO发布定制需求基于公版 centos 7.9 minimal 镜像二次定制开发定制修改 anaconda installer 支持高级功能软件组越小越好需要支持基本的容器项目的正常运行需要自动化安装无需人工干预系统盘分区采用标准分区根据主流的 CSI benchmark 安全红线要求设置用户的密码强度要求弱密码不准使用首次登录必须更改密码默认不开防火墙与 selinux 服务默认系统为英语环境美式键盘上海时区默认增大系统单个进程能打开的句柄数到 65536*2默认启用 root用户的 ssh 访问采用图形化安装界面默认系统盘选盘逻辑要适应多盘位的使用场景支持多种类型的磁盘支持 vmware与 KVM 虚拟机部署增加的个性化的定制化信息支持放入超大的软件包超过 4GB支持使用U盘刻录安装支持带外 BMC 挂载 ISO 安装刻录 cd/dvd 安装支持 UEFI 与 BIOS 两种引导方式默认系统需要禁用 CPU C-stat 省电安装完后的系统中删除ks文件防止泄密默认需要开启 KDUMP 服务默认需要关闭不必要的后台服务系统默认网络采用 DHCP无需设置主机名系统默认预置两个用户一个 root 用户一个 isotest 用户 root 用户密码为 XXXXX iso_test 用户默认密码为 isotest系统默认密码文件采用影子形式加密存储原版社区的 ISO 镜像俗称公版ISO镜像树的结构解析公版的 CentOS-2009-Minimal_x86_64.iso 镜像文件将镜像挂载到 /media 目录可以看到 ISO 抽取后的文件目录结构如下目录说明EFI 存放EFI 模式的引导文件images 存放efi 文件与PXE 启动的内核与临时跟文件系统文件 stage1 image 目录isolinux 存放 BIOS 模式引导文件 stage1 image 目录LiveOS 存放 Anaconda installer 的目录stage2 image 目录Packages 存放 RPM 软件包的目录repodata 存放 RPM 软件组元数据的目录文件说明CentOS_BuildTag CentOS 构建标签.discinfo 记录构建 ISO 时间戳ISO架构信息版本号.treeinfo 记录构建 ISO 中重要文件的配置文件RPM-GPG-KEY-CentOS-7 RPM 包的 GPG KEYRPM-GPG-KEY-CentOS-Testing-7 RPM 包的 GPG KEY.TBL 记录 ISO 生成时的文件名转换的文件EULA 用户协议文档GPL CentOS 的开源协议BIOS 模式 ISO 启动流程BIOS 模式 server 启动 ---- BIOS POST ----- BIOS 选择选择从 CD/DVD 启动 ----- ISO 读取启动扇区偏移 ---- isolinux/isolinux.bingrub2 程序 ---- 读取 isolinux/isolinux.cfg 启动菜单(stage1 阶段 ) ----- 按照菜单的配置 stage2 阶段 加载 isolinux/vmlinuz 内核 isolinux/initrd.img ----- (切换加载 安装器 anaconda installer rootfs LiveOS/squashfs.img ) ----- 加载基础的各类 systemd 服务 ------ 启动默认的 default-target 实际指向 ----- anaconda.service ----- 启动 anaconda 图形安装界面 or anaconda text 安装界面 ----- 手动选择安装 or kickstart 自动安装UEFI 模式 server 启动 ---- BIOS POST ----- UEFI 选择选择从 CD/DVD 启动 ----- ISO 读取 EFI BOOT 信息---- grub2 程序BOOTX64.EFI ---- 读取 EFI/BOOT/grub.cfg 启动菜单(stage1 阶段 ) ----- 按照菜单的配置 stage2 阶段 加载 image/pxeboot/vmlinuz 内核 image/pxeboot/initrd.img ----- (切换加载 安装器 anaconda installer rootfs LiveOS/squashfs.img) ----- 加载基础的各类 systemd 服务 ------ 启动默认的 default-target 实际指向 ----- anaconda.service ----- 启动 anaconda 图形安装界面 or anaconda text 安装界面 ----- 手动选择安装 or kickstart 自动安装引导菜单定制开发背景引导菜单的设计分为两类一种是传统的 BIOS 类型引导一种是 UEFI/EFI 类型的引导其中BIOS类型的引导目前使用的是开源的 syslinux 组件中的 isolinux 部分组件实现的 而 EFI/UEFI 模式则采用 grubx64.efi 或 BOOTX64.EFI 完成引导实现方法逻辑两种类型引导的原版引导文件打开进行走读掌握两种模式的引导菜单的语法格式参数等等主要修改点是修改引导时指定的安装菜单的标签名称stage2 阶段映像的加载的媒介的标签以及添加获取自动安装 ks 的内核传参外加一些额外的内核参数 ; 定制的图形启动菜单背景图 LOGO 信息也可以写在里面但是目前图形化的引导菜单支持目前 BIOS 模式支持比较好UEFI 模式不做处理于支持修改后的配置文件示意BIOS 模式启动菜单 引导文件为 ISO目录中的 isolinux/isolinux.cfg 文件/* by 01130.hk - online tools website : 01130.hk/zh/calcpressure.html */ prompt 1 ui vesamenu.c32 menu background splash.jpg default kickstart MENU TITLE RTX-9090 Linux BOOT MENU timeout 50 # Do not display the actual menu unless the user presses a key. All that is displayed is a timeout message. menu tabmsg Press Tab for full configuration options on menu items. menu separator # insert an empty line menu separator # insert an empty line label kickstart menu label ^INSTALL RTXOS X86_64 LAGACY kernel vmlinuz append initrdinitrd.img inst.stage2hd:LABELrtxOS:/ inst.kshd:LABELrtxOS:/ks.cfg vga791 modprobe.blacklistnouveau menu separator # insert an empty line label isocheck menu label Test This Media Install RTXOS kernel vmlinuz append initrdinitrd.img inst.stage2hd:LABELrtxOS:/ inst.kshd:LABELrtxOS:/ks.cfg rd.live.check quiet vga791 modprobe.blacklistnouveau menu separator # insert an empty line label memtest menu label Run a ^Memory Test text help If your system is having issues, a problem with your systems memory may be the cause. Use this utility to see if the memory is working correctly. endtext kernel memtest menu separator # insert an empty line label rescue menu indent count 5 menu label ^Rescue a RTXOS system text help If the system will not boot, this lets you access files and edit config files to try to get it booting again. endtext kernel vmlinuz append initrdinitrd.img inst.stage2hd:LABELrtxOS:/ rescue vga791 modprobe.blacklistnouveau menu separator # insert an empty line menu separator # insert an empty line menu endUEFI 模式下的启动菜单/* by 01130.hk - online tools website : 01130.hk/zh/calcpressure.html */ set default1 function load_video { insmod efi_gop insmod efi_uga insmod video_bochs insmod video_cirrus insmod all_video } load_video set gfxpayloadkeep insmod gzio insmod part_gpt insmod ext2 set timeout5 ### END /etc/grub.d/00_header ### search --no-floppy --setroot -l rtxOS ### BEGIN /etc/grub.d/10_linux ### menuentry Test This Media Install RTXOS X86_64 UEFI --class fedora --class gnu-linux --class gnu --class os { linuxefi /images/pxeboot/vmlinuz rd.live.check inst.stage2hd:LABELrtxOS:/ inst.kshd:LABELrtxOS:/ks.cfg vga791 modprobe.blacklistnouveau initrdefi /images/pxeboot/initrd.img } menuentry INSTALL RTXOS X86_64 UEFI --class fedora --class gnu-linux --class gnu --class os { linuxefi /images/pxeboot/vmlinuz inst.stage2hd:LABELrtxOS:/ inst.kshd:LABELrtxOS:/ks.cfg vga791 modprobe.blacklistnouveau initrdefi /images/pxeboot/initrd.img } menuentry Rescue A RTXOS System --class fedora --class gnu-linux --class gnu --class os { linuxefi /images/pxeboot/vmlinuz inst.stage2hd:LABELrtxOS:/ rescue vga791 modprobe.blacklistnouveau initrdefi /images/pxeboot/initrd.img }定制 修改 XML 配置文件 阅红帽子的官方资料后得知XXXX-minimal-x86_64-comps.xml 即为定义软件组的XML控制文件XML中存放着软件包的语言描述名字环境组软件组等等信息eg: 简化后的 软件组环境组的基本结构如下一个环境组中可以包含多个软件组软件包组包含需要安装的 RPM 包的名称列表环境包组包含需要安装的软件包组的名称使用tab 缩进4个字符定义软件组软件组包含需要的RPM包列表group 代表定义一个软件组 idXXXX/id 软件组的检索字段 name xml:langen_GBcustom_name/name 软件组的英文基本名称自行编写 name xml:langzh_CN定制的软件组名称/name 软件组的中文基本名称自行编写 descriptionSmallest possible installation./description 软件组的英文的基本描述自行编写 description xml:langzh_CN最小可能安装。/description 软件组的支持中文的基本描述自行编写 defaultfalse/default 是否为默认一般保持默认不用更改 uservisiblefalse/uservisible 是否用户可见一般保持默认不用更改 packagelist RPM包列表XML固定语法写法 packagereq typemandatoryXXXXX/packagereq 需要的RPM包在这里定义XXXXX为rpm包名称其中 type 字段有三类default默认的 mandatory强制的 optional可选的可选的包一般不会进行安装 /packagelist XML 语法写法 /group XML语法写法定义环境组环境组包含了需要的软件组enviroment 定义一个环境组 idXXXX/id 环境组检索字段 nameXXXXXXXXXX/name 环境组名称自行编写 name xml:langzh_CN简体中文描述/name 环境组名称的基本名称自行编写 descriptionBasic functionality./description 环境组的英文基本描述自行编写 description xml:langzh_CN简体中文的描述/description 环境组的支持中文的基本描述自行编写 display_order5/display_order 显示顺序一般不用更改 grouplist 声明使用哪些软件组自行编写 groupidXXXX/groupid 需要的软件组的名称 /grouplist XML语法固定写法 /enviroment XML语法固定写法软件组与环境组关系如下重建包依赖 repo 数据库上述修改后使用 createrepo 工具 重新基于上面的 XML 重新生成 repodata 下面的 RPM 包的依赖关系数据库 保存到 ISO 构建的本地路径下Anaconda Installer 的定制开发Anaconda 安装器简介Anaconda 安装器是 RHELCentOSFedora 发行版的操作系统安装器采用python语言编写 Anaconda是在ISO加载完内核 vmlinuz与临时的 initrd.img 完成初始化后chroot 后切换到安装器所在的真实 rootfs 文件系统然后调用 /usr/sbin/anaconda 住入库启动 安装器的文件系统是运行在内存中的最小的内存需求为大于等于1536 MB否则 GUI 的 Ananconda 安装器无法初始化只能进入text 文本模式安装模式土办法修改Anaconda 安装器是包在 ISO 文件的 LiveOS 目录下的 squashf.img中一组 python 程序其中LiveOS 下的squashfs.img 是可以解压进行修改重新打包所以也可以用来做定制可以在 LIVE rootfs 中进行厂商信息修改或者添加缺少命令工具的话可以利用 yum install XXXXX --installrootXXXXX 补全部分缺少的命令工具最后修改完成后安装 解压 squashfs.img 的逆操作全部反过来操作就行当然也可以用原厂开源的专用制作工具进行定制开发修改 关键命令行工具说明mock创建干净构建环境 使用 mock build RPMrpmbuildRPM 包构建工具createrepo创建YUM仓库lorax红帽子系列发行版的 OS 官方镜像构建工具pungiFedora/CentOS 镜像构建工具mkisofs/genisoimageISO 镜像创建工具Anaconda红帽子系列发行版的 OS 安装程序器X86_64 处理器架构对应的 7.x KE linux 定制版 lorax 修改点如下 说明 lorax 主要修改的配置文件模板的路径为 /usr/share/lorax//usr/share/lorax/runtime-install.tmpl 安装配置 anaconda liveos 的主配置文件/usr/share/lorax/runtime-postinstall.tmpl 安装完基础的 OS 后额外配置的入口配置文件/usr/share/lorax/runtime-cleanup.tmpl 安装完成后执行清理的配置文件/usr/share/lorax/x86.tmpl 最后阶段生成对应架构的 ISO 的模板文件/usr/share/lorax/config_files/common 存放模板配置文件的 目录修改新增原有 anaconda 安装器缺少的功能不能执行 ipmitool 设置带外缺少部分编辑器压缩解压下载工具缺少调试日志用的网络连接ssh 功能被禁用增加集成阵列卡的识别管理工具增加自由品牌厂商的定制化安装信息 LOGO 自定义安装类 (installclass)自定义 systemd 服务 等等自定义安装类说明配置安装类存放目录 /usr/lib64/python2.7/site-packages/pyanaconda/installclasses/分析 通过解压 公版的 suqashfs.img rootfs 根解读下面的 /.buildstamp 中的配置定义推测[Main]ProductcentosVersion7BugURLxxxxxxxIsFinalTrueUUID202011251613[Compose]Lorax19.7.19-xxx厂商信息为 productXXX 定义的其中 XXX 为修改后的自定义的厂商信息 修改此处要在 rootfs 的 /usr/lib64/python2.7/site-packages/pyanaconda/installclasses/ 里面添加修改对应的包含 productXXX 字段的 install_class 的方法否则安装器会出现奔溃报错 厂商自定义的安装类参考 centos.py 的写法# # rhel.py # # Copyright (C) 2010 Red Hat, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # import os import logging log logging.getLogger(anaconda) from pyanaconda.installclass import BaseInstallClass from pyanaconda.product import productName from pyanaconda import network from pyanaconda import nm from pyanaconda import iutil from pyanaconda.kickstart import getAvailableDiskSpace from blivet.partspec import PartSpec from blivet.platform import platform from blivet.devicelibs import swap from blivet.size import Size __all__ [RHELBaseInstallClass, RHELAtomicInstallClass] class RHELBaseInstallClass(BaseInstallClass): name CentOS Linux sortPriority 20001 if not productName.startswith(CentOS): hidden True defaultFS xfs bootloaderTimeoutDefault 5 ignoredPackages [ntfsprogs, reiserfs-utils, hfsplus-tools] installUpdates False _l10n_domain comps efi_dir centos help_placeholder CentOSPlaceholder.html help_placeholder_with_links CentOSPlaceholderWithLinks.html def configure(self, anaconda): BaseInstallClass.configure(self, anaconda) def setNetworkOnbootDefault(self, ksdata): if any(nd.onboot for nd in ksdata.network.network if nd.device): return # choose the device used during installation # (ie for majority of cases the one having the default route) dev network.default_route_device() \ or network.default_route_device(familyinet6) if not dev: return # ignore wireless (its ifcfgs would need to be handled differently) if nm.nm_device_type_is_wifi(dev): return network.update_onboot_value(dev, True, ksdataksdata) def __init__(self): BaseInstallClass.__init__(self) class RHELAtomicInstallClass(RHELBaseInstallClass): name CentOS Atomic Host sortPriority21001 hidden not productName.startswith((CentOS Atomic Host, CentOS Linux Atomic)) def __init__(self): self.localemap {} # loaded lazily RHELBaseInstallClass.__init__(self) def setDefaultPartitioning(self, storage): autorequests [PartSpec(mountpoint/, fstypestorage.defaultFSType, sizeSize(3GiB), maxSizeSize(15GiB), growTrue, lvTrue, thinTrue, encryptedTrue)] bootreqs platform.setDefaultPartitioning() if bootreqs: autorequests.extend(bootreqs) disk_space getAvailableDiskSpace(storage) swp swap.swapSuggestion(disk_spacedisk_space) autorequests.append(PartSpec(fstypeswap, sizeswp, growFalse, lvTrue, encryptedTrue)) for autoreq in autorequests: if autoreq.fstype is None: if autoreq.mountpoint /boot: autoreq.fstype storage.defaultBootFSType autoreq.size Size(300MiB) else: autoreq.fstype storage.defaultFSType storage.autoPartitionRequests autorequests def filterSupportedLangs(self, ksdata, langs): self._initialize_localemap(ksdata.ostreesetup.ref, ksdata.ostreesetup.url) for lang in langs: if lang in self.localemap: yield lang def filterSupportedLocales(self, ksdata, lang, locales): self._initialize_localemap(ksdata.ostreesetup.ref, ksdata.ostreesetup.url) supported [] if lang in self.localemap: for locale in locales: stripped self._strip_codeset_and_modifier(locale) if stripped in self.localemap[lang]: supported.append(locale) return supported def _initialize_localemap(self, ref, repo): if self.localemap: return # fallback to just en_US in case of errors self.localemap { en: [en_US] } # Lets only handle local embedded repos for now. Anyway, itd probably # not be very common to only override ostreesetup through kickstart and # still want the interactive installer. Though to be nice, lets handle # that case. if not repo.startswith(file://): log.info(ostree repo is not local; defaulting to en_US) return # convert to regular UNIX path repo repo[len(file://):] iutil.mkdirChain(os.path.join(repo, tmp/usr/lib)) rc iutil.execWithRedirect(/usr/bin/ostree, [checkout, --repo, repo, ref, --subpath, /usr/lib/locale/locale-archive, install/ostree/tmp/usr/lib/locale]) if rc ! 0: log.error(failed to check out locale-archive; check program.log) return for line in iutil.execReadlines(/usr/bin/localedef, [--prefix, os.path.join(repo, tmp), --list-archive]): line self._strip_codeset_and_modifier(line) (lang, _) line.split(_) if lang not in self.localemap: self.localemap[lang] [line] else: self.localemap[lang].append(line) staticmethod def _strip_codeset_and_modifier(locale): if in locale: locale locale[:locale.find()] if . in locale: locale locale[:locale.find(.)] return locale其中我们需要修改点需要基于本身的 centos.py 拷贝一份新的命名为 xxxx.py 再进行修改需要修改为 RHELBaseInstallClass 与 RHELAtomicInstallClass 两个类中的厂商信息 productName 变量这个信息字段为 /.buildstamp 中 product 后面的字段分析 centos.py 安装类的导入函数时可以看到 productName 是从 pyanaconda.product 里面导入的检查 /usr/lib64/python2.7/site-packages/pyanaconda/product.py 代码逻辑如下# # product.py: product identification string # # Copyright (C) 2003 Red Hat, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # import ConfigParser import os from pyanaconda.i18n import _ # First, load in the defaults. In order of precedence: contents of # .buildstamp, environment, stupid last ditch hardcoded defaults. config ConfigParser.ConfigParser() config.add_section(Main) config.set(Main, Arch, os.environ.get(ANACONDA_PRODUCTARCH, os.uname()[4])) config.set(Main, BugURL, os.environ.get(ANACONDA_BUGURL, your distribution provided bug reporting tool)) config.set(Main, IsFinal, os.environ.get(ANACONDA_ISFINAL, false)) config.set(Main, Product, os.environ.get(ANACONDA_PRODUCTNAME, anaconda)) config.set(Main, UUID, ) config.set(Main, Version, os.environ.get(ANACONDA_PRODUCTVERSION, bluesky)) # Now read in the .buildstamp file, wherever it may be. config.read([/.buildstamp, /tmp/product/.buildstamp, os.environ.get(PRODBUILDPATH, )]) # Set up some variables we import throughout, applying a couple transforms as necessary. bugUrl config.get(Main, BugURL) isFinal config.getboolean(Main, IsFinal) productArch config.get(Main, Arch) productName config.get(Main, Product) if productName.endswith( Alternate Architectures): productName productName[:-len( Alternate Architectures)] productStamp config.get(Main, UUID) productVersion config.get(Main, Version) if not productArch and productStamp.index(.) ! -1: productArch productStamp[productStamp.index(.)1:] if productVersion development: productVersion rawhide def distributionText(): return _(%(productName)s %(productVersion)s INSTALLATION) % \ {productName: productName, productVersion: productVersion} def translated_new_install_name(): return _(New %(name)s %(version)s Installation) % \ {name : productName, version : productVersion}修改后的自定义的 xxxxos.py 安装类配置方法 , 比如定义为 rtxos.py# # rhel.py # # Copyright (C) 2010 Red Hat, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # from pyanaconda.installclass import BaseInstallClass from pyanaconda.product import productName from pyanaconda import network from pyanaconda import nm from pyanaconda.kickstart import getAvailableDiskSpace from blivet.partspec import PartSpec from blivet.platform import platform from blivet.devicelibs import swap from blivet.size import Size class RHELBaseInstallClass(BaseInstallClass): name rtxOS Linux sortPriority 20002 if not productName.startswith(rtxOS): hidden True defaultFS xfs bootloaderTimeoutDefault 5 ignoredPackages [ntfsprogs, reiserfs-utils, hfsplus-tools] installUpdates False _l10n_domain comps efi_dir centos help_placeholder CentOSPlaceholder.html help_placeholder_with_links CentOSPlaceholderWithLinks.html def configure(self, anaconda): BaseInstallClass.configure(self, anaconda) self.setDefaultPartitioning(anaconda.storage) def setNetworkOnbootDefault(self, ksdata): if any(nd.onboot for nd in ksdata.network.network if nd.device): return # choose the device used during installation # (ie for majority of cases the one having the default route) dev network.default_route_device() \ or network.default_route_device(familyinet6) if not dev: return # ignore wireless (its ifcfgs would need to be handled differently) if nm.nm_device_type_is_wifi(dev): return network.update_onboot_value(dev, yes, ksdata) def __init__(self): BaseInstallClass.__init__(self) class RHELAtomicInstallClass(RHELBaseInstallClass): name rtxOS Atomic Host sortPriority21001 hidden not productName.startswith((rtxOS Atomic Host, rtxOS Linux Atomic)) def setDefaultPartitioning(self, storage): autorequests [PartSpec(mountpoint/, fstypestorage.defaultFSType, sizeSize(1GiB), maxSizeSize(3GiB), growTrue, lvTrue)] bootreqs platform.setDefaultPartitioning() if bootreqs: autorequests.extend(bootreqs) disk_space getAvailableDiskSpace(storage) swp swap.swapSuggestion(disk_spacedisk_space) autorequests.append(PartSpec(fstypeswap, sizeswp, growFalse, lvTrue, encryptedTrue)) for autoreq in autorequests: if autoreq.fstype is None: if autoreq.mountpoint /boot: autoreq.fstype storage.defaultBootFSType autoreq.size Size(300MiB) else: autoreq.fstype storage.defaultFSType storage.autoPartitionRequests autorequests注意:自定义的安装类的 sortPriority 的值需要大于 20000 才会优先加载并启动运行efi_dir 目录的名字不要修改成 productName 变量的值否则会出现 EFI 模式安装完成系统后安装 EFI 引导文件失败的问题原因是公版的 CentOS 发行版中grub2-efi-x64-2.02-0.81.el7.centos.x86_64.rpm 包中包含的引导项的默认 efi_dir 的值为 centos 所以如果这里改成厂商定义的其他值会导致 EFI 引导文件无法写入所以系统也就无法引导除非拿到 grub2-efi SRPM 源码进行修改再重新打包成二进制 RPM 包否则不推荐修改这里修改 anaconda 制作的配置模板修改 /usr/share/lorax/runtime-install.tmpl 增加部分需要的安装包filesystem tools 里面增加了 ntfs-3g ntfsprogs RPM 包用于支持 ntfs 格式文件系统的读写hardware utility 中增加了硬盘检测工具 ipmi 带内带外工具extra tools 中增加如下工具 vim less bc wget unzip iperf 等net/server tools 里面新增 修改 /usr/share/lorax/runtime-postinstall.tmpl 调整运行的时区为 UTC8 shanghai 时区安装增加下面的 OEM 定制化厂商信息 比如 rtx增加部分安装器 bash shell 使用的 环境变量配置模板增加自定义的服务. tmpl 配置文件中的语法说明大部分语法与构建 RPM 包的 SPEC 中的语法类似${xxxx} 中的变量使用预定义好的模板的参数赋值installclasses 路径 /usr/lib64/python2.7/site-packages/pyanaconda/installclasses/服务器上的路径 /usr/share/lorax/config_files/common/ 等于 runtime-postinstall.tmpl 文件中 ${configdir} 变量所指的路径anaconda GUI 背景图替换文件路径 /usr/share/anaconda/pixmaps/ 替换原有的 sidebar-bg.png sidebar-logo.png topbar-bg.png/usr/share/anaconda/pixmaps/rnotes/en 路径下centos-artwork.pngcentos-cloud.pngcentos-cloud.pngcentos-core.pngcentos-promotion.pngcentos-virtualization.png制作并输出新的 anaconda 安装器参数说明 最后的 /home/new_anaconda/ 代表制作新输出的 anaconda boot.iso 的根目录路径输出目录不能先存在否则会提示报错-p 代表 product name-r 代表 release version-v 代表 version identifier-s 代表 软件仓库的 URL 地址 可用网上的开源镜像站的源也可以换成自己搭建维护的 http 仓库源--isfinal 表示构建最终用于发布的 anaconda build 版本CMDlorax -p rtxOS -v 7 -r 9 -s http://192.168.2.24/ISO_TREE_REPO/CentOS-7-x86_64-Everything-2207-02/ $(pwd)/new_anaconda/ --isfinal替换打包 ISO 根目录中的同名同路径资源文件#!/bin/bash anaconda_path/mnt/workspace/new_anaconda target_path/mnt/workspace/RTX_ISO_ROOT /bin/cp -fa ${anaconda_path:?}/.discinfo ${target_path:?}/ /bin/cp -fa ${anaconda_path:?}/.treeinfo ${target_path:?}/ /bin/cp -fa ${anaconda_path:?}/isolinux/vmlinuz ${target_path:?}/isolinux/vmlinuz /bin/cp -fa ${anaconda_path:?}/isolinux/initrd.img ${target_path:?}/isolinux/initrd.img /bin/cp -fa ${anaconda_path:?}/images/pxeboot/vmlinuz ${target_path:?}/images/pxeboot/vmlinuz /bin/cp -fa ${anaconda_path:?}/images/pxeboot/initrd.img ${target_path:?}/images/pxeboot/initrd.img /bin/cp -Rfa ${anaconda_path:?}/LiveOS ${target_path:?}/最终打包输出 根据需求镜像需要支持存放大于4GB的单个文件所以参考 genisoimage 的 man 文件后外加参考红帽子提供的资料打包ISO的命令参数如下#!/bin/bash #CURRENT_PATH$(pwd) ISO_SOURCE/mnt/workspace/RTX_ISO_ROOT/ ISO_PATHisolinux ISO_FORMAT-no-emul-boot -boot-load-size 4 -boot-info-table echo para$1 if [ -z ${para} ];then read -p Please Make A Name For ISO : name else name${para} fi if [ -z $name ];then namebiubiubiu_rtx9090_os_custom_$(uname -m)_$(date %Y%m%d)_7.9 fi cd $ISO_SOURCE || exit 1 #### make iso genisoimage -U -r -v -T -J -udf -joliet-long -V rtxOS -volset rtxOS -A rtxOS \ -o /mnt/workspace/${name}.iso -c ${ISO_PATH}/boot.cat -b ${ISO_PATH}/isolinux.bin ${ISO_FORMAT} \ -eltorito-alt-boot -e images/efiboot.img -allow-limited-size -no-emul-boot ${ISO_SOURCE} #### insert md5 checksum implantisomd5 /mnt/workspace/${name}.iso #### make to hybrid boot isohybrid -v /mnt/workspace/${name}.iso [ $? 0 ] echo -e \n ${name}.iso generate complete !! \n参数 -U -r -v -T -J -udf -joliet-long 含义为不翻译文件名生成 RockRidge 目录信息可视化的给系统无法理解的长文件名生成转换表信息生成 Joliet 目录信息使用UDF格式支持大于4GB的文件允许 Joliet 文件名的达到 103 个 unicode 字符。参数 -V rtxOS -volset rtxOS -A rtxOS 表示生成 ISO 的卷名称标签label为 ‘rtxOS’参数 -o /mnt/workspace/${name}.iso 表示输出 ISO 文件到 /mnt/workspace/ 下参数 -c isolinux/boot.cat -b isolinux/isolinux.bin 表示使用ISO打包目录中 isolinux目录下的 boot.cat 与 isolinux.bin 两个固件引导 BIOS 模式参数 -eltorito-alt-boot -e images/efiboot.img 表示使用ISO 打包目录中的 image/efiboot.img 引导EFI 模式参数 -allow-limited-size -no-emul-boot 表示允许限制尺寸非模拟启动参数 $ISO_SOURCE 代表制作 ISO 的打包根目录路径ISO 安装测试BIOS 模式UEFI 模式