summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-01-07 12:39:13 +0000
committerLars Wirzenius <liw@liw.fi>2022-01-07 12:39:13 +0000
commita697783d63d8dc410ae0b104f1cf37e4b4d886cf (patch)
treec0346af742973940684d17daf31a843df352a3cb
parentb2614eb640c624f63189ada4af868069ff395469 (diff)
parent602680ab9db41e60ffadacae5c9f190c6d105d86 (diff)
downloadv-i-a697783d63d8dc410ae0b104f1cf37e4b4d886cf.tar.gz
Merge branch 'install-script' into 'main'
drop gnome See merge request larswirzenius/v-i!5
-rw-r--r--ansible.cfg3
-rwxr-xr-xbuild-installer.sh (renamed from v-i.sh)0
-rwxr-xr-xclean-up-disks91
-rwxr-xr-xv-i296
-rwxr-xr-xx220.sh36
-rw-r--r--x220.vmdb118
-rw-r--r--x220.yml12
7 files changed, 304 insertions, 252 deletions
diff --git a/ansible.cfg b/ansible.cfg
deleted file mode 100644
index 67e1f40..0000000
--- a/ansible.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-[defaults]
-nocows = 1
-log_path = ansible.log
diff --git a/v-i.sh b/build-installer.sh
index e1e5084..e1e5084 100755
--- a/v-i.sh
+++ b/build-installer.sh
diff --git a/clean-up-disks b/clean-up-disks
deleted file mode 100755
index 794badf..0000000
--- a/clean-up-disks
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/python3
-
-import glob
-import os
-from subprocess import run
-
-
-def physical_volumes():
- p = run(["pvdisplay", "-C", "--noheadings"], capture_output=True, check=True)
- lines = p.stdout.decode().splitlines()
- pvs = []
- for line in lines:
- words = line.split()
- pv = words[0]
- vg = words[1]
- pvs.append({"pv": pv, "vg": vg})
- return pvs
-
-
-def logical_volumes():
- p = run(["lvdisplay", "-C", "--noheadings"], capture_output=True, check=True)
- lines = p.stdout.decode().splitlines()
- lvs = []
- for line in lines:
- words = line.split()
- lv = words[0]
- vg = words[1]
- path = os.path.realpath(f"/dev/{vg}/{lv}")
- lvs.append({"lv": lv, "vg": vg, "path": path})
- return lvs
-
-
-def volume_groups():
- p = run(["vgdisplay", "-C", "--noheadings"], capture_output=True, check=True)
- lines = p.stdout.decode().splitlines()
- return [line.split()[0] for line in lines if line.strip()]
-
-
-def mount_points():
- mounts = {}
- for line in open("/proc/mounts").readlines():
- words = line.split()
- dev = os.path.realpath(words[0]) if words[0].startswith("/") else words[0]
- mounts[dev] = {
- "mount": words[1],
- "type": words[2],
- }
- return mounts
-
-
-def find_mount_points(mounts, dev):
- res = []
- if dev in mounts:
- root = mounts[dev]["mount"]
- for m in mounts.values():
- if m["mount"].startswith(root):
- res.append(m)
- return res
-
-
-def is_luks(path):
- p = run(["cryptsetup", "isLuks", path], check=False)
- return p.returncode == 0
-
-
-mounts = mount_points()
-pvs = physical_volumes()
-lvs = logical_volumes()
-vgs = volume_groups()
-
-for lv in lvs:
- for m in find_mount_points(mounts, lv["path"]):
- print("unount", m["mount"])
- run(["umount", m["mount"]])
-
-for vg in vgs:
- print("vgremove", vg)
- run(["vgremove", "--yes", vg], check=True)
-
-for pv in pvs:
- print("pvremove", pv)
- run(["pvremove", pv["pv"]], check=True)
- if is_luks(pv["pv"]):
- print("cryptsetup close", pv["pv"])
- run(["cryptsetup", "close", pv["pv"]], check=True)
- else:
- print("not LUKS:", pv["pv"])
-
-for mapping in glob.glob("/dev/mapper/*"):
- if not mapping.endswith("/control"):
- run(["cryptsetup", "close", mapping], check=False)
diff --git a/v-i b/v-i
new file mode 100755
index 0000000..bf1903e
--- /dev/null
+++ b/v-i
@@ -0,0 +1,296 @@
+#!/usr/bin/python3
+
+import argparse
+import glob
+import os
+import shutil
+import sys
+import tempfile
+import yaml
+from subprocess import run
+
+
+def log(msg):
+ print("INSTALLER:", msg)
+
+
+def physical_volumes():
+ log("list physical volumes")
+ p = run(["pvdisplay", "-C", "--noheadings"], capture_output=True, check=True)
+ lines = p.stdout.decode().splitlines()
+ pvs = []
+ for line in lines:
+ words = line.split()
+ pv = words[0]
+ vg = words[1]
+ pvs.append({"pv": pv, "vg": vg})
+ return pvs
+
+
+def logical_volumes():
+ log("list logical volumes")
+ p = run(["lvdisplay", "-C", "--noheadings"], capture_output=True, check=True)
+ lines = p.stdout.decode().splitlines()
+ lvs = []
+ for line in lines:
+ words = line.split()
+ lv = words[0]
+ vg = words[1]
+ path = os.path.realpath(f"/dev/{vg}/{lv}")
+ lvs.append({"lv": lv, "vg": vg, "path": path})
+ return lvs
+
+
+def volume_groups():
+ log("list volume groups")
+ p = run(["vgdisplay", "-C", "--noheadings"], capture_output=True, check=True)
+ lines = p.stdout.decode().splitlines()
+ return [line.split()[0] for line in lines if line.strip()]
+
+
+def mount_points():
+ log("find mount all points")
+ mounts = {}
+ for line in open("/proc/mounts").readlines():
+ words = line.split()
+ dev = os.path.realpath(words[0]) if words[0].startswith("/") else words[0]
+ mounts[dev] = {
+ "mount": words[1],
+ "type": words[2],
+ }
+ return mounts
+
+
+def find_mount_points(mounts, dev):
+ log(f"find mount points using {dev}")
+ res = []
+ if dev in mounts:
+ root = mounts[dev]["mount"]
+ for m in mounts.values():
+ if m["mount"].startswith(root):
+ res.append(m)
+ return res
+
+
+def is_luks(path):
+ log(f"is {path} a LUKS device?")
+ p = run(["cryptsetup", "isLuks", path], check=False)
+ return p.returncode == 0
+
+
+def clean_up_disks():
+ log("clean up disks from old installs")
+
+ mounts = mount_points()
+ pvs = physical_volumes()
+ lvs = logical_volumes()
+ vgs = volume_groups()
+
+ for lv in lvs:
+ for m in find_mount_points(mounts, lv["path"]):
+ log(f"unmount {m['mount']}")
+ run(["umount", m["mount"]])
+
+ for vg in vgs:
+ log(f"remove volume group {vg}")
+ run(["vgremove", "--yes", vg], check=True)
+
+ for pv in pvs:
+ log(f"remove physical volume {pv}")
+ run(["pvremove", pv["pv"]], check=True)
+ if is_luks(pv["pv"]):
+ run(["cryptsetup", "close", pv["pv"]], check=True)
+
+ for mapping in glob.glob("/dev/mapper/*"):
+ if not mapping.endswith("/control"):
+ log(f"open LUKS volume {mapping} (just in case it is one)")
+ run(["cryptsetup", "close", mapping], check=False)
+
+
+def vmdb_spec(cryptsetup_password, playbook):
+ device = "{{ image }}"
+ spec = {
+ "steps": [
+ {
+ "mklabel": "gpt",
+ "device": device,
+ },
+ {
+ "mkpart": "primary",
+ "device": device,
+ "start": "0%",
+ "end": "500M",
+ "tag": "efi",
+ },
+ {
+ "mkpart": "primary",
+ "device": device,
+ "start": "500M",
+ "end": "1G",
+ "tag": "boot",
+ },
+ ]
+ }
+
+ # Set up pv0 for lvm2, either encrypted or cleartext.
+ if cryptsetup_password:
+ spec["steps"].extend(
+ [
+ {
+ "mkpart": "primary",
+ "device": device,
+ "start": "1G",
+ "end": "100%",
+ "tag": "cryptsetup0",
+ },
+ {
+ "cryptsetup": "cryptsetup0",
+ "password": cryptsetup_password,
+ "name": "pv0",
+ },
+ ]
+ )
+ else:
+ spec["steps"].extend(
+ [
+ {
+ "mkpart": "primary",
+ "device": device,
+ "start": "1G",
+ "end": "100%",
+ "tag": "pv0",
+ },
+ ]
+ )
+
+ # Create file systems and install Debian.
+ spec["steps"].extend(
+ [
+ {
+ "mkfs": "vfat",
+ "partition": "efi",
+ },
+ {
+ "mkfs": "ext2",
+ "partition": "boot",
+ },
+ {
+ "vgcreate": "vg0",
+ "physical": ["pv0"],
+ },
+ {
+ "lvcreate": "vg0",
+ "name": "root",
+ "size": "10G",
+ },
+ {
+ "mkfs": "ext4",
+ "partition": "root",
+ },
+ {
+ "mount": "root",
+ },
+ {"mount": "boot", "dirname": "/boot", "mount-on": "root"},
+ {
+ "mount": "efi",
+ "dirname": "/boot/efi",
+ "mount-on": "boot",
+ },
+ {
+ "virtual-filesystems": "root",
+ },
+ {
+ "unpack-rootfs": "root",
+ },
+ {
+ "debootstrap": "bullseye",
+ "mirror": "http://deb.debian.org/debian",
+ "target": "root",
+ "unless": "rootfs_unpacked",
+ },
+ {
+ "cache-rootfs": "root",
+ "unless": "rootfs_unpacked",
+ },
+ {
+ "fstab": "root",
+ },
+ {
+ "apt": "install",
+ "packages": ["linux-image-amd64"],
+ "tag": "root",
+ },
+ {
+ "apt": "install",
+ "packages": [
+ "console-setup",
+ "cryptsetup",
+ "cryptsetup-initramfs",
+ "dosfstools",
+ "ifupdown",
+ "locales-all",
+ "lvm2",
+ "psmisc",
+ "python3",
+ "ssh",
+ "strace",
+ ],
+ "tag": "root",
+ },
+ {
+ "grub": "uefi",
+ "tag": "root",
+ "efi": "efi",
+ "quiet": True,
+ "image-dev": device,
+ },
+ ]
+ )
+
+ # If a playbook has been specified, add an ansible step.
+ if playbook:
+ spec["steps"].append({"ansible": "root", "playbook": playbook})
+
+ return spec
+
+
+def main():
+ p = argparse.ArgumentParser()
+ p.add_argument("--verbose", action="store_true")
+ p.add_argument("--log", default="install.log")
+ p.add_argument("--cache", default="cache.tar.gz")
+ p.add_argument("--playbook")
+ p.add_argument("--luks")
+ p.add_argument("device")
+ args = p.parse_args()
+
+ clean_up_disks()
+
+ spec = vmdb_spec(args.luks, args.playbook)
+ tmp = tempfile.mkdtemp()
+ specfile = os.path.join(tmp, "spec.yaml")
+ if args.verbose:
+ yaml.dump(spec, stream=sys.stdout, indent=4)
+ with open(specfile, "w") as f:
+ yaml.dump(spec, stream=f, indent=4)
+
+ log(f"run vmdb2 to install on {args.device}")
+ run(
+ [
+ "vmdb2",
+ "--verbose",
+ f"--rootfs-tarball={args.cache}",
+ f"--log={args.log}",
+ f"--image={args.device}",
+ specfile,
+ ],
+ check=True,
+ )
+
+ log("cleanup")
+ shutil.rmtree(tmp)
+
+ log("OK, done")
+
+
+main()
diff --git a/x220.sh b/x220.sh
deleted file mode 100755
index dcb322d..0000000
--- a/x220.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-vi="$1"
-vmdb2="$2"
-
-gitget() {
- local url="$1"
- local branch="$2"
- local dir="$3"
- echo "get $url ($branch)"
- if [ ! -e "$dir" ]; then
- git clone -b "$branch" "$url"
- else
- (cd "$dir" && git checkout "$branch" && git pull)
- fi
-}
-
-git config --global pull.ff only
-gitget git://git.liw.fi/v-i "$vi" v-i
-gitget git://git.liw.fi/vmdb2 "$vmdb2" vmdb2
-gitget git://git.liw.fi/ansibleness main ansibleness
-gitget git://git.liw.fi/debian-ansible main debian-ansible
-
-cd v-i
-export ANSIBLE_LOG=/root/ansible.log
-export ANSIBLE_ROLES_PATH=/root/debian-ansible/roles:/root/ansibleness/ansible/roles
-
-rm -f /root/x220.log
-/root/vmdb2/vmdb2 \
- --verbose \
- --rootfs-tarball /root/rootfs.tar.gz \
- --log /root/x220.log \
- --image /dev/sda \
- x220.vmdb
diff --git a/x220.vmdb b/x220.vmdb
deleted file mode 100644
index 8d48a77..0000000
--- a/x220.vmdb
+++ /dev/null
@@ -1,118 +0,0 @@
-# This is a vmdb2 input file that installs Debian onto my Thinkpad
-# X220. It has an SSD as sdb.
-
-steps:
- - mklabel: gpt
- device: "{{ image }}"
-
- # EFI partition. This MUST be vfat and cleartext so that UEFI BIOS
- # can handle it.
- - mkpart: primary
- device: "{{ image }}"
- start: 0%
- end: 500M
- tag: efi
-
- - mkfs: vfat
- partition: efi
-
- # /boot partition. This will be cleartext, because GRUB doesn't seem
- # to support LUKS2 yet.
- - mkpart: primary
- device: "{{ image }}"
- start: 500M
- end: 1G
- tag: boot
-
- - mkfs: ext2
- partition: boot
-
- # The physical volume for LVM. This will be encrypted and the
- # unlocked, opened variant will be used as the physical volume for
- # LVM2.
- - mkpart: primary
- device: "{{ image }}"
- start: 1G
- end: 100%
- tag: cleartext_pv0
-
- - cryptsetup: cleartext_pv0
- password: asdf
- name: pv0
-
- - vgcreate: vg0
- physical:
- - pv0
-
- - lvcreate: vg0
- name: root
- size: 10G
-
- - mkfs: ext4
- partition: root
-
- # Mount the file systems on top of each other.
- - mount: root
-
- - mount: boot
- dirname: /boot
- mount-on: root
-
- - mount: efi
- dirname: /boot/efi
- mount-on: boot
-
- - virtual-filesystems: root
-
- # Install Debian.
-
- - unpack-rootfs: root
-
- - debootstrap: bullseye
- mirror: http://deb.debian.org/debian
- target: root
- unless: rootfs_unpacked
-
- - apt: install
- packages:
- - linux-image-amd64
- tag: root
- unless: rootfs_unpacked
-
- - cache-rootfs: root
- unless: rootfs_unpacked
-
- # Create fstab and crypttab
- - fstab: root
-
- # Install additional packages. These are not in the rootfs tarball,
- # while I keep changing this list: it's easier and faster to iterate
- # if the rootfs tarball doesn't need to be re-generated from
- # scratch.
- - apt: install
- packages:
- - console-setup
- - cryptsetup
- - cryptsetup-initramfs
- - dosfstools
- - gdm3
- - gnome
- - ifupdown
- - locales-all
- - lvm2
- - psmisc
- - python3
- - ssh
- - strace
- tag: root
-
- # Configure the system with Ansible.
- - ansible: root
- playbook: x220.yml
-
- # Install GRUB as the bootloader.
- - grub: uefi
- tag: root
- efi: efi
- quiet: true
- image-dev: "{{ image }}"
diff --git a/x220.yml b/x220.yml
index e3d8c08..0b33376 100644
--- a/x220.yml
+++ b/x220.yml
@@ -3,10 +3,11 @@
- hosts: image
roles:
- sane_debian_system
-# - comfortable-debian-system
+ - ssd
+ - comfortable-debian-system
- unix_users
# - gnome-system
-# - intel-wifi
+ - intel-wifi
pre_tasks:
@@ -26,7 +27,7 @@
- name: "set root authorized keys"
copy:
content: |
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPQe6lsTapAxiwhhEeE/ixuK+5N8esCsMWoekQqjtxjP liw personal systems
+ {{ liw_personal_ssh_pub }}
dest: /root/.ssh/authorized_keys
owner: root
group: root
@@ -82,4 +83,7 @@
comment: Lars Wirzenius
sudo: yes
authorized_keys: |
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDAlECa3tbFGXhB3Zh/4/GhM11THOThVfiuLqqJ2dpWHEClzpKJHpzzwWt7g9z/MMQNMsUJLy+okz+De6hdjjmYJ9kG9Sr3H4YKq6itGQMj7L/cH3WS3ynp0uy0oW3hf932vDZKQ8iy9vczXH+ERYl+4TYae1Jp4Hyf4/2IYxEfuhKctvSvqySST3Qk9JNZ71HFGOWhjH/MmoCLoT1v+HkqmHdYf/GMKGRo3gqCEGgCgNErYYIyKm3OF3dHXK+hyGLE/cZNu6fU5woW3rvtUCFt08Ri2pm0cnXXJn9jQIMxfS5Kkf64svwgzKmPqgX1f4flopYPlsBXduCgzbJvj+lpgauAk/i1A5B01CFa9sI4C6pHZmwk1qxRwN+4IXL2CQt+tDgYC84ZDDd8R7cNyL22a3KhMQmdHtvog1beAa3Ab+J+cafkXXN+Es9f1wQjzk7DiHupmJIVofBvPP+cRcB46rwha6ati8Fa5QkT9rXFNqQsKk7jq8TIi54Bm15OOa0jInGG3TM17b9Ftu2WTJSAaqgBnDfZiInK7HEvC6K/IBljrN3oGagmFZPrAvzw7d6C2/nKFAQtfoMcE5oWVDrJyjsmJ8oaru0E8rwj7mMvyKPgEMnXTGXLWDgEo50+i291m4bkCxVwiOPbPRvdMll1Y8qfBAPT76sY4Ikgcw/2iw== openpgp:0xBBE80E50
+ {{ liw_personal_ssh_pub }}
+
+ liw_personal_ssh_pub: |
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPQe6lsTapAxiwhhEeE/ixuK+5N8esCsMWoekQqjtxjP liw personal systems