Translation(s): English - espaƱol


Install a preseeded Debian from a USB stick which holds a package archive.

Introduction

The techniques described on this page have the objectives of

Automation is done via preseeding and the focus here will be on the i386 Debian 8 (Jessie) and Debian 9 (Stretch) architectures to illustrate the process. The same techniques should be applicable to pre-Debian 8 (Wheezy and earlier) and the amd64 architecture of both distributions.

  • There is a sample preseed.cfg file available to consult. It is tailored to install a minimal text mode OS which has an ethernet connection to the internet.

Requiring Root Privileges

For Debian 8 and later an ordinary user does not have the permissions to write to a raw device. Using the dd, fdisk, cfdisk, mkfs.vfat and grub-install commands will not work for such a user. The only way to have these commands complete successfully is for a user to gain root privileges with su or sudo or logging in as root.

For Debian 7 an ordinary user does have the permissions to write to a raw device and the dd, fdisk, cfdisk, mkfs.vfat and grub-install commands will be successful. There is no requirement to use su or sudo for a device to be partitioned, formatted and have GRUB installed to its MBR on Debian 7.

An exception to the need to have root privileges is when it comes to mounting a partition on a USB stick. This can be done with or without becoming root.

Preparing the USB Stick

Plug the stick in and use dmesg to determine its device name. For example,

 dmesg | tail -n5

may show:

  [1397586.638562] sd 57:0:0:0: [sdb] Mode Sense: 23 00 00 00
  [1397586.639306] sd 57:0:0:0: [sdb] No Caching mode page found
  [1397586.639316] sd 57:0:0:0: [sdb] Assuming drive cache: write through
  [1397587.391423]  sdb: sdb1 sdb2 sdb3
  [1397587.397023] sd 57:0:0:0: [sdb] Attached SCSI removable disk

In the above case, its device name is "/dev/sdb". Its device name is assumed as "/dev/sdb" in the following commands. If it is not, replace "/dev/sdb" with the correct value.

The device name can also be found using the command

  lsblk

It is best to play safe and obliterate any record of previous partitioning and of the stick having possibly held an isohybrid ISO. GRUB will refuse to install in the MBR of a device if it detects that it has once held an isohybrid image.

  dd if=/dev/zero of=/dev/sdb count=100

Partition the stick to have a single FAT16 primary partition:

  /sbin/fdisk /dev/sdb
or
  /sbin/cfdisk /dev/sdb

Install the dosfstools package, put a vfat filesystem on the partition you have created and label the partition.

  /sbin/mkfs.vfat /dev/sdb1
  /sbin/dosfslabel /dev/sdb1 ARCHIVE

FAT and vfat are chosen because modules for them are available from the very beginning of the start the installer.

Installing GRUB on the USB Stick

Being able to mount and unmount the USB stick is a pre-requisite to installing GRUB to its MBR. As root:

  mount /dev/sdb1 /mnt
  umount /mnt

If you are working within one of the desktop environments it is very likely the mounting can be done as a user from the file manager which comes with it. This is because udisks2 will be on the system. A label will possibly be used for the mount point.

Check the mount point from within the file manager or with the command

  mount

Without a desktop environment but with pmount, udevil or udisks2 on the system, one of the following commands may be run as a user to mount the primary partition. The mount point for pmount is /media/ARCHIVE. The other two programs will indicate where the mount point is located.

  pmount /dev/disk/by-label/ARCHIVE ARCHIVE
  udevil mount /dev/disk/by-label/ARCHIVE
  udisksctl loop-setup -f /dev/disk/by-label/ARCHIVE
  udisksctl mount -b /dev/disk/by-label/ARCHIVE

Unmounting is with:

  pumount /dev/disk/by-label/ARCHIVE
  udevil unmount /dev/disk/by-label/ARCHIVE
  udisksctl unmount -b /dev/disk/by-label/ARCHIVE

GRUB in the Master Boot Record (MBR) of the USB stick is achieved with:

  /usr/sbin/grub-install --boot-directory=<mount_point>/boot /dev/sdb

Booting from the USB Stick

The method chosen here to boot a USB stick requires a kernel, an initrd and a grub.cfg. The first two items are obtainable for the Debian 8 i386 architecture from

  http://ftp.nl.debian.org/debian/dists/jessie/main/installer-i386/current/images/hd-media/

and copied to <mount_point>/boot:

  cp vmlinuz <mount_point>/boot
  cp initrd.gz <mount_point>/boot

The Installation Image

The initrd contains the iso-scan program; this will search all disks for an installation image. Suitable images are the first image of a CD or DVD set (labelled as debian-something-1) or a netinst image. If you anticipate having to rely on non-free firmware for the installation you could consider using an image from

  http://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/

As part of an automated process you can avoid all disks being searched by constructing a grub.cfg which designates where the image to be used for the installation is. shared/ask_device=manual informs the installer that the device where the image is will be manually selected and shared/enter_device=/dev/disk/by-label/ARCHIVE (if labelling is used) tells it what the selected device is.

The Preseed File

A directory to hold the installation image, the preseed.cfg and any other files is convenient:

  mkdir <mount_point>/files
  cp <installation_image> <mount_point>/files
  cp preseed.cfg <mount_point>/files

The location for the installer to look for preseed.cfg is given as file=/hd-media/preseed.cfg on the linux line of grub.cfg.

preseed.cfg will be found and loaded by the installer because the partition holding the initrd is mounted on /hd-media after the questions about language and keyboard layout are asked. This implies language and keyboard layout cannot be preseeded in preseed.cfg. They can be preseeded, however, on the linux line with (for example) locale=en_GB.UTF-8 and keymap=gb.

A Sample grub.cfg File

Putting together what we have up to now, grub.cfg would look like this:

  menuentry 'Debian 8.2.0 i386 automated install' {
    linux /boot/vmlinuz shared/ask_device=manual                       \
                        shared/enter_device=/dev/disk/by-label/ARCHIVE \
                        file=/hd-media/files/preseed.cfg               \
                        locale=en_GB.UTF-8 keymap=gb
    initrd /boot/initrd.gz
  }

Copy this file to the USB stick:

  cp grub.cfg <mount_point>/boot/grub

Summary-1

  1. After blanking the first 64 sectors of the USB stick, partition it, format the partition with vfat and label it.

  2. Install GRUB to the stick's MBR.

  3. Make a directory files on the stick. Copy the installation image and preseed.cfg to files.

  4. Copy initrd.gz and vmlinuz to /boot.

  5. Copy grub.cfg to /boot/grub. Do not forget to specify your label.

  6. Unmount the stick and boot from it.

Choose from Multiple Installation Images

It is tempting to have more than one installation image in files and anticipate choosing one of them. This will work with a single partition on the USB stick if you are prepared to forgo some of the preseeded automation of responses to the first few questions presented by the installer.

One method is to add

  priority=medium

to the linux line of grub.cfg. The stick's primary partition will be scanned for ISO images and a choice of which one to use given. After the selection the debconf priority can be put back to high to take advantage of the rest of the preseeding.

This bug report suggests a second method when all ISOs are in one directory. The installation will halt and display the contents of morefiles. After the selection the preseeding takes over again without user intervention.

  mkdir <mount_point>/files/morefiles

and move the installation images into the morefiles directory. Then add

  so-scan/ask_second_pass=true

to the grub.cfg.

A third method, which preserves all automation, is to make more partitions on the USB stick and put an ISO on each of them. Label the new partitions (LABEL-2, LABEL-3 etc) and construct more grub stanzas. They will only differ from the original one by having

   shared/enter_device=/dev/disk/by-label/<LABEL-2>
   shared/enter_device=/dev/disk/by-label/<LABEL-3>

  • Remember that the architectures of the kernel and initrd images and the installation image must match.

Using GRUB's Loopback Facility

This feature of GRUB allows the kernel and initrd images within an ISO to be used for booting an ISO. This means the hd-media vmlinuz and initrd.gz would apparently not be required. Unfortunately, the installer images (netinst, CD-1, DVD-1 etc) have initrds which do not contain iso-scan, so an installation image cannot be searched for.

What could be tried, though, is using the hd-media initrd with a loopback stanza in grub.cfg.

set isofile="files/firmware-8.2.0-i386-netinst.iso"
menuentry 'loopback' {
     loopback loop (hd0,1)/$isofile
     linux  (loop)/install.386/vmlinuz shared/ask_device=manual                       \
                                       shared/enter_device=/dev/disk/by-label/ARCHIVE \
                                       file=/hd-media/files/preseed.cfg               \
                                       locale=en_GB.UTF-8 keymap=gb
     initrd /boot/initrd.gz
}

  • There is no guarantee that mixing an hd-media initrd with an ISO's kernel will produce a desirable outcome in all circumstances.

Creating a Package Archive

Mount the USB stick and set up a package directory structure. Staying with the i386 architecture:

  mkdir -p <mount_point>/debian/dists/jessie/main/binary-i386
  mkdir -p <mount_point>/debian/dists/jessie/contrib/binary-i386

Binary packages for the archive are obtained from the CD or DVD sets, (labelled as debian-something-1, debian-something-2 etc). Please consider using jigdo for downloading packages and making the images.

The binaries are in the pool/main and pool/contrib directories of the downloaded images. They may be copied to the stick using one of the methods described here. For example, for DVD-1:

 bsdtar -C <mount_point>/debian -xf debian-8.2.0-i386-DVD-1.iso pool/main

Repeat for other images.

The Packages Index Files

Install dpkg-dev to get dpkg-scanpackages. Then:

  cd <mount_point>

and

  dpkg-scanpackages debian/pool/main /dev/null > debian/dists/jessie/main/binary-i386/Packages

Repeat for the contrib packages.

  dpkg-scanpackages debian/pool/contrib /dev/null > debian/dists/jessie/contrib/binary-i386/Packages

Telling the OS About the Package Archive

This is done as root in /etc/apt/sources.list of the installed OS.

  deb [ trusted=yes ] file:/media/<mount_point>/debian jessie main contrib

With a labelled partition <mount_point> could be /media/ARCHIVE or /media/$USER/ARCHIVE, depending on which utility is used to mount the USB stick.

Summary-2

  1. Carry out steps 1 to 5 of Summary-1

  2. Construct a package directory structure.

  3. Extract binary packages from Debian ISOs and copy them to the stick.

  4. Create Packages index files.

  5. Write a sources.list.

Accessing the Package Archive

Plug in the stick and mount it. As root:

  apt-get update
  apt-get install <packages>