stages: add debug shell

This gives shell access into the image on a given tty. Useful for
testing and debugging, while minimally affecting the image.

Note that this must never be used in production, as it allows root
access without a password.

For instance this could be used to verify that an image was fully
booted:

```
[teg@teg-x270 osbuild]$ qemu-kvm -m 1024 -nographic -serial mon:stdio -snapshot  base.qcow2
sh-5.0# systemctl is-system-running --wait
running
```

Signed-off-by: Tom Gundersen <teg@jklm.no>
This commit is contained in:
Tom Gundersen 2019-08-27 14:06:06 +02:00 committed by Lars Karlitski
parent 53fe311bcd
commit a914627c89
2 changed files with 56 additions and 1 deletions

View file

@ -50,7 +50,13 @@
"name": "org.osbuild.grub2",
"options": {
"root_fs_uuid": "76a22bf4-f153-4541-b6c7-0332c0dfaeac",
"kernel_opts": "ro biosdevname=0 net.ifnames=0 console=ttyS0,115200"
"kernel_opts": "ro biosdevname=0 net.ifnames=0"
}
},
{
"name": "org.osbuild.debug-shell",
"options": {
"tty": "/dev/ttyS0"
}
},
{

49
stages/org.osbuild.debug-shell Executable file
View file

@ -0,0 +1,49 @@
#!/usr/bin/python3
import json
import os
import sys
def main(tree, options):
tty = options["tty"]
unit = f"""
[Unit]
Description=Early root shell on {tty} FOR DEBUGGING ONLY
DefaultDependencies=no
IgnoreOnIsolate=yes
ConditionPathExists={tty}
[Service]
Environment=TERM=linux
ExecStart=/bin/sh
Restart=always
RestartSec=0
StandardInput=tty
TTYPath={tty}
TTYReset=yes
TTYVHangup=yes
KillMode=process
IgnoreSIGPIPE=no
# bash ignores SIGTERM
KillSignal=SIGHUP
# Unset locale for the console getty since the console has problems
# displaying some internationalized messages.
UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION
"""
with open(f"{tree}/etc/systemd/system/osbuild-debug-shell.service", "w") as f:
f.write(unit)
os.symlink("../osbuild-debug-shell.service",
f"{tree}/etc/systemd/system/sysinit.target.wants/osbuild-debug-shell.service")
return 0
if __name__ == '__main__':
args = json.load(sys.stdin)
r = main(args["tree"], args["options"])
sys.exit(r)