定制Fedora 27 Workstation Live OS首启自动执行Python脚本配置问询
我来给你详细拆解这个需求的实现步骤,毕竟Fedora Live的定制有它自己的一套逻辑——因为Live镜像默认是只读的,而且启动后会在内存中创建临时会话,所以要实现“仅首次启动运行脚本”需要兼顾文件放置、服务配置和持久化标记三个关键点。
一、脚本放置位置
你需要把enable_settings.py放在Live系统的/usr/local/bin/目录下。这个目录是系统预留的自定义脚本位置,不会被系统包更新覆盖,而且默认在系统PATH里,方便调用。
二、具体修改步骤
1. 准备定制环境
首先在一台Fedora系统上安装必要的定制工具:
sudo dnf install lorax livecd-tools xorriso
然后挂载原Fedora 27 Live ISO,提取核心的只读文件系统镜像:
# 创建挂载目录 sudo mkdir /mnt/iso # 挂载原ISO sudo mount -o loop Fedora-Workstation-Live-x86_64-27-1.6.iso /mnt/iso # 提取squashfs.img(Live系统的根文件系统) mkdir ~/live-custom cp /mnt/iso/LiveOS/squashfs.img ~/live-custom/ # 卸载原ISO sudo umount /mnt/iso
2. 挂载只读镜像为可读写模式
因为squashfs是只读格式,我们需要用overlayfs创建可写层来修改内容:
# 创建overlay所需的目录结构 mkdir -p ~/live-custom/rootfs ~/live-custom/upper ~/live-custom/work ~/live-custom/mount # 挂载overlay sudo mount -t overlay overlay -o lowerdir=~/live-custom/rootfs,upperdir=~/live-custom/upper,workdir=~/live-custom/work ~/live-custom/mount # 挂载squashfs.img到lower层 sudo mount -o loop ~/live-custom/squashfs.img ~/live-custom/rootfs
现在~/live-custom/mount就是可读写的Live系统根目录了。
3. 添加脚本并设置权限
把你的脚本复制到目标目录,然后赋予可执行权限:
# 替换为你的脚本实际路径 sudo cp /path/to/your/enable_settings.py ~/live-custom/mount/usr/local/bin/ # 设置可执行权限 sudo chmod +x ~/live-custom/mount/usr/local/bin/enable_settings.py
4. 创建Systemd首次启动服务
我们用systemd的oneshot服务来控制脚本的执行时机,并且通过标记文件确保仅运行一次。创建服务文件~/live-custom/mount/etc/systemd/system/first-boot-settings.service,内容如下:
[Unit] Description=Run one-time system configuration script After=graphical.target Wants=graphical.target [Service] Type=oneshot # 仅当标记文件不存在时执行脚本 ConditionPathExists=!/var/lib/first-boot-completed # 执行你的配置脚本 ExecStart=/usr/local/bin/enable_settings.py # 执行完成后创建标记文件 ExecStartPost=/usr/bin/touch /var/lib/first-boot-completed # 确保服务执行后保持状态 RemainAfterExit=yes [Install] WantedBy=graphical.target
然后启用这个服务:
sudo systemctl enable --root=~/live-custom/mount first-boot-settings.service
5. 解决Live会话的持久化标记问题
这里是关键:Fedora Live默认的/var目录是在内存中的临时文件系统,重启后标记文件会消失,导致脚本每次启动都运行。你有两种解决方案:
方案A:依赖用户创建持久存储
如果你的定制镜像预期用户会创建Live持久存储分区,那么/var/lib会被持久化保存,标记文件会一直存在,后续启动就不会再运行脚本。
方案B:让脚本将标记写入U盘可写分区
如果你希望用户无需手动设置持久化,只要用这个U盘启动过一次,后续就不再运行脚本,可以修改enable_settings.py的开头,自动检测U盘的可写分区并写入标记:
import os import glob # 查找Live用户挂载的U盘可写分区 marker_file = None for mount_point in glob.glob('/run/media/liveuser/*'): if os.path.ismount(mount_point): marker_file = os.path.join(mount_point, '.first-boot-done') break # 如果标记文件存在,直接退出 if marker_file and os.path.exists(marker_file): exit(0) # ---------------------- # 这里写你的脚本核心逻辑 # ---------------------- # 执行完成后创建标记文件 if marker_file: with open(marker_file, 'w') as f: f.write('completed')
6. 重新生成定制Live ISO
完成所有修改后,我们需要重新打包成可引导的ISO镜像:
# 卸载所有挂载的目录 sudo umount ~/live-custom/mount sudo umount ~/live-custom/rootfs # 重新生成squashfs镜像 sudo mksquashfs ~/live-custom/upper ~/live-custom/new-squashfs.img -comp xz # 创建新ISO的目录结构 mkdir ~/new-iso cp -r /mnt/iso/* ~/new-iso/ # 若之前未保留原ISO内容,需重新挂载原ISO复制 # 替换原squashfs.img cp ~/live-custom/new-squashfs.img ~/new-iso/LiveOS/squashfs.img # 生成可引导的ISO sudo xorriso -as mkisofs -o ~/Fedora-Custom-Live-27.iso \ -isohybrid-mbr /usr/share/syslinux/isohdpfx.bin \ -c isolinux/boot.cat -b isolinux/isolinux.bin \ -no-emul-boot -boot-load-size 4 -boot-info-table \ -eltorito-alt-boot -e images/efiboot.img -no-emul-boot \ -isohybrid-gpt-basdat -isohybrid-apm-hfsplus \ ~/new-iso/
内容的提问来源于stack exchange,提问作者Amit24x7

