summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-03-06 17:00:21 +0000
committerLars Wirzenius <liw@liw.fi>2022-03-06 17:00:21 +0000
commiteeeac21cea769bc34eb2e5ede7aa0ac961b6c6be (patch)
tree00226c55bfbb532e44605f7e7e0367121543d31f
parent86991387198200e5d0c066600175650fbcdbc952 (diff)
parentf21ac0c30a2097fdb09a990fdb219e079ecb0671 (diff)
downloadv-i-eeeac21cea769bc34eb2e5ede7aa0ac961b6c6be.tar.gz
Merge branch 'tutorial' into 'main'
docs: add a tutorial See merge request larswirzenius/v-i!18
-rw-r--r--README.md58
-rw-r--r--tutorial.md115
2 files changed, 149 insertions, 24 deletions
diff --git a/README.md b/README.md
index 1d1294e..14a00fb 100644
--- a/README.md
+++ b/README.md
@@ -60,12 +60,14 @@ Explanation:
DHCP, it can provide a name. The author's home network setup
automatically adds that hostname to the internal DNS. This avoids a
manual DNS configuration step, and the author is lazy.
-* `drive`---the main drive to install to. This will have the EFI and
- `/boot` partitions, and have GRUB installed. The rest of the drive
- will be a physical volume for LVM2.
+ ([dnsmasq](https://dnsmasq.org/) is lovely.)
+* `drive`---the main drive to install to. This is where the EFI and
+ `/boot` partitions are created, and where GRUB gets installed. The
+ rest of the drive will be a physical volume for LVM2.
* `extra_drives`---any additional physical volumes for LVM2. These
- will not be partitioned.
-* `luks`---the password for full disk encryption for LVM2 physical
+ will not be partitioned, and will be used entirely as physical
+ volumes.
+* `luks`---the password for full disk encryption for all LVM2 physical
volumes. If not set, LUKS is not used. This is a single, fixed
password that is in cleartext. You are expected to change it after
the system is installed and boots. If you'd rather use, say, a
@@ -76,14 +78,15 @@ Explanation:
[`std.yml`][]) that it uses unconditionally, to set up a "standard
system" that the author likes. You can provide additional playbooks,
for additional configuration at installation time.
+* `ansible_vars`---variables to set for Ansible playbooks.
- the `user_pub` variable contains an SSH public key that gets
installed into the `root` user `authorized_keys` file on the
- installed system
-* `ansible_vars`---variables to set for Ansible playbooks.
+ installed system by the standard playbook
With all this configuration in a file, which you can keep in git, you
can install a base system repeatedly to a specific computer, and do it
-the same way every time.
+the same way every time. If that's not something you do, then you may
+want to use the official Debian installer instead.
(Caveat: **v-i** does nothing to configure your BIOS/UEFI. It can't.
You have to manually configure it the way you want it to be. For
@@ -106,24 +109,25 @@ tedious.)
The official [Debian installer][] is often referred to as _d-i_. It
works quite well, for almost any hardware Debian can run on, and
-supports a lot of languages, and if flexible enough to be acceptable
+supports a lot of languages, and it's flexible enough to be acceptable
for nearly every use case. Millions upon millions of people are
satisfied users of it. It is a great achievement of Debian, and the
people of the `debian-boot` team.
-However, the **v-i** author felt it could be improved upon for them:
+However, the **v-i** author felt it could be improved upon slightly
+for their use case:
* d-i is not entirely easy to understand and modify. It requires
building special [udeb][] packages for any software that's to be
part of the installer environment, which makes it harder to make
- changes without collaboration from maintainers of those packages.
- The architecture of d-i is also a little non-linear. d-i also needs
- to support a very wide variety of hardware and use cases, which has
+ changes without co-operation from maintainers of those packages. The
+ architecture of d-i is also a little non-linear. d-i also needs to
+ support a very wide variety of hardware and use cases, which has
made it large and complex.
**v-i** is happy with normal deb packages, and is a thin Python
wrapper script around **vmdb2**, making it reasonably easy to
- understand and change.
+ understand and change. Well, easy for its author.
* d-i is primarily meant to be used interactively, but it does support
[preseed files][] for automating an installation. Preseeding means
@@ -154,7 +158,8 @@ be finished using your configuration management system of choice.
While **vmdb2** can, and does, run Ansible to configure the system
being installed, in practice some things work better if most
-configuration is done to a running system. The goal of **v-i** is to
+configuration is done to a running system; if nothing else, some
+Ansible modules don't work well in a chroot. The goal of **v-i** is to
get a system into that state as quickly and easily as possible. For
example, the Ansible module to set a hostname on a system with systemd
requires systemd to be running. That's awkward while the system is
@@ -164,6 +169,8 @@ Thus, **v-i** does the following:
* delete any trace of LVM2 from all drives, wipe all SSDs, and
generally reset the system to as close to a blank state as possible
+ - there is no question "are you sure?" to give the user a chance to
+ repent: as soon as you run **v-i**, you've lost all your data
* create a partition table ("label") on the target drive
* create EFI and boot partitions, needed to boot with UEFI and LUKS
* create a physical volume for LVM2, and a logical volume for the root
@@ -189,7 +196,8 @@ archive. On subsequent runs, if the cache file exists, it's unpacked,
instead of running the commands. This speeds things up a bit: running
**v-i** without the cache file takes the author about 5 minutes; with
the cache file it takes about 1.5 minutes. This matters if there is a
-need to do many installations.
+need to do many installations. It also matters if you're developing
+an installer and need to run it tens of times a day.
## Hacking
@@ -210,11 +218,8 @@ Also, to build an image to boot off for running the installer:
* `installer.yml`---the Ansible playbook for creating the installer
image
-You'll want to build your own installer image, if you want to log into
-it over SSH, so that you can install your own SSH key. If you log in
-via the Linux virtual console, you don't need that: there's no
-password for root (but SSH login for root doesn't work with
-passwords).
+See the tutorial about ways to add your SSH public key to the image so
+that you can log into the installer via SSH.
You probably mostly only need to modify `v-i` and `std.yml`. The rest
is to get you and your target machine into a state where you can run
@@ -242,10 +247,15 @@ we will see.
Yes.
+### Why is BIOS (without UEFI) not supported?
+
+All of the author's PCs have UEFI, and the author doesn't care to do
+the work to add support for BIOS.
+
### What about multi-boot?
**v-i** doesn't support installing more than one operating system on
-one computer.
+one computer. The author has no need for this.
### What about installing something else than Debian?
@@ -263,10 +273,10 @@ least the following steps in **vmdb2** code, and then change the
cache tar archive
* `apt`---install packages
- whatever package manager the system has probably works
- - you can probably run the package manager from a chroot step
+ - you can probably run the package manager from a **vmdb2** `chroot` step
* `grub`---install boot loader
- this chooses the appropriate Debian package automatically
- - might possibly be doable as a chroot step
+ - might possibly be doable as a `shell` step
- this is likely the trickiest bit: booting is _intricate_
* `cryptsetup`---format a drive for full disk encryption
- this just runs the `cryptsetup` program and tells the fstab step
diff --git a/tutorial.md b/tutorial.md
new file mode 100644
index 0000000..e9bbee2
--- /dev/null
+++ b/tutorial.md
@@ -0,0 +1,115 @@
+# Install Debian on a bare metal system with v-i
+
+You need:
+
+- a USB drive, at least 4 GB
+- a PC that supports UEFI
+- backups: _all drives_ in the PC will be wiped from data
+
+The steps:
+
+1. Download the installer image from
+ <https://files.liw.fi/v-i/v-i.img.xz>. You can use `curl` or `wget`
+ or your web browser. Use **one of** the following commands:
+
+ ~~~sh
+ curl https://files.liw.fi/v-i/v-i.img.xz > v-i.img.xz
+ wget -c https://files.liw.fi/v-i/v-i.img.xz
+ ~~~
+
+2. Unpack the image.
+
+ ~~~sh
+ unxz v-i.img.xz
+ ~~~
+
+3. Insert USB drive and write the image to the stick. I prefer GNOME
+ Disks for this, but dd will work. Look up the device of the USB
+ stick: run `sudo dmsg -T` and look for relevant kernel message, or
+ use GNOME Disks, or something else. Replace the actual device for
+ `sdx` below, then run the following command:
+
+ ~~~sh
+ dd if=v-i.img bs=1M oflag=direct status=progress of=/dev/sdx
+ ~~~
+
+4. You will need to be able to log into the installer, once it's
+ running. You can do this by logging in as `root` without a password
+ on the virtual console, or you can use SSH. Note that SSH logins as
+ root _must_ use key authentication: passwords _do not work_.
+
+ For SSH login you need to install your SSH public key into the
+ `authorized_keys` file. If you want that, use **one of** the
+ following two:
+
+ - run a script to install it on the USB drive you've just written
+ the image to:
+
+ ~~~sh
+ sudo bash set-authorized-keys /dev/sdx path/to/your/key.pub
+ ~~~
+
+ - create a second stick with a file system with the label
+ `v-i-config` and a file called `authorized_keys`, and have that
+ in a USB port when you boot from the v-i USB drive
+
+5. Make sure everything has been written to the USB drive. Again, I
+ prefer GNOME Disks for this, but from the command line:
+
+ ~~~sh
+ sync
+ eject /dev/sdx
+ ~~~
+
+6. Move the USB drive to the target machine and boot off the drive.
+ How this happens varies from machine to machine. On my Thinkpad, I
+ press F12 at the POST screen and then choose the right drive from
+ the boot menu.
+
+7. Wait for the system to boot. Log in as root, either from the
+ virtual console (no password), or via SSH.
+
+8. Create a target specification file `foo-target.yaml`. The name can
+ be anything, but it must be valid YAML. In the example below, there
+ are two NVMe drives. An extra logical volume is created. An extra
+ Ansible playbook is run against the target system. The given SSH
+ public key is installed into the `authorized_keys` file for the
+ `root` user on the target system. All drives will be encrypted
+ using LUKS, with the password "hunter2".
+
+ ~~~yaml
+ luks: hunter2
+ drive: /dev/nvme0n1
+ extra_drives:
+ - /dev/nvme1n1
+ hostname: foo
+ extra_playbooks:
+ - foo-playbook.yml
+ ansible_vars:
+ user_pub: |
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPQe6lsTapAxiwhhEeE/ixuK+5N8esCsMWoekQqjtxjP liw personal systems
+ extra_lvs:
+ - name: vms
+ size: 1T
+ fstype: ext4
+ mounted: /mnt/vms
+ ~~~
+
+9. Install. Add the `--verbose` option to `./v-i` if you want to know
+ what's happening. The first time you run this on a given v-i USB
+ drive, it takes a while: it runs `vmdebootstrap` and that is just
+ slow. However, the output is cached, so further runs are faster.
+
+ ~~~sh
+ rm -f install.log
+ ./v-i foo-target.yaml
+ ~~~
+
+10. Reboot into the installed system.
+
+11. Finish configuring the system in whatever way you like to do that.
+ You can log into it via SSH as root. I use Ansible.
+
+ Remember to change the LUKS password for each drive.
+
+12. Optional: Let me know how it went.