• 将pebuilder变成dibuilder.sh,将di tools集入boot层(2):发明minstack live os


    本文关键字:remaster多个deb成单个静态配置deb包,或可重新配置的deb包,及用dpkg命令代替apt操作deb文本数据库,安装信息数据库,slax,can be in a rom flash,自己发明一个tinycorelinux

    本文接文章1,在tdi的基础上发明minstack liveos,即实现在tdi上kiosk mode开启chrome。先测试一下可行性。在debian jessie 8.11上安装xorg,要初步实现能在安装完后startx。

    我们直接linux /boot/vmlinuz,initrd /boot/tdl-intrd.gz启动tdl,然后apt-get install --no-install-recommends xserver-xorg-core xinit,xinit中有startx,为什么用xserver-xorg-core,是因为考虑到它应该是较小的。但是安装完后startx,出现usr/bin/x not found,这是因为/usr/bin/X在xserver-xorg里面,而在高版中的debian中,dpkg-query -S /usr/bin/X的确是在xserver-xorg-core中但811中是在xserver-xorg中的,所以:把xserver-xorg-core换成xserver-xorg,解决。

    网上说/usr/bin/x是/usr/bin/xorg的软链且是一个脚本,但其实高低版本对此的处理不同,我发现debian系的包其实很容易版本依赖在一个包更新后往往不能一起工作。如qemu libgl,如这里.

    如果startx时还出现timeout in locking authority file /home/xxx/.Xauthority,那是因为前面文章中做的目录权限不对。解决:sudo chown -R td:users $HOME

    startx终于可以进了,默认打开一个黑乎乎的窗口(如果是显示一个窗口后又迅速退出,提示xinit:connect to x server lost,这结果其实也对,这种情况下安装x11-utils会提示一个小对话框因为已经进入x了没有evdev无法点击或切换出来)。altctl f1切出来。继续:

    apt-get install --no-install-recommends chromium,chromium最好用all static build的ungoogle chromium portable linux版的,这里是作为例子直接用仓库中的,然后touch ~/.xinitrc,内容为usr/bin/chromium --viewport=maximized --lang=zh-CN https://www.baidu.com,进去不显光标。无法输入。控制台切换也无法使用了,这是因为tdl没有集成evdev module也没有加载。解决方法:集成同版modules中的kernel/drives/input/evdev.ko并insmod或modprobe进来

    测试通过。

    在tdl 上得到宏xorg包

    第二步是得到一个宏打包的xorg,我们的测试环境是一台正常的debian8.11,利用cpio remaster tdl initramfs的正常套路测试:

    为什么要得到一个宏打包的xorg呢?因为我们想把xorg做成静态免配置的文件在后来放进tdl中被安装,而我们知道debian文件往往使用了大量配置,几乎每个包都是动态的,都有配置文件和脚本。

    关于如何remaster多个deb成单个静态配置deb包/可重新配置deb包

    deb生态其实就是后端文本数据库,加deb工具(dpkg,apt,etc),比如其实文1讲到的dpkg与debootstrape,就是后者调用前者的关系,debootstrap自己维护有一个base apt,,再加前后端如dialog,readline收集用户输入组成的一个系统。因此debootstrape会有前面说到的if has frontend等判断。而包中会有一些调用deb工具的脚本,由于这些脚本与debconf等工具绑定。因此deb包只适用于debian系。

    在当前debain中remaster多个目标debian的deb为一个,要么在新debian系统里针对重新形成的deb再配置。要么直接在当前debian中事先配置好,使之成为预配置/静态/无须再配置的deb包,在新debian中无须再配置。
    首先我们不能直接在当前系统批量无序dpkg -x *.deb extracted,因为软件未配置。如果批量dpkg -i *.deb,则不能无序,因为依赖关系存在。否则一个包在其依赖包没有配置好前配置,会在目标失败。另外,批量dpkg -i,也没有机会喂给一个extracted,即使使用dpkg -i --instdir=extracted *.deb(无论是在当前系统还是chroot到目标debian),这句也经常出错。
    如果没有-instdir需求,我们可以有一个权宜之计,你完全可以find all debs|while read line; do sudo chroot $xx dpkg --force-overwrite --force-confold -i ${line};done这种方式重复3到5次强行覆盖以解决安装依赖问题模拟我们接下来的测试过程:直到命令中全部提示already installed, skipping为止,上面二个force保证了可以多次覆盖的方法来粗暴地解决依赖问题,还有force-depends,force-all等(这也是debootstrap chroot xxx用的参数),最后打包进initramfs测试,不过这样你就失去了inistdir的好处。不是我们的目的。
    如果没有-instdir需求,你也可以将上述命令换成-x,进而在目标debian中你只需要配置刚刚忽略依赖关系 unpack 的所有软件包: dpkg --force-confold --skip-same-version --configure -a,这里-a 等价于 --pending)不过,这种方式要工作起来需要在单一系统中进行而不是我们这里的跨系统环境,单系统这样做工具可以自动维护好安装信息库的方方面面不出错以dpkg-reconfigure,dpkg -p反删除和卸载(除了status还有statoverrides等),不过这样也失去了instdir的好处而且有点不现实,所以也不是我们的目的。

    总之instdir不工作我们不能依赖dpkg-i,即使能也难维护一个跨debian的后配置完善安装信息库,因此我们只采用dpkg -x,dpkg -e这些解压手段,自己产生并维护一套基本能工作的后配置文件。

    (我们首先用二次以下命令得到xorg包的所有debs差异包)
    sudo debootstrap --download-only --variant=minbase --include=module-init-tools,sudo,ifupdown,isc-dhcp-client jessie tinydebianlive1  http://mirrors.aliyun.com/debian/
    sudo debootstrap --download-only --variant=minbase --include=module-init-tools,sudo,ifupdown,isc-dhcp-client,xserver-xorg,xinit jessie tinydebianlive2  http://mirrors.aliyun.com/debian/
    a=tinydebianlive1
    b=tinydebianlive2
    for i in `ls $a/var/cache/apt/archives`; do sudo rm -rf $b/var/cache/apt/archives/$i; done
    
    (建立目标chroot环境,用文章1得到的tdl-initrd.gz)
    c=tinydebianlive
    sudo mkdir -p $c $c/var/cache/apt/archives && cd $c
    sudo wget -O- http://10.211.55.2:8000/downloads/mirrors/debian/releases/tdl-initrd.gz | gunzip -dc | cpio -idmv
    (复制到等待chroot的环境,b->c)
    sudo rm -rf $c/var/cache/apt/archives/*.*
    sudo cp -av $b/var/cache/apt/archives/* $c/var/cache/apt/archives/
    (去除名字中的%3a,不然接下来dpkg -xx对这些文件名进行处理时可能会跳过)
    for i in `ls $c/var/cache/apt/archives`; do [[ $i =~ '%3a' ]] && sudo mv $c/var/cache/apt/archives/$i $c/var/cache/apt/archives/${i//%3a/-}; done
    
    (接下来就是chroot并得到打包data内容和control)
    sudo mkdir -p $c/extracted $c/extracted/var/lib/dpkg/info
    sudo find $c/var/cache/apt/archives -type f -name "*.deb" | while read line; do echo $line;sudo dpkg -x $line extracted; done
    (你也可以用sudo find $c/var/cache/apt/archives -type f -name "*.deb" | while read line; do sudo sh -c "echo ${line};ar -p ${line} data.tar.xz |xzcat|tar -xf - -C $c/extracted"; done这种更为portable的方法)
    
    sudo find $c/var/cache/apt/archives -type f -name "*.deb" | while read line; do
      echo ${line}
      pkg=$(ar -p ${line} control.tar.gz|zcat|tar -O -xf - ./control 2>/dev/null | sed -ne 's/^Package: *//Ip' | head -n 1)
      ver=$(ar -p ${line} control.tar.gz|zcat|tar -O -xf - ./control 2>/dev/null | sed -ne 's/^Version: *//Ip' | head -n 1)
      echo ${pkg}
      echo ${ver}
      for file in ./control ./templates ./conffiles ./config ./preinst ./postinst ./prerm ./postrm ./shlibs ./md5sums;do
          if ar -p ${line} control.tar.gz| zcat|grep -q $file; then echo $file
          sudo sh -c "ar -p ${line} control.tar.gz| zcat | tar -O -xf - $file > $c/extracted/var/lib/dpkg/info/${pkg}.${file//.//}"
          fi
      done
      sudo touch "$c/extracted/var/lib/dpkg/info/${pkg}.list"
    done
    sudo chmod +x $c/extracted/var/lib/dpkg/info/*.{config,preinst,postinst,prerm,postrm}
    (管道中存在sh -c会开启新的管道因此行不通,管道中也最好不要出现控制流程等,因此尽量使管道中的逻辑简化,并把多出的部分放到整个管道的前面或后面,这个算法解压了$line四次,不科学但是逻辑清晰)
    
    (生成后配置脚本,供在新debian中配置用)
    sudo touch $c/extracted/var/lib/dpkg/info/my-cust-xorg.preinst,作为my-cust-xorg的DEBIAN/preinst控制文件.postinst的内容,请把下列2段处理后的内容手动拷入my-cust-xorg.postinst:
    
    (生成pkglist=pkgname###pkgver形式的软件包列表,注:末尾一个逗号不要)
    echo -n pkglist=;sudo find $c/var/cache/apt/archives -type f -name "*.deb" | while read line; do pkg=$(ar -p ${line} control.tar.gz|zcat|tar -O -xf - ./control 2>/dev/null | sed -ne 's/^Package: *//Ip' | head -n 1);ver=$(ar -p ${line} control.tar.gz|zcat|tar -O -xf - ./control 2>/dev/null | sed -ne 's/^Version: *//Ip' | head -n 1);echo -n ${pkg}'###'${ver}',';done
    (直接复制,调用软件包config,postinstall脚本的函数,然后生成已安装逻辑的语句,这二条效果相当于dpkg -i force-depends安装,注:下列命令直接粘贴执行和放到文件中的效果可能表现不同,优先放文件中执行,你可以用echo 放在{}前测试仅查看匹配的文件名)
    
    for curpkg in `echo ${pkglist} | sed 's/,/
    /g'`; do
        pkg=${curpkg%###*}
        ver=${curpkg##*###}
        sudo find /var/lib/dpkg/info -type f -name $pkg.templates -exec debconf-loadtemplate $USER {} ;
    
        ## sudo find /var/lib/dpkg/info -type f -name $pkg.preinst -exec {} ;
       ## [[ -z $(cat /var/lib/dpkg/status | grep "Package: $pkg") ]] && sudo sh -c "echo 'Package: $pkg
    Version: $ver
    Status: Notinstalled' >> /var/lib/dpkg/status";
    
        sudo find /var/lib/dpkg/info -type f ( -name $pkg.config -o -name $pkg.postinst ) -exec {} ;
       ## [[ -z $(cat /var/lib/dpkg/status | grep "Package: $pkg") && $?==0 ]] && sudo sh -c "echo 'Package: $pkg
    Version: $ver
    Status: install ok installed' >> /var/lib/dpkg/status";
    done
    
    (archives/*.deb也保留不删,便于在新目标中再多方向尝试解决重配置问题。最后要记得加入evdev.ko到extracted的lib/modules/3.16.0-6/kernel/drivers/input)
    

    最后,进行打包,先新建一个extracted/DEBIAN

    (exit chroot环境,在extracted中写DEBIAN/control)
    Package: my-cust-xorg
    Version: 2016-02-26
    Section: free
    Priority: optional
    Depends: libstdc++2.10-glibc2.2
    Suggests: minstack
    Architecture: amd64
    Installed-Size: 6666
    Maintainer: minlearn
    Provides: shalol.com
    Description: xorginabundle=xorg-server+xinit-minbase,module-init-tools,sudo,ifupdown,isc-dhcp-client
    (注意结尾必须空一行)
    

    把上面my-cust-xorg.postinstall拷进extracted/var/lib/dpkg/info,如DEBIAN中含有postinst 、prerm等执行文件我们还要chmod -R 755 DEBIAN,最后dpkg -b extracted xorg.ldeb

    测试后配置脚本

    好了,现在在新启动的tdl-initrd.gz中可以dpkg -x这个包到/并测试chromium等的安装了(不能dpkg -i,安装chromium前sudo depmod,sudo modprobe evdev下再重配置下,然后启动startx)。重配置是一个重点,有几个关注点:

    (上述重配置脚本在实际执行前,由于纯粹依赖脚本和解压文件,我们没有了每个软件的control信息,优先权当然也就没有了,我们做一些准备工作重新获得软件的优先权信息:实际上整个过程就是相当于将preinst和解包隔离在制作deb的那个系统上,而将config和postinst放在新debian上,所以会导致preinstall被抛弃)
    export LC_CTYPE=C
    export LC_ALL=C
    sudo apt-get install Dialog debconf-utils
    sudo dpkg-reconfigure debconf
    (选择dialog,优先权选择low,再次执行下面脚本就会出现让你选择了,我们选择dialog前端和low优先,这样执行下面的脚本时就会弹出配置窗口,有二个一个是关于配置x的用户的,一个是用于配置键盘布局的)

    (尝试启动startx,注意,开启startx只能在非ssh终端才能看到黑屏窗口。提示td用户没有权限X: user not authorized to run the X server, aborting.。只有root有,这跟当初测试时普通和root用户都可以startx不一样,貌似是没有配置到,然而再次/var/lib/dpkg/x11-common.confg,这个配置再次执行是弹不出的不能reconfigure)不过很容易解决(新建/etc/X11/Xwrapper.config,写上一条allowed_users=console),总体来说,它是可用的。

    看来要实现方案完美化,还是需要依赖和dpkg -i那套:

    未来我们还将创建一个从packages.gz计算出依赖的正式脚本而不是从一堆debs中去权宜着去做(并用它强化dibuilder.sh),在得到充份的deb的前提下,上述这种方法基本是能成功的,也是通用的,纯静态配置/后配置的方法,即离线(脱离dpkg和chroot,甚至debian)安装deb包的方法,那么在我们dibuilder.sh脚本仅有静态解压的能力的基础上,可以加上这种能力,使之成为有别于文章1使用debootstrap的方法,因为除非在debian系上才有dpkg+chroot dpkg-reconfigure。甚至可以对udeb包和udpkg进行一样的处理以在di中集进udeb的内容。


    还有,我们可以像群晖pe一样统一di和td,比如发现td没安装的情况下提示安装td或其它系统,这其实也是tc脚本,用同一套脚本适配live和hd安装的pivot root逻辑。比如我们还可以为di提供一个web界面接收dd url,Cobbler就有一个web界面

  • 相关阅读:
    怪怪设计论闲谈篇:职责与解耦的矛盾
    知识传播与社区讨论 : 兜售狗皮膏药的"软件先知"
    反弹和补遗:再论Bjarne Stroustrup的"基于对象"的含义
    回帖整理: 领域建模/表模块,Java/.NET 社区风格
    贫血或职责的讨论
    近期可能会研究和讨论的个人动向
    CLR寄宿(上) MSCOREE.DLL
    代码组(2) 成员条件
    说说emit(中)ILGenerator
    CLR寄宿(下) 托管宿主
  • 原文地址:https://www.cnblogs.com/minlearn/p/14230899.html
Copyright © 2020-2023  润新知