一. 制作环境的准备

1. 安装制作发行版的工具:
[shell]# yum -y install anaconda repodata createrepo mkisofs
[shell]# yum -y install anaconda-runtime createrepo yum-utils anacondaanaconda-help busybox-anaconda mkisofs

2. 安装Centos6.0系统
由于方便制作,我们可以在VMware、vbox、xen等虚拟环境中进行安装,这里我们选用了VMware作为制作环境。
(1) 在官方网站上下载CentOS-6.0-x86_64-bin-DVD.iso镜像文件
Wget http://mirrors.loosefoot.com/centos/6.0/isos/x86_64/CentOS-6.0-x86_64-bin-DVD1.iso
Wget http://mirrors.loosefoot.com/centos/6.0/isos/x86_64/CentOS-6.0-x86_64-bin-DVD2.iso

(2) 创建VM虚拟机
CPU:2 core / MEM:4G / HD:20G
由于在制作过程中需要拷贝大量数据,所以硬盘尽量保持20G以上。

(3) 生成packages.list软件清单
(由于install.log文件在root目录,所以该操作在root目录进行)
[英文版centos执行此命令]
[shell]# cat install.log | grep Installing | sed ‘s/Installing //g’ < /root/packages.list
[中文版centos执行此命令]
[shell]# cat install.log | grep 安装 | sed ‘s/安装 //g’ < /root/packages.list
生成后,需要仔细看该文件,一般会在某些文件开始部分如“1:”这样的字符,需要删除这些字符,否在后面执行copy动作会报错。

二. 创建定制系统(My4399OS)目录
1. 光盘结构及文件简介
*isolinux 目录存放光盘启动时的安装界面信息
*images 目录包括了必要的启动映像文件
*Packages 目录存放安装软件包及信息
*.discinfo 文件是安装价质的识别信息
*lnmp 目录存放定制系统配置文件及LNMP安装脚本

2. 创建设/disk目录,挂载光盘
[shell]# mkdir /disk
[shell]# mkdir /mnt/cdrom
[shell]# mount –o loop /dev/cdrom /mnt/cdrom

3. 拷贝光盘目录
[shell]# cd /mnt/cdrom
[shell]# ls -a .|grep –v “Packages”|xargs -i cp -rp {} /disk
//将所有文件和文件夹拷贝到/disk,除了Packages目录
[shell]# mkdir /disk/Packages

4. 拷贝packages.list软件清单
编写复习脚本copyrpms.sh,脚本的功能是为了从packages.list获取软件清单,然后将其逐一地拷贝到/disk/Packages目录下。

  1. #!/bin/bash
  2. ############################################################
  3. # 生成RPM包packages.list列表、拷贝packages.list中RPM包列表
  4. ############################################################
  5. prog=copyrpm.sh
  6. ###拷贝光盘内容到/disk,排除Packages目录
  7. #cd /mnt/cdrom
  8. #ls -a|grep -v “Packages”|xargs -i cp -rp {} /disk/
  9. ###生成RPM包packages.list列表
  10. build_packages_list(){
  11. poin_file=$2
  12. cat /root/install.log | grep Installing | sed ‘s/Installing //g’ < $poin_file
  13. }
  14. ###拷贝packages.list中RPM包列表到指定位置
  15. copy_packages_list(){
  16. DEBUG=0
  17. DVD_CD=$3#/disk/Packages
  18. ALL_RPMS_DIR=$2#/mnt/cdrom/Packages/
  19. DVD_RPMS_DIR=$DVD_CD
  20. packages_list=$4#/root/packages.list
  21. number_of_packages=`cat $packages_list | wc -l`
  22. i=1
  23. while [ $i -le $number_of_packages ] ; do
  24. line=`head -n $i $packages_list | tail -n -1`
  25. name=`echo $line | awk ‘{print $1}’`
  26. version=`echo $line | awk ‘{print $3}’ | cut -f 2 -d :`
  27. if [ $DEBUG -eq “1” ] ; then
  28. echo $i: $line
  29. echo $name
  30. echo $version
  31. fi
  32. if [ $DEBUG -eq “1” ] ; then
  33. ls $ALL_RPMS_DIR/$name-$version*
  34. if [ $? -ne 0 ] ; then
  35. echo “cp $ALL_RPMS_DIR/$name$version* “
  36. fi
  37. else
  38. echo “cp $ALL_RPMS_DIR/$name-$version* $DVD_RPMS_DIR/”
  39. cp $ALL_RPMS_DIR/$name$version* $DVD_RPMS_DIR/
  40. # in case the copy failed
  41. if [ $? -ne 0 ] ; then
  42. echo “cp $ALL_RPMS_DIR/$name$version* “
  43. cp $ALL_RPMS_DIR/$name* $DVD_RPMS_DIR/
  44. fi
  45. fi
  46. i=`expr $i + 1`
  47. done
  48. }
  49. ###模糊查找rpm包,并拷贝指定文件夹
  50. find_packages_list() {
  51. root_dir=$2#源目录
  52. decs_dir=$3#目标目录
  53. load_file=$4#检查列表
  54. xorg_dim=$5#通配规则
  55. for i in `cat $load_file|sort|uniq -c|awk ‘{print$2}’`
  56. do
  57. if [ $decs_dir = “–test” ];then
  58. case “$xorg_dim”in
  59. –fr)
  60. echo “=====================$i(fr)========================”
  61. echo `/bin/find $root_dir -name “*$i”`
  62. echo “===============================================”
  63. ;;
  64. –br)
  65. echo “=====================$i(br)========================”
  66. echo `/bin/find $root_dir -name “$i*”`
  67. echo “===============================================”
  68. ;;
  69. –all)
  70. echo “=====================$i(all)========================”
  71. echo `/bin/find $root_dir -name “*$i*”`
  72. echo “===============================================”
  73. ;;
  74. *)
  75. echo “=====================$i(default)===============”
  76. echo `/bin/find $root_dir -name “*$i*”`
  77. echo “===============================================”
  78. ;;
  79. esac
  80. elif [ -d $decs_dir ];then
  81. case “$decs_dir”in
  82. –fr)
  83. find $root_dir -name “*$i” -type f -exec cp -rf {} $decs_dir ;
  84. echo $i
  85. ;;
  86. –br)
  87. find $root_dir -name “$i*” -type f -exec cp -rf {} $decs_dir ;
  88. echo $i
  89. ;;
  90. –all)
  91. find $root_dir -name “*$i*” -type f -exec cp -rf {} $decs_dir ;
  92. echo $i
  93. ;;
  94. *)
  95. find $root_dir -name “*$i*” -type f -exec cp -rf {} $decs_dir ;
  96. echo $i
  97. ;;
  98. esac
  99. else
  100. echo “Usage: {–test|destination_dir}”
  101. exit 1
  102. fi
  103. done
  104. }
  105. case “$1″in
  106. -b)
  107. if [ $2 ];then
  108. build_packages_list -b $2
  109. else
  110. echo “Nothing input!!! “
  111. fi
  112. ;;
  113. -c)
  114. if [ $2 -a $3 -a $4 ];then
  115. copy_packages_list -c $2 $3 $4
  116. else
  117. echo “Nothing input!!! “
  118. fi
  119. ;;
  120. -f)
  121. if [ $2 -a $3 -a $4 -a $4 -a $5 ];then
  122. find_packages_list -f $2 $3 $4 $5
  123. else
  124. echo “Nothing input!!! “
  125. fi
  126. ;;
  127. –h|–help)
  128. echo “===============================================================”
  129. echo “这个脚本主要用在定制linux_base系时,将install.log文件中安装的rpm包”
  130. echo “导到一个文件列表中;然后再将该导出的文件中的rpm包列表全部拷贝到将要”
  131. echo “定制的base版系统的Packages文件夹中.这些rpm包为裁剪原版系统后所得的”
  132. echo “基本包.”
  133. echo “使用方法:”
  134. echo ” 1、生成RPM列表:$prog -b {export_file}”
  135. echo ” 例子:$prog -b /root/soft.list”
  136. echo ” 2、拷贝RPM包:$prog -c {source_dir} {destination_dir} {inport_file}”
  137. echo ” 例子:$prog -c /mnt/cdrom/ /disk/ /root/soft.list”
  138. echo ” 3、查找并拷贝rpm包:”
  139. echo ” $prog -f {source_dir} {destination_dir} {inport_file} {fr,br,all}”
  140. echo ” $prog -f /mnt/cdrom/ /disk/ /root/soft.list –all”
  141. echo ” 4、只测试不拷贝文件:”
  142. echo ” $prog -f {source_dir} –test {inport_file} {fr,br,all}”
  143. echo ” $prog -f /mnt/cdrom/ –test /root/soft.list –all”
  144. echo ” ==============================================================”
  145. ;;
  146. *)
  147. echo $”Usage: $prog {-b|-c|–h|–help}”
  148. exit 1
  149. esac

 

[shell]# ./copyrpms.sh -c /mnt/cdrom/Packages /disk/Packages /root/packages.list
//从光盘中拷贝packages.list里的软件清单到/disk/Packages目录里

这里已经拷贝了定制centos系统最基本的rpm包,但实际上我们的应用环境还需用到更多的rpm包。这种情况我们应该做的是先找出我们还需要的软件包,如:gcc、gd、vnstat等,然后一个一个手动将它们拷贝到/disk/Packages目录里。但这里要注意的是,这些包中很可能存在依赖关系,如果你没有把它们相依赖的rpm包同时拷贝到/disk/Packages目录里,那在安装过程中将会提示找不到所需依赖包。
我们可以使用yum install命令找出它们的依赖包,然后将其依赖包记录到一个文本文件中,如add_soft.txt,再使刚才的脚本;
[shell]# ./copyrpms.sh -f /mnt/cdrom/Packages –test /root/soft.txt –all
//这条命令是在光盘中找出soft.txt中对应的软件清单,只显示不拷贝,–all为匹配规则,fr,br分别表示为“*str”、“str*”,all为“*str*”。
[shell]# ./copyrpms.sh -f /mnt/cdrom/Packages /disk/Packages /root/soft.txt –all
//在光盘中找出soft.txt中对应的软件清单,直接拷贝到/disk/Packages

经过一系列的复制就完成了你要定制的RPM包(在/Disk/Packages/目录下)。

5. 定制安装控制文件ks.cfg
ks文件主要分为三个部分:
a) 系统安装及配置
b) 自定义安装准备(%post –nochroot)
c) 用户自定义安装(%post)
系统安装及配置一般写在ks.cfg文件最前面,系统安装设置以%post –nochroot为结束标志,接着是用户自定义安装准备部分,以“%post –nochroot”作为开始,以“%post”作为结束,自定义安装部分以“%post”作为开始。一般方便可以直接由root下面的anaconda-ks.cfg修改。
[shell]# cp /root/anaconda-ks.cfg /disk/isolinux

ks.cfg基本的书写样式:

  1. # Kickstart file automatically generated by anaconda.
  2. install //指定开始全新安装系统
  3. cdrom //光驱方式
  4. text //文本界面安装
  5. lang en_US.UTF-8 //系统语言设定
  6. keyboard us //键盘设置
  7. skipx //跳过X桌面
  8. network –device eth0 –bootproto dhcp //设置系统的IP地址信息
  9. rootpw –iscrypted $1$sXpmDpgD$IOEYOpdpXtxXgw7RmjtZS/ //经过加密的root密码
  10. firewall –enabled //关闭防火墙
  11. authconfig –enableshadow –enablemd5 //系统验证方式,这里启用默认md5加密
  12. selinux –disabled //关闭Selinux
  13. timezone Asia/Shanghai //系统时区设置
  14. bootloader –location=mbr //引导选项
  15. clearpart –all –initlabel //全部格式化系统磁盘所有分区,下面开始进行分区设置
  16. part / –bytes-per-inode=4096 –fstype=”ext4″ –size=1000 –grow
  17. part /boot –bytes-per-inode=4096 –fstype=”ext4″ –size=100
  18. part swap –bytes-per-inode=4096 –fstype=”swap” –size=12000
  19. reboot //这个reboot必须写在系统分区之后
  20. %packages //系统需要安装的软件包
  21. @chinese-support
  22. @core
  23. rsyslog
  24. patch
  25. gcc
  26. gcc-c++
  27. libXft
  28. make
  29. autoconf
  30. automake
  31. ntp
  32. sysstat
  33. rsync
  34. dstat
  35. ncurses
  36. ncurses-devel
  37. net-snmp
  38. net-snmp-libs

除了cdrom安装方式外,还可以使用网络或硬盘安装方式;其示例如下:
url –url http://192.168.2.62/centos6
nfs –server=192.168.2.62 –dir=/centos6
harddrive –partition=sda1 –dir=/centos6 //sda1是像文件所在的硬盘标识
以上ks.cfg示例属于系统安装及配置部份,另外的%post和%post –nochroot作用是当系统初始化安装完毕后需要执行的工作。例如:
%post –nochroot
# Mount CDROM
mkdir -p /mnt/cdrom
mount -r -t iso9660 /tmp/cdrom /mnt/cdrom
cp /mnt/cdrom/lnmp.tar.gz /mnt/sysimage/tmp/lnmp.tar.gz< /dev/null
cd /mnt/sysimage/tmp/
tar -zxvf lnmp.tar.gz < /dev/null
cp -R /mnt/sysimage/tmp/boot/* /mnt/sysimage/boot/ </dev/null 2</dev/null
cp -R /mnt/sysimage/tmp/etc/* /mnt/sysimage/etc/ </dev/null 2</dev/null
# Unmount CDROM
umount /mnt/cdrom
%post –nochroot 表示允许你指定你想在chroot环境之外运行的命令,由Linux系统安装进程在系统安装完成后,会卸载光盘,因此,象复制安装介质中的文件或RPM之类的任务将不能被执行。此时就需要用“%post –nochroot”选项。
[备注:经过测试在centos6.x系统无法在%post –nochroot环境下挂载光盘,所以这里只适合在centos5.x系列。其centos6.x的挂载方式在下面的%post中说明。]
%post 表示系统安装完成后,要运行的脚本,相当于在root环境下进行的操作,与在真实linux系统下进行操作完全一致。此时光盘已经被系统安装程序自动卸载。一般这里做一些系统的优化调整。
%post
chkconfig sendmail off
chkconfig –level 3 iptables on
chkconfig –level 2345 nfslock off
chkconfig –level 2345 portmap off
chkconfig –level 2345 crond on
[备注:由于centos6.x系统无法在–nochroot环境下挂载,只能在%post下挂载,挂载方式跟在真实linux环境下一致,命令和挂载路径也一致。]
Tips:手册后面附件为:本My4399_6.0系统的配置文件ks.cfg,重命为my4399.cfg。

6. 修改isolinux.cfg文件
将/Disk/isolinu/目录下的isolinux.cfg修改如下:
default auto
label auto
kernel vmlinuz
append ks=cdrom:/isolinux/ks.cfg initrd=initrd.img
append指定ks文件的读取路径,如果ks.cfg更名为其他名称,即在此修改。
append ks=cdrom:/isolinux/my4399.cfg

7. 修改安装界面文本标题
这里我们可以去掉安装过程中的CentOS字样,在安装光盘里面有两个.buildstamp文件,一个位于stage2.img中,一个位于initrd.img中,安装光盘运行时读取的是initrd.img中的那个.buildstamp文件,所以只要把initrd.img文件改了就可以了。
(1) 解压initr.dimg文件
2.6内核中的initrd.img采用cpio压缩,不再是2.4内核使用的ext2格式,无法使用mount-o loop 挂载。需要使用gunzip解压缩,然后再利用cpio给img解包。
# cd /disk/isolinux/
# cp initrd.img /tmp/initrd.img.gz
# cd /tmp
# gunzip initrd.img.gz
# mkdir initrd
# mv initrd.img initrd
# cd initrd
# cpio -ivmd < initrd imgbr style=’font-size:12px;font-style:normal;font-weight:normal;color:rgb(102, 102, 102);’ />然后修改.buildstamp文件,将CentOS改为LTOS即可.

(2) 制作initrd.img文件
假设当前目录位于准备好的initrd文件系统的根目录下;
# find . | cpio -c -o <../initrd.img
# cp initrd.img /disk/isolinux/
Tips1:安装界面文本修改后如《图例一》所示,“Welcome to My4399 os for x86_64”。

8. 生成comps.xml
comps.xml文件中包含了安装时用户所见到的与rpm相关的所有内容,它会检查Packages下的RPM包的依赖关系,安装时如果缺少依赖包,它会提示您哪个RPM包需要哪些依赖库。同时它的角色就是相当于图形安装时选择软件包那个环节。主要由三部分组成,首先是组列表,它描述了在安装过程中需要的不同的组(或组件),包括组名、组的描述和包含的RPM包;其次是组的层次结构,它将组分成不同的类,并定义了组的一个顺序,从而可以决定哪些组需要先安装;最后为一系列RPM包以及它们之间的依赖关系。
下面先进入/disk/repodata 目录,将“*-x86_64-comps.xml”文件改为“comps.xml”,并且将其他文件删除。由于centos6.0下的comps.xml文件名很长,这里“*”为省略符,实际操作时输入完整文件名。
[shell]# cd /disk/ repodata
[shell]# mv *-comps.xml comps.xml
[shell]# ls .|grep -v “comps.xml”|xargs -i rm -f {}
然后返回到/disk根目录,就可以重新开始生成comps.xml文件了。
[shell]# cd /disk/
[shell]# createrepo -g repodata/comps.xml ./
[shell]# declare -x discinfo=`head -1 .discinfo`
[shell]# createrepo -u “media://$discinfo” -g repodata/comps.xml /disk/
到这里,comps.xml文件和其他相关联的文件已被重新生成到repodata目录下。
Tips2:如果你新增或删除了Packages目录的RPM包,请重新生成comps.xml文件。

三. 制作ISO文件
到了这一步,实际定制配置系统的工作已经完成了。下面就是生成一个ISO镜像文件,便于刻录到光盘中进行安装。
[shell]# cd /disk/
[shell]# mkisofs -o My4399.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -R -J -v -T /disk/
/disk/ 目录下产生的My4399.iso是生成的ISO文件。我们可以测试这个iso的正确性,通过VM的iso镜像安装即可测试定制系统的正确性,如果没问题就可以进行光盘刻录。