无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 3535|回复: 2
打印 上一主题 下一主题

[分享] 把DI当online packer用:利用installnet制作一个云装机packerpe(1)

[复制链接]
跳转到指定楼层
1#
发表于 2020-5-20 23:57:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 minlearn 于 2020-5-24 04:13 编辑



本文关键字:pebuilder,云主机装机就用云镜像装机。直接在网络上组装生成目标系统,模拟群晖的webassit,wget --spider to stdout not work

前面《利用hashicorp packer把dbcolinux导出为虚拟机和docker格式》系列中我们讲到了packer,这是一个类虚拟机管理器的工具,它有一个iso模式,允许用户提供一个最原始的iso和一系列脚本。,然后在这个系统上运行脚本内命令行,完成格式硬盘,安装软件包,动态生成目标系统镜像内容。关机即得这个镜像。packer也常被用来在本地生成虚拟机镜像,然后上传导入到云主机供云主机用,然而,这有一个缺点,生成镜像通常很大,本地网络拉取一些特定区的镜像速度也不太好,最后,还得上传,那么,有没有一种在云主机上类packer,边拉取软件边生成目标镜像的工具呢?如果有,是否适用所有系统呢,比如windows不提供linux方式的kernel与rootfs分离,也不支持软件包仓库丰富系统,是不是也同样适用这个过程呢?

Ps:debianinstaller,是一种debian netboot system组成的类packer的环境,当可引导安装介质(安装光盘,安装U盘)启动后,可以选择进入文本向导模式或图形向导模式,然后完成如下操作  加载 kernel,initrd,加载额外的Udeb包,完成安装界面初始化环境; 如果启动参数包含preseed文件,则会按照preseed文件内定义的规则自动执行,如果没有对应的规则,则返回交互界面; 交互界面会引导用户完成键盘,时区,主机名,网络,用户密码,分区等设置,存储在当前安全器环境中; 完成分区格式化等操作后,该磁盘会被挂载到 /target,安装器会调用debootstrap在 /target 完成核心系统的构建; 安装器通过执行 chroot 操作进入以 /target 为根的系统中,完成软件源的更新,执行 tasksel,弹出可选软件菜单; 安装可选的软件包, 完成上述操作后,最后配置 grub, 将之前保存的全部设置应用,完成安装过程.  


可见,整个debian installer 类似packer,只不过这里bootstrap系统是debian(packer iso模式下的iso)。工具是Debian-installer等,脚本是preseed,provision过程是运行这个pe回放preseed。当被用于云主机时,使用debian installerb也可在其中完成识别硬盘格式化等操作,,实际上它开始是一个按preseed自动化的livecd,先启动进livecd,还原回放preseed时,可以在这里继续安装完整系统(preseed)完成即得到目标镜像,debian-installer不光用来生成debian派生系的镜像,对于windows,osx这种没有在线组装能力的系统而言,可直接在preseed早期就通过wget,tar,dd的管理道dd镜像完成安装目标系统 ——— 格盘,装系统,这其实是一种比服务商提代的镜像恢复方式和dd方式更符合云机装机的原生方式。《云主机上装windows iso》《virtio 0pe》这是我早期使用virtiope网络装机的文章,我们讲到过pebuilder,我们还谈到过群晖的webassit都是类比物,在后面一些文章,尤其是《云主机上装黑群,黑果》系列中我们都提到过moeclue的installnet.sh脚本,用它网络装机可在线完成。就相当pebuilder ,生成的pe相当packer ,

下面来完善这个脚本

注意!!!!!!!!:使用此脚本安装镜像默认会抹除你硬盘中的所有内容。请谨慎尝试。
注意!!!!!!!!:使用此脚本安装镜像默认会抹除你硬盘中的所有内容。请谨慎尝试。
注意!!!!!!!!:使用此脚本安装镜像默认会抹除你硬盘中的所有内容。请谨慎尝试。

前置


主要是把selectmirror精简为dd only,把一些全局变量置为局部过程变量,不用作为参数喂给脚本。


  1. #!/bin/bash

  2. ## License: GPL,Written By MoeClub.org,moded by minlearn for dd purpose only

  3. export tmpDDURL=''
  4. export tmpMIRROR=''
  5. export tmpINSTANTWITHOUTVNC='0'

  6. export ipAddr=''
  7. export ipMask=''
  8. export ipGate=''

  9. export UNKNOWHW='0'
  10. export UNVER='6.4'

  11. while [[ $# -ge 1 ]]; do
  12.   case $1 in
  13.     -dd|--ddurl)
  14.       shift
  15.       tmpDDURL="$1"
  16.       shift
  17.       ;;
  18.     --mirror)
  19.       shift
  20.       tmpMIRROR="$1"
  21.       shift
  22.       ;;
  23.     -i|--instantwithoutvnc)
  24.       shift
  25.       tmpINSTANTWITHOUTVNC="$1"
  26.       shift
  27.       ;;
  28.     --ip-addr)
  29.       shift
  30.       ipAddr="$1"
  31.       shift
  32.       ;;
  33.     --ip-mask)
  34.       shift
  35.       ipMask="$1"
  36.       shift
  37.       ;;
  38.     --ip-gate)
  39.       shift
  40.       ipGate="$1"
  41.       shift
  42.       ;;
  43.     *)
  44.       if [[ "$1" != 'error' ]]; then echo -ne "\nInvaild option: '$1'\n\n"; fi
  45.       echo -ne " Usage(args are self explained):\n\tbash $(basename $0)\t-dd/--ddurl\n\t\t\t\t--mirror\n\t\t\t\t-i/--instantwithoutvnc\n\t\t\t\t--ip-addr/--ip-gate/--ip-mask\n\t\t\t\t\n"
  46.       exit 1;
  47.       ;;
  48.     esac
  49.   done

  50. [[ "$EUID" -ne '0' ]] && echo "Error:This script must be run as root!" && exit 1;

  51. function CheckDependence(){
  52.   FullDependence='0';
  53.   for BIN_DEP in `echo "$1" |sed 's/,/\n/g'`
  54.     do
  55.       if [[ -n "$BIN_DEP" ]]; then
  56.         Founded='0';
  57.         for BIN_PATH in `echo "$PATH" |sed 's/:/\n/g'`
  58.           do
  59.             ls $BIN_PATH/$BIN_DEP >/dev/null 2>&1;
  60.             if [ $? == '0' ]; then
  61.               Founded='1';
  62.               break;
  63.             fi
  64.           done
  65.         if [ "$Founded" == '1' ]; then
  66.           echo -en "$BIN_DEP";
  67.         else
  68.           FullDependence='1';
  69.           echo -en "[\033[31mNot Install\033[0m]";
  70.         fi
  71.         echo -en "\t\t\t[\033[32mok\033[0m]\n";
  72.       fi
  73.   done
  74.   if [ "$FullDependence" == '1' ]; then
  75.     echo -ne "\n\033[31mError! \033[0mPlease use '\033[33mapt-get\033[0m' or '\033[33myum\033[0m' install it.\n\n\n"
  76.     exit 1;
  77.   fi
  78. }

  79. clear && echo -e "\n\n\n\n\n\n\n\n\n\n\033[36m# Check Dependence\033[0m\n"

  80. CheckDependence wget,ar,awk,grep,sed,cut,cat,cpio,curl,gzip,find,dirname,basename;

  81. function SelectMirror(){

  82.   [ $# -ge 1 ] || exit 1
  83.   AddonMirror=$(echo "$1" |sed 's/\ //g')

  84.   declare -A MirrorBackup
  85.   MirrorBackup=(["Debian0"]="" ["Debian1"]="http://httpredir.debian.org/debian")
  86.   echo "$AddonMirror" |grep -q '^http://\|^https://\|^ftp://' && MirrorBackup[{"Debian"}0]="$AddonMirror"

  87.   for mirror in $(echo "${!MirrorBackup[@]}" |sed 's/\ /\n/g' |sort -n |grep "^Debian")
  88.     do
  89.       CurMirror="${MirrorBackup[$mirror]}"
  90.       [ -n "$CurMirror" ] || continue

  91.       CheckPass1='0';
  92.       DistsList="$(wget --no-check-certificate -qO- "$CurMirror/dists/" |grep -o 'href=.*/"' |cut -d'"' -f2 |sed '/-\|old\|Debian\|experimental\|stable\|test\|sid\|devel/d' |grep '^[^/]' |sed -n '1h;1!H;$g;s/\n//g;s/\//\;/g;$p')";
  93.       for DIST in `echo "$DistsList" |sed 's/;/\n/g'`
  94.         do
  95.           [[ "$DIST" == "jessie" ]] && CheckPass1='1' && break;
  96.         done
  97.       [[ "$CheckPass1" == '0' ]] && {
  98.         echo -ne '\njessie not find in $CurMirror/dists/, Please check it! \n\n'
  99.         bash $0 error;
  100.         exit 1;
  101.       }

  102.       CheckPass2=0
  103.       ImageFile="SUB_MIRROR/dists/jessie/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz"
  104.       [ -n "$ImageFile" ] || exit 1
  105.       URL=`echo "$ImageFile" |sed "s#SUB_MIRROR#${CurMirror}#g"`
  106.       wget --no-check-certificate --spider --timeout=3 -o /dev/null "$URL"
  107.       [ $? -eq 0 ] && CheckPass2=1 && echo "$CurMirror" && break
  108.     done

  109.     [[ $CheckPass2 == 0 ]] && {
  110.       echo -ne "\033[31mError! \033[0minitrd.gz not find in $CurMirror/jessie/main/installer-amd64/current/images/netboot/debian-installer/amd64/! \n";
  111.       bash $0 error;
  112.       exit 1;
  113.     }
  114. }

  115. sleep 5s

  116. echo -e "\n\n\033[36m# Select Mirror\033[0m\n"
  117. LinuxMirror=$(SelectMirror "$tmpMIRROR")
  118. echo -e "${LinuxMirror}"
复制代码


缓存udebs和kernel,rootfs:

把udebs仓库也缓存下来放进pe,做成本地镜像。因为rootfs中有一个httpd,可以通过preseed启动,做成仓库镜像服务器。可以看到preseed中地址用了127.0.0.1,验证也去掉了By default the installer requires that repositories be authenticated using a known gpg key. This setting can be used to disable that authentication,a udeb就是一个方便在liveos中运行的简化的deb。

  1. sleep 5s

  2. echo -e "\n\033[36m# All prerequisites Done,Begin processing [DD URL:$tmpDDURL,Instant without vnc:$tmpINSTANTWITHOUTVNC]\033[0m\n"

  3. [[ -d /tmp/boot ]] && rm -rf /tmp/boot;
  4. mkdir -p /tmp/boot/usr/bin;
  5. cd /tmp/boot;

  6. LIBC6_SUPPORT='pool/main/g/glibc/libc6_2.19-18+deb8u10_amd64.deb'
  7. WGETSSL_SUPPORT=''
  8. declare -A HTTPD_SUPPORT
  9. HTTPD_SUPPORT=(
  10. ["webfs1"]="pool/main/w/webfs/webfs_1.21+ds1-10_amd64.deb"
  11. ["webfs2"]="pool/main/g/gnutls28/libgnutls-deb0-28_3.3.8-6+deb8u7_amd64.deb"
  12. ["webfs3"]="pool/main/p/p11-kit/libp11-kit0_0.20.7-1_amd64.deb"
  13. ["webfs4"]="pool/main/libt/libtasn1-6/libtasn1-6_4.2-3+deb8u3_amd64.deb"
  14. ["webfs5"]="pool/main/n/nettle/libnettle4_2.7.1-5+deb8u2_amd64.deb"
  15. ["webfs6"]="pool/main/n/nettle/libhogweed2_2.7.1-5+deb8u2_amd64.deb"
  16. ["webfs7"]="pool/main/g/gmp/libgmp10_6.0.0+dfsg-6_amd64.deb"
  17. ["webfs8"]="pool/main/libf/libffi/libffi6_3.1-2+deb8u1_amd64.deb"
  18. ["webfs9"]="pool/main/m/mime-support/mime-support_3.58_all.deb"
  19. )
  20. DDPROGRESS_SUPPORT=''
  21. UNZIP=''

  22. [[ -n "$LIBC6_SUPPORT" ]] && {
  23.   echo -ne 'Add libc6 support(binary-amd64/Package)...'

  24.   wget --no-check-certificate -qO ${LIBC6_SUPPORT##*/} $LinuxMirror/$LIBC6_SUPPORT; \
  25.   ar x ${LIBC6_SUPPORT##*/} data.tar.gz; tar xzf data.tar.gz; \
  26.   rm -rf data.tar.gz ${LIBC6_SUPPORT##*/}

  27.   [[ ! -f  /tmp/boot/lib/x86_64-linux-gnu/libc.so.6 ]] && echo 'Error! LIBC6_SUPPORT.' && exit 1 || sleep 3s && echo -en "[\033[32mok\033[0m]\n" ;
  28.   # [[ $? -eq '0' ]] && echo -ne 'Success! \n\n'
  29. }


  30. if [[ -n "$tmpDDURL" ]]; then
  31.   echo "$tmpDDURL" |grep -q '^http://\|^ftp://\|^https://';
  32.   [[ $? -ne '0' ]] && echo 'No valid URL in the DD argument,Only support http://, ftp:// and https:// !' && exit 1;
  33.   curl -Is "$tmpDDURL" | grep -q 'gzip';
  34.   [[ $? -ne '0' ]] && echo 'not tar or gunzip file !' && exit 1 || UNZIP='0';
  35. else
  36.   echo 'Please input vaild image URL! ';
  37.   exit 1;
  38. fi

  39. echo "$tmpDDURL" |grep -q '^https://'
  40. [[ $? -eq '0' ]] && {

  41.   [[ -n "$WGETSSL_SUPPORT" ]] && {
  42.     echo -ne 'Add ssl support(binary-amd64/Package)...'

  43.     wget --no-check-certificate -qO- $LinuxMirror/$WGETSSL_SUPPORT |tar -x
  44.     mv -f /tmp/boot/usr/bin/wget /tmp/boot/usr/bin/

  45.     [[ ! -f  /tmp/boot/usr/bin/wget2 ]] && echo 'Error! WGETSSL_SUPPORT.' && exit 1 || sleep 3s && echo -en "[\033[32mok\033[0m]\n" ;
  46.     # sed -i 's/wget\ -qO-/\/usr\/bin\/wget2\ --no-check-certificate\ --retry-connrefused\ --tries=7\ --continue\ -qO-/g' /tmp/boot/preseed.cfg
  47.     # [[ $? -eq '0' ]] && echo -ne 'Success! \n\n'
  48.   }
  49.     # || {
  50.     # echo -ne 'Not ssl support package! \n\n';
  51.     # exit 1;
  52.     # }
  53. }

  54. #[[ -n "$HTTPD_SUPPORT" ]] && {
  55.   echo -ne 'Add httpd support(webfs binary-amd64 Package)...'

  56.   for pkg in $(echo "${!HTTPD_SUPPORT[@]}" |sed 's/\ /\n/g' |sort -n |grep "^webfs")
  57.     do
  58.       CurPkg="${HTTPD_SUPPORT[$pkg]}"
  59.       [ -n "$CurPkg" ] || continue

  60.       wget --no-check-certificate -qO ${CurPkg##*/} $LinuxMirror/$CurPkg; \
  61.       ar x ${CurPkg##*/} data.tar.xz; xz -d data.tar.xz; tar xf data.tar; \
  62.       rm -rf data.tar ${CurPkg##*/}
  63.     done

  64.     [[ ! -f  /tmp/boot/usr/bin/webfsd ]] && echo 'Error! HTTPD_SUPPORT.' && exit 1 || sleep 3s && echo -en "[\033[32mok\033[0m]\n" ;
  65.     # [[ $? -eq '0' ]] && echo -ne 'Success! \n\n'
  66. #}


  67. echo -e "Downloading kernel : ${LinuxMirror}/....../debian-installer/amd64/initrd.gz"

  68. IncFirmware='0'

  69. wget --no-check-certificate -qO '/boot/initrd.img' "${LinuxMirror}/dists/jessie/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz"
  70. [[ $? -ne '0' ]] && echo -ne "\033[31mError! \033[0mDownload 'initrd.img' for \033[33mdebian\033[0m failed! \n" && exit 1
  71. wget --no-check-certificate -qO '/boot/vmlinuz' "${LinuxMirror}/dists/jessie/main/installer-amd64/current/images/netboot/debian-installer/amd64/linux"
  72. [[ $? -ne '0' ]] && echo -ne "\033[31mError! \033[0mDownload 'vmlinuz' for \033[33mdebian\033[0m failed! \n" && exit 1
  73. MirrorHost="$(echo "$LinuxMirror" |awk -F'://|/' '{print $2}')";
  74. MirrorFolder="$(echo "$LinuxMirror" |awk -F''${MirrorHost}'' '{print $2}')";

  75. if [[ "$IncFirmware" == '1' ]]; then
  76.   wget --no-check-certificate -qO '/boot/firmware.cpio.gz' "http://cdimage.debian.org/cdimage/unofficial/non-free/firmware/jessie/current/firmware.cpio.gz"
  77.   [[ $? -ne '0' ]] && echo -ne "\033[31mError! \033[0mDownload 'firmware' for \033[33mdebian\033[0m failed! \n" && exit 1
  78. fi

  79. vKernel_udeb=$(wget --no-check-certificate -qO- "http://jessieMirror/dists/$DIST/main/installer-amd64/current/images/udeb.list" |grep '^acpi-modules' |head -n1 |grep -o '[0-9]\{1,2\}.[0-9]\{1,2\}.[0-9]\{1,2\}-[0-9]\{1,2\}' |head -n1)
  80. [[ -z "vKernel_udeb" ]] && vKernel_udeb="3.16.0-6"

  81. echo -e "Downloading debs : ${LinuxMirror}/pool/....."

  82. IncUdebrepo='1'

  83. if [[ "$IncUdebrepo" == '1' ]]; then

  84.   mkdir -p /tmp/boot/var/log/debian;

  85.   udeburl=".*pool\/main\(.*\)udeb.*"
  86.   wget --no-check-certificate -qO- "$LinuxMirror/dists/jessie/main/debian-installer/binary-amd64/Packages.gz" |gunzip -dc|sed "/$udeburl/!d"|sed "s/Filename: //g"|while read line
  87.   do
  88.     path=${line%/*}
  89.     mkdir -p /tmp/boot/var/log/debian/$path
  90.     file=${line##*/}
  91.     wget --no-check-certificate -qO /tmp/boot/var/log/debian/$path/$file $LinuxMirror/$line
  92.   done

  93.   mkdir -p /tmp/boot/var/log/debian/dists/jessie/main/binary-amd64/
  94.   mkdir -p /tmp/boot/var/log/debian/dists/jessie/main/debian-installer/binary-amd64/
  95.   mkdir -p /tmp/boot/var/log/debian/dists/jessie/main/installer-amd64/current/images/

  96.   wget --no-check-certificate -qO /tmp/boot/var/log/debian/dists/jessie/Release $LinuxMirror/dists/jessie/Release
  97.   wget --no-check-certificate -qO /tmp/boot/var/log/debian/dists/jessie/main/binary-amd64/Release $LinuxMirror/dists/jessie/main/binary-amd64/Release
  98.   wget --no-check-certificate -qO /tmp/boot/var/log/debian/dists/jessie/main/debian-installer/binary-amd64/Release $LinuxMirror/dists/jessie/main/debian-installer/binary-amd64/Release,同路径下还有一个Packages.gz
  99.   wget --no-check-certificate -qO /tmp/boot/var/log/debian/dists/jessie/main/installer-amd64/current/images/udeb.list $LinuxMirror/dists/jessie/main/installer-amd64/current/images/udeb.list

  100.   chmod -R 0644 /tmp/boot/var/log/debian/
  101. fi
复制代码


————

脚本版权归原作者所有。还可以像群晖web assit一样,https://wiki.debian.org/DebianInstaller/WebInstaller。preseed还可用于网络和qemu启动


2#
发表于 2020-5-29 21:37:19 来自手机 | 只看该作者
非常专业,赞
回复

使用道具 举报

3#
 楼主| 发表于 2020-6-25 17:07:17 | 只看该作者
这篇系列文章(2)发布在csdn和我的个人站上,太长。超过贴子总长不让发
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-12-1 18:56

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表