annotate pi-setup/setup_pi.py @ 279:1cb4aeec8fc6

pi_setup code to prepare a pi for netboot
author drewp@bigasterisk.com
date Sun, 14 Apr 2024 20:54:35 -0700
parents
children 957eb07e06e6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
279
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
1 import asyncio
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
2 import logging
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
3 import re
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
4 import sys
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
5 import time
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
6 from pathlib import Path
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
7 from functools import wraps
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
8 from runner import get_output, iscsi_login, mount, run, sshfs
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
9
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
10 logging.basicConfig(level=logging.INFO, format='%(asctime)s.%(msecs)03d %(levelname)s %(filename) 12s:%(lineno)d %(message)s', datefmt='%H:%M:%S')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
11 log = logging.getLogger()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
12
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
13 WORK = Path('/tmp/pi-setup')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
14 LITE_PREFIX = '2024-03-15-raspios-bookworm'
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
15
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
16 # These come from fdisk -l on the img:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
17 IMG_BOOT_OFFSET = 512 * 8192
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
18 IMG_ROOT_OFFSET = 512 * 1056768
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
19
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
20 TFTP_SPEC = 'root@pipe:/opt/dnsmasq/tftp/'
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
21
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
22
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
23 def step(func):
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
24 name = func.__name__
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
25
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
26 @wraps(func)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
27 async def wrapper(*a, **kw):
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
28 print("", file=sys.stderr)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
29 log.info(f'👣 step {name}')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
30 t1 = time.time()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
31 ret = await func(*a, **kw)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
32 dt = time.time() - t1
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
33 log.info(f' -> step {name} took {dt:3} seconds')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
34 return ret
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
35
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
36 return wrapper
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
37
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
38
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
39 @step
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
40 async def init_work_dir():
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
41 WORK.mkdir(exist_ok=True)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
42 await run(
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
43 'wget', '--continue', '--no-verbose', '-O', WORK / 'raspios.img.xz',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
44 f'https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2024-03-15/{LITE_PREFIX}-arm64-lite.img.xz'
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
45 )
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
46
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
47
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
48 @step
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
49 async def unpack_fresh_img_copy():
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
50 await run('xz', '-dkf', WORK / 'raspios.img.xz')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
51 await run('qemu-img', 'resize', ['-f', 'raw'], WORK / 'raspios.img', '4G')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
52
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
53
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
54 @step
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
55 async def extract_boot_files():
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
56 async with mount(WORK, WORK / 'raspios.img', IMG_BOOT_OFFSET) as img_boot:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
57 await run('cp', img_boot / 'bcm2710-rpi-3-b-plus.dtb', WORK)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
58 await run('cp', img_boot / 'kernel8.img', WORK)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
59
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
60
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
61 @step
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
62 async def setup_ssh_login():
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
63 async with mount(WORK, WORK / 'raspios.img', IMG_ROOT_OFFSET) as img_root:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
64 root_pub_key = Path('/root/.ssh/id_ecdsa.pub').read_text()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
65 (img_root / 'root/.ssh/authorized_keys').write_text(root_pub_key)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
66 # (img_root / 'etc/iscsi/initiatorname.iscsi').write_text(f"InitiatorName=iqn.2024-03.com.bigasterisk:{PI_HOSTNAME}\n")
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
67
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
68 async with mount(WORK, WORK / 'raspios.img', IMG_BOOT_OFFSET) as img_boot:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
69 await run('touch', img_boot / 'ssh')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
70
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
71
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
72 @step
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
73 async def qemu():
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
74 await run(
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
75 'qemu-system-aarch64',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
76 ['-machine', 'raspi3b'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
77 ['-cpu', 'cortex-a72'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
78 ['-nographic'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
79 ['-dtb', WORK / 'bcm2710-rpi-3-b-plus.dtb'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
80 ['-m', '1G'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
81 ['-smp', '4'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
82 ['-kernel', WORK / 'kernel8.img'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
83 ['-sd', WORK / 'raspios.img'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
84 ['-append', "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootdelay=1"],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
85 ['-device', 'usb-net,netdev=net0'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
86 ['-netdev', 'user,id=net0,hostfwd=tcp::2222-:22'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
87 )
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
88
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
89
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
90 @step
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
91 async def setup_pi_in_emulator():
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
92 src_path = Path(__file__).parent / 'on_pi_setup.sh'
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
93 path_on_pi = '/tmp/on_pi_setup.sh'
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
94
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
95 ssh_opts = [
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
96 '-oPort=2222',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
97 '-oConnectTimeout=2',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
98 '-oBatchMode=yes',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
99 '-oNoHostAuthenticationForLocalHost=yes',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
100 ]
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
101 give_up = time.time() + 60
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
102 final_err = ValueError("timed out")
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
103 while time.time() < give_up:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
104 try:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
105 await run('scp', ssh_opts, src_path, f'root@localhost:{path_on_pi}')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
106 except ValueError as err:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
107 final_err = err
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
108 log.info('waiting for qemu to boot...')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
109 await asyncio.sleep(8)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
110 continue
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
111 break
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
112 else:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
113 raise final_err
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
114
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
115 cmd_on_pi = ['sh', path_on_pi, PI_HOSTNAME]
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
116 await run('ssh', ssh_opts, 'root@localhost', *cmd_on_pi)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
117
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
118
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
119 async def _get_iscsi_device(better_be_the_iscsi_device='sde') -> Path:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
120 # don't screw up- this device is about to get formatted!
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
121 dev_path = Path(f'/dev/{better_be_the_iscsi_device}')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
122
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
123 iscsi = await get_output('iscsiadm', '-m', 'session', '-P3')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
124 for m in re.findall(r'Attached scsi disk (\S+)', iscsi):
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
125 if f'/dev/{m}' != str(dev_path):
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
126 raise ValueError(f'surprised by attached iscsi disk {m!r} (try `iscsiadm -m node --logoutall=all`)')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
127
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
128 fdisk = await get_output('fdisk', '-l', dev_path)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
129 for m in re.findall(r'Disk model: (\S+)', fdisk):
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
130 if m != 'VIRTUAL-DISK':
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
131 raise ValueError(f'surprised that {dev_path} is model {m!r} instead of "VIRTUAL-DISK"')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
132
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
133 return dev_path
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
134
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
135
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
136 @step
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
137 async def fs_to_iscsi():
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
138 async with mount(WORK, WORK / 'raspios.img', IMG_ROOT_OFFSET) as img_root:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
139 async with iscsi_login('-m', 'node', '-T', f'iqn.2024-03.com.bigasterisk:{PI_HOSTNAME}.target', '-p', '10.2.0.133'):
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
140 dev = await _get_iscsi_device()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
141 await run('mkfs.ext4', '-F', dev)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
142 async with mount(WORK, dev, 0) as iscsi_root:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
143 await run(
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
144 'rsync',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
145 '-r', # recurs
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
146 '-l', # symlinks as symlinks
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
147 '-p', # perms
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
148 '-t', # mtimes
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
149 '-g', # group
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
150 '-o', # owner
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
151 '-D', # devices + specials
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
152 '-H', # hard links
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
153 ['--exclude', '/boot'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
154 ['--exclude', '/dev'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
155 ['--exclude', '/mnt'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
156 ['--exclude', '/proc'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
157 ['--exclude', '/sys'],
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
158 str(img_root) + '/',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
159 str(iscsi_root) + '/',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
160 )
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
161 for d in [
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
162 'boot',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
163 'dev',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
164 'mnt',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
165 'proc',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
166 'sys',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
167 ]:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
168 (iscsi_root / d).mkdir()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
169 (iscsi_root / 'etc/fstab').write_text('''
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
170 proc /proc proc defaults 0 0
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
171 /dev/sda / ext4 defaults,noatime 0 1
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
172 ''')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
173 # don't open cursesui for making first user
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
174 (iscsi_root / 'etc/systemd/system/multi-user.target.wants/userconfig.service').unlink()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
175 log.info("there may be a delay here for flushing all the new files")
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
176
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
177
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
178 @step
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
179 async def setup_tftp():
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
180 async with sshfs(WORK, TFTP_SPEC) as tftp:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
181 tftp_host_dir = tftp / f'{PI_HOSTNAME}-boot'
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
182 async with mount(WORK, WORK / 'raspios.img', IMG_ROOT_OFFSET) as img_root:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
183 await run(
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
184 'rsync',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
185 '-r', # recurs
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
186 '-l', # symlinks as symlinks
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
187 '-p', # perms
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
188 #'-t', # mtimes
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
189 '-g', # group
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
190 '-o', # owner
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
191 '-D', # devices + specials
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
192 #'-H', # hard links
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
193 '--delete',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
194 str(img_root) + '/boot/',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
195 str(tftp_host_dir) + '/',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
196 )
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
197 async with mount(WORK, WORK / 'raspios.img', IMG_BOOT_OFFSET) as img_boot:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
198 await run(
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
199 'rsync',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
200 '-r', # recurs
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
201 '-l', # symlinks as symlinks
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
202 '-p', # perms
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
203 '-t', # mtimes
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
204 '-g', # group
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
205 '-o', # owner
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
206 '-D', # devices + specials
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
207 '-H', # hard links
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
208 # (no delete)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
209 str(img_boot) + '/',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
210 str(tftp_host_dir) + '/firmware/',
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
211 )
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
212 await run('ln', '-sf', f'{PI_HOSTNAME}-boot/firmware/', str(tftp / PI_SERIAL))
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
213 kernel_cmdline = [
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
214 "console=serial0,115200",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
215 "console=tty1",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
216 f"ip=::::{PI_HOSTNAME}:eth0:dhcp",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
217 "root=/dev/sda",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
218 f"ISCSI_INITIATOR=iqn.2024-03.com.bigasterisk:{PI_HOSTNAME}.initiator",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
219 f"ISCSI_TARGET_NAME=iqn.2024-03.com.bigasterisk:{PI_HOSTNAME}.target",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
220 "ISCSI_TARGET_IP=10.2.0.133",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
221 "ISCSI_TARGET_PORT=3260",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
222 "rw",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
223 "rootfstype=ext4",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
224 "fsck.repair=yes",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
225 "rootwait",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
226 "cgroup_enable=cpuset",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
227 "cgroup_memory=1",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
228 "cgroup_enable=memory",
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
229 ]
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
230 (tftp_host_dir/'firmware/cmdline.txt').write_text(' '.join(kernel_cmdline))
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
231
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
232
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
233 async def main():
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
234 global PI_HOSTNAME, PI_SERIAL
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
235
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
236 if sys.argv[1:] == ['--init']:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
237 await init_work_dir()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
238 else:
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
239 PI_HOSTNAME, PI_SERIAL = sys.argv[1:]
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
240 # todo: dd and add iscsi volume (handled by pyinfra)
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
241 # dd if=/dev/zero of={out} count=0 bs=1 seek=5G conv=excl || true
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
242 # edit /etc/tgt/conf.d/{pi_hostname}.conf etc
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
243
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
244 await unpack_fresh_img_copy()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
245 await extract_boot_files()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
246 await setup_ssh_login()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
247
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
248 qemu_task = asyncio.create_task(qemu())
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
249 await asyncio.sleep(20) # inital qemu startup delay
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
250 await setup_pi_in_emulator() # finishes with a poweroff
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
251 log.info('waiting for qemu to exit')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
252 await qemu_task
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
253
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
254 await fs_to_iscsi()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
255 await setup_tftp()
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
256
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
257 log.info(f'🎉 {PI_HOSTNAME} is ready for net boot')
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
258
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
259
1cb4aeec8fc6 pi_setup code to prepare a pi for netboot
drewp@bigasterisk.com
parents:
diff changeset
260 asyncio.run(main())