自定义Ubuntu安装程序的指南

我尝试阅读关于预配置定制的指南,但我不明白在哪里和如何修改哪些选项。我只能通过实际示例来舒适地学习,所以我问了这个问题。

我正在研究预配置和自定义解决方案,只需完成几个特定任务:

  • 完全重写默认安装的软件包,类似于最小化安装,并使用 --no-install-recommends 标志的 apt-get
  • 将几个专有应用程序添加到默认安装列表中
  • 在安装和实时会话中自动安装和挂载专有驱动程序
  • 编辑默认安装的应用程序的配置文件
  • 指定带有权限的分区
  • 使用命令行工具(类似于 apt-getaptitude)修改安装媒体(CD/DVD/USB)中的软件包池。

请问有人能告诉我如何配置预配置选项来实现以上要求吗?

NB 在向软件包池添加或删除软件包后,我不理解 GPG 部分。

PS 第三点特别重要。


只是为了明确一下,“Ubuntu Installer”指的是图形界面安装程序(uniquity)还是备选安装程序(debian-installer)? - komputes
@komputes,随便哪个都可以。 - Oxwivi
2个回答

对于参考预置,您可能希望参考安装指南-i386,其中包含以下示例预置:
  /usr/share/doc/installation-guide-i386/example-preseed.txt.gz

完全重写默认安装的软件包,就像最小安装一样。 将几个专有应用程序添加到默认安装列表中。
要提供您想要安装的软件包列表,您可能需要查找以下行:
  tasksel tasksel/first   multiselect ubuntu-desktop

在这里,“ubuntu-desktop”可以更改为任意数量的软件包或元软件。

  • 在安装和实时会话中自动安装和挂载专有驱动程序

除了指定所需的软件包(用于专有驱动程序)之外,我不确定如何完成这个任务。另外一点需要注意的是,你“挂载”一个分区,你“加载”一个内核模块/驱动程序。

  • 编辑默认配置文件以适应默认安装的应用程序

要进行这种类型的脚本更改,你可能需要研究一下:

  d-i preseed/late_command string ...

在这里,"..." 可以被替换为任意命令,例如 sed -i。

  • 指定分区及其权限

上述示例 preseed 中有一个分区部分。

使用 preseed 的 Ubiquity

Casper 支持 preseed,并且 ubiquity 可以预设多个值。以下是与 ubiquity 相关的一些可预设的变量:

ubiquity countrychooser/shortlist select US
ubiquity languagechooser/language-name select English
ubiquity localechooser/supported-locales multiselect en_US.UTF-8
ubiquity ubiquity/summary note
ubiquity ubiquity/reboot boolean true
ubiquity ubiquity/poweroff boolean true
ubiquity ubiquity/success_command string ...

在这里的 "..." 中包含的内容与上述的 late_command 相同,success_command 是由 ubiquity 读取的,而 late_command 是由 d-i 读取的。


没有办法事先更改配置文件吗?我如何防止安装推荐的软件包?我如何添加专有软件包进行离线安装? - Oxwivi
听起来你想创建一个自定义镜像,就像这里描述的那样:https://help.ubuntu.com/community/LiveCDCustomization该镜像还可以包含一个预置文件,您可以在其中更改配置文件,就像之前描述的那样。另一种方法是,您还可以为某些自定义内容创建自己的软件包。 - komputes
好的,忘掉改变配置吧,我需要自定义CD说明书来包含默认光盘上没有的软件包吗? - Oxwivi
我挂载了一个镜像,将内容复制到一个目录中,修改了Ubiquity参数。我该如何完成它? - Oxwivi
要完成/构建ISO映像,请参阅此处标题为“生成CD映像”的讨论:help.ubuntu.com/community/LiveCDCustomization - komputes

以下是创建修改后的引导镜像的步骤。将其刻录到光盘上,或将ISO文件插入虚拟机进行测试。您需要使用cpiogenisoimage(这些是软件包和可执行文件的名称)。
以下内容以Makefile的形式呈现,但也可以交互输入。${IN_ISO}指的是原始ISO镜像(我使用了-alternative版本,建议您也这样做),${OUT_ISO}指的是所需的ISO名称。
# Extract the ISO image to mount/ and copy it to cdroot/
cdroot:
    mkdir -p mount
    sudo mount -o loop ${IN_ISO} mount
    mkdir cdroot
    cd cdroot && tar cf - ../mount --transform 's,^mount/,,' | tar xf -
    sudo umount mount && rm -r mount
    chmod -R a+rw cdroot

# Copy new files to the disk. Content of those files is posted below
prepare: cdroot
    cp isolinux.cfg cdroot/isolinux/isolinux.cfg
    test -e ./initrd.orig.gz || cp cdroot/install/initrd.gz ./initrd.orig.gz
    mkdir -p initrd
    cd initrd && gunzip <../initrd.orig.gz | sudo cpio -i && cd ..
    cp preseed.cfg initrd/preseed.cfg
    cd initrd && find . | cpio -o --format=newc | gzip -9 > ../cdroot/install/initrd.gz && cd ..
    sudo rm -rf initrd

# Create the ISO image. Make sure to use extensions for lower-case filenames    
iso: cdroot prepare
    genisoimage -o ${OUT_ISO} \
        -force-rr -J \
        -b isolinux/isolinux.bin -c isolinux/boot.cat \
        -no-emul-boot -boot-load-size 4 -boot-info-table \
        cdroot

你需要一些额外的文件: isolinux.cfg 配置引导加载程序。你希望它只是启动,并自动完成安装过程。它应该看起来像这样:
default install
label install
  menu label ^Install my custom Ubuntu
  kernel /install/vmlinuz
  append auto initrd=/install/initrd.gz --
# Leave 2 seconds to abort or debug
prompt 1
timeout 20

这是我们在实际配置安装之前所需的所有准备工作。下载预设示例并将其命名为preseed.cfg。仔细查看并编辑您想要的内容。重要选项包括:
# Locale
d-i debian-installer/locale string en_US
d-i time/zone string US/Eastern

# Partitioning. The following settings WILL OVERWRITE ANYTHING
# Don't insert the CD into your boss' computer ...
d-i partman-auto/method string regular
d-i partman/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true

# To create a normal user account.
d-i passwd/user-fullname string Ubuntu User
d-i passwd/username string ubuntu
d-i passwd/user-password password insecure
d-i passwd/user-password-again password insecure
d-i user-setup/allow-password-weak boolean true

# Package selection. Don't include ubuntu-desktop to significantly reduce the content
tasksel tasksel/first multiselect standard

#d-i preseed/early_command string driver installation commands (stuff needed to boot)
#d-i preseed/late_command string driver installation commands, custom software, etc.

但我建议您不要使用上述内容作为示例,而是下载Ubuntu的示例,并使用late_command根据您的需求进行配置。您可以在shell中执行任何操作,包括下载和执行安装和配置自定义软件的脚本。例如,将以下内容用作late_command
d-i preseed/late_command string in-target sh -c 'wget https://example.com/my/install.sh && sh install.sh'

或者,您可以将install.sh放到initrd上方并直接执行它。它的内容可能如下所示:
#!/bin/sh
aptitude install -y x11-apps any-package-you-want-installed
wget http://proprietary.com/drivers/for/ubuntu.tar.gz -O- | tar xf - && sh drivers/instal.sh

这真的取决于你的专有驱动程序安装程序如何工作。


就像我在问题中所说的那样,我想要关于如何准确执行我列出的任务的指导;我应该如何重写将要安装的软件包?那么专有驱动程序的自动安装呢? - Oxwivi
@Oxwivi 写一个脚本,用 late_command 下载并执行安装你想要的所有东西。Package selection 是你可以使用来安装自己的软件包的部分,但你也可以在脚本中完成。 - phihag
更新了一个安装软件包和专有驱动程序的示例。 - phihag
好的,我开始理解它的工作原理,但是我希望驱动程序可以自动安装在光盘上 - 我不知道你是否知道,但是专有驱动程序在Ubuntu镜像的ISO文件中是可用的,因为我在没有互联网连接的情况下安装了它们。 - Oxwivi
看来我需要发布另一个问题,询问如何编写安装和配置专有驱动程序的脚本。 - Oxwivi
@Oxwivi 抱歉,我以为你想要安装自己的驱动程序,而不是非免费的Ubuntu驱动程序。但这没问题:只需在“tasksel”部分中添加软件包名称即可。将d-i mirror/udeb/components multiselect main, restricted, universe, multiverse添加到preseed文件中以启用专有的Ubuntu存储库。哦,还有,编写安装和配置脚本很简单:只需将您在交互式控制台中键入的内容复制到安装脚本中(并设置一些标志,例如对于软件包管理器,使用-y来抑制询问)。 - phihag
请举个例子好吗?我从实际例子中学得最好,而不是通过指令。你给我展示了例子并解释了它们的作用,让我终于明白了我需要的前置工作是如何运作的。谢谢! - Oxwivi
@Oxwivi 我已经更新了答案,并附上了安装脚本的示意图。例如,如果你想要安装2ping软件包,只需在配置脚本中添加aptitude install -y 2ping。如果你想要添加配置项,可以在etc目录下找到配置文件(比如说/etc/2ping.conf),然后添加配置选项,比如echo "verbose-level 3" >> /etc/2ping.conf。抱歉,但这真的取决于你想要安装什么。 - phihag
不,我想要安装专有驱动程序的示例。唉,希望能更像论坛贴子一样,以便进行这种延续性讨论。非常抱歉给你添麻烦了。 - Oxwivi
@Oxwivi 专有驱动程序也是常规软件包,只是从二进制源代码构建而成。例如,要安装最新的NVIDIA驱动程序,您可以使用 apt-get --purge remove xserver-xorg-video-nouveau && aptitude -y install nvidia-glx-new linux-restricted-modules - phihag
在我的情况下,是无线网卡出了问题,而不是显卡。我没有办法在没有jockey(附加驱动程序及其命令行对应项)的情况下安装它,但我又不想只为了一个驱动程序而安装它。而且我是一个(非官方的)LoCo成员,所以我正在寻找一种通用的方法,在安装过程中安装任何类型的专有驱动程序。 - Oxwivi
1@Oxwivi 你可以在脚本中安装jockey,然后使用aptitude purge jockey将其移除。我不确定你所指的“通用方法安装任何类型的专有驱动程序”是什么意思。这是一种通用方法来安装任何受限驱动程序,只需将要安装的驱动程序包放入tasksel或在脚本中的aptitude install -y之后即可,它就会起作用。如果你希望你的映像在多台机器上运行,你可能需要找到一种方式询问jockey以获取所有适用的专有驱动程序。 - phihag
1@Ocwivi ... 不过,安装所有可用的专有驱动程序通常是一个不明智的做法:专有驱动程序通常是旧的、不受支持的,并且需要额外的非标准配置。此外,您必须确保您在法律上被允许分发非自由驱动程序。 - phihag
我相信Ubuntu自带的专有驱动程序,并且如果需要的话,我想安装它们。 - Oxwivi
1@Oxwivi 那种信任是没有根据的,因为任何人都可以将任何东西放入非自由软件仓库中。然而,这个讨论超出了这个问题的范围(关于预设)。你应该问如何获取适用于当前系统的专有驱动程序列表。 - phihag
我已经做过了,并发现jockey-common只是Python脚本的一个包装器 - 现在要弄清楚哪个脚本做什么...无论如何,一旦我弄清楚了我安装程序上想要的一切,我会有更多问题的,感谢你的帮助和耐心! - Oxwivi
安装一个发行版会加载一个Linux会话,对吗?你知道加载了哪些应用程序以及如何将应用程序添加到该列表中吗? - Oxwivi
@Oxwivi 是的,你可以这么说。然而,在命令行环境中,并不是“加载”应用程序,而是执行它们(通常只按顺序执行)。正如我在答案中提到的,你可以通过将其添加到“late_command”选项来使程序执行。例如,要计算1+1并将结果写入根目录,你可以将 in-target sh -c 'expr 1 + 1> /addition.result' 添加到 late_command 中。 - phihag
嗯,有哪些应用程序可以供我使用,以及如何添加更多应用程序? - Oxwivi
@Oxwivi 所有应用程序都可以在目标系统中使用,但只有非常有限的子集(其中包括一个精简版的 busybox)。唯一的限制是在安装期间某些基本服务(如音频和图形服务器)不可用。您可以通过将相应的软件包添加到 d-i pkgsel/include 或将应用程序包含在您的 initrd 中来添加更多内容。 - phihag
我在preseed.cfg上遇到了问题,我将其作为一个新问题发布了(http://askubuntu.com/questions/85744/preseed-file-being-ignored-during-installation)。还有其他人遇到过预置的问题吗? - Curtis Hall