Skip to content

Commit dbed89b

Browse files
committed
vsock: connect: generate helper script
Directly connecting to the remote shell using socat launching 'bash' remotely doesn't give a nice user experience: env vars like $HOME are not propagated, the terminal size is set to 80x24, the command that is typed is not visible, the directory is not the one picked with --cwd, etc. To give a better user experience, the '--vsock-connect' option is now creating a script that is setting up the missing pieces. This script is executed when the VM is launched with '--vsock' without any arguments. Note that it is required to pass info from the host, when launching '--vsock-connect', to the VM, e.g. for the terminal size. This is done via the script that is executed once connected to the vsock inside the VM. The VM needs access to this script, and the host needs to be able to modify it. Such script is then created in /tmp/virtme-vsock/<CID>.sh on both the host and the VM. If the whole filesystem is mounted (default), this file will be accessible from the VM. If not, a mount point will be added to access the parent directory from the VM. Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
1 parent 7b3096d commit dbed89b

File tree

5 files changed

+63
-26
lines changed

5 files changed

+63
-26
lines changed

README.md

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -354,24 +354,6 @@ Examples
354354
$ vng --vsock-connect
355355
```
356356

357-
- Connect to a remote shell with proper dimensions, env vars, and using 'Fish':
358-
```
359-
# Start the vng instance with vsock support:
360-
$ vng --vsock "${PWD}/console.sh"
361-
362-
# In a separate terminal run the following commands:
363-
$ read -r rows columns <<< "$(stty size)"
364-
$ cat <<-EOF > console.sh
365-
#! /bin/bash
366-
stty rows ${rows} columns ${columns}
367-
cd "\${virtme_chdir}"
368-
HOME=${HOME}
369-
fish # use use zsh, tmux, byobu, screen, etc.
370-
EOF
371-
$ chmod +x console.sh
372-
$ vng --vsock-connect
373-
```
374-
375357
- Run virtme-ng inside a docker container:
376358
```
377359
$ docker run -it --privileged ubuntu:23.10 /bin/bash

virtme/commands/run.py

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,16 @@ def make_parser() -> argparse.ArgumentParser:
133133
g.add_argument(
134134
"--vsock",
135135
action="store",
136-
default=None,
137-
help="Enable a VSock to communicate from the host to the device and "
138-
+ "execute the specified command.",
136+
nargs="?",
137+
metavar="COMMAND",
138+
const="",
139+
help="Enable a VSock to communicate from the host to the device. "
140+
+ "An argument can be optionally specify to start a different command.",
139141
)
140142
g.add_argument(
141143
"--vsock-cid",
142144
action="store",
145+
metavar="CID",
143146
type=int,
144147
default=3,
145148
help="CID for the VSock.",
@@ -866,7 +869,27 @@ def is_subpath(path, potential_parent):
866869
def do_it() -> int:
867870
args = _ARGPARSER.parse_args()
868871

872+
vsock_script_path = os.path.join(tempfile.gettempdir(), "virtme-vsock",
873+
f"{args.vsock_cid}.sh")
874+
869875
if args.vsock_connect:
876+
# Note: we could accept arguments passed to --vsock-connect to run a
877+
# specific command, and return, without requiring an interactive tty.
878+
try:
879+
(cols, rows) = os.get_terminal_size()
880+
except OSError:
881+
cols, rows = (80, 24)
882+
883+
with open(vsock_script_path, 'w', encoding="utf-8") as file:
884+
print((
885+
'#! /bin/bash\n'
886+
f'stty rows {rows} cols {cols} iutf8 echo\n'
887+
'HOME=$(getent passwd ${virtme_user:-root} | cut -d: -f6)\n'
888+
'cd ${virtme_chdir:+"${virtme_chdir}"}\n'
889+
'exec su ${virtme_user:-root}'
890+
), file=file)
891+
os.chmod(vsock_script_path, 0o755)
892+
870893
tty = os.ttyname(sys.stdin.fileno())
871894
command = ['socat', f'file:{tty},raw,echo=0',
872895
f'VSOCK-CONNECT:{args.vsock_cid}:1024']
@@ -1409,8 +1432,34 @@ def get_net_mac(index):
14091432
]
14101433
)
14111434

1412-
if args.vsock:
1413-
kernelargs.extend([f"virtme.vsockexec=`{args.vsock}`"])
1435+
def cleanup_vsock_script():
1436+
os.unlink(vsock_script_path)
1437+
1438+
if args.vsock is not None:
1439+
if os.path.exists(vsock_script_path):
1440+
arg_fail("vsock: '%s' file exists: " % vsock_script_path
1441+
+ "another VM is running with the same --vsock-cid? "
1442+
+ "If not, remove this file.")
1443+
1444+
# create an empty file that can be populated later on
1445+
vsock_script_dir = os.path.dirname(vsock_script_path)
1446+
os.makedirs(vsock_script_dir, exist_ok=True)
1447+
open(vsock_script_path, 'w', encoding="utf-8").close()
1448+
atexit.register(cleanup_vsock_script)
1449+
1450+
if args.vsock:
1451+
vsock_exec = args.vsock
1452+
else:
1453+
vsock_exec = vsock_script_path
1454+
if args.root != "/":
1455+
virtfs_config = VirtFSConfig(
1456+
path=vsock_script_dir,
1457+
mount_tag="virtme.vsockmount",
1458+
)
1459+
export_virtfs(qemu, arch, qemuargs, virtfs_config)
1460+
kernelargs.append("virtme_vsockmount=%s" % vsock_script_dir)
1461+
1462+
kernelargs.extend([f"virtme.vsockexec=`{vsock_exec}`"])
14141463
qemuargs.extend(["-device", "vhost-vsock-pci,guest-cid=%d" % args.vsock_cid])
14151464

14161465
if args.pwd:

virtme/guest/virtme-init

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ fi
277277

278278
vsock_exec=$(sed -ne "s/.*virtme.vsockexec=\`\(.*\)\`.*/\1/p" /proc/cmdline)
279279
if [[ -n "${vsock_exec}" ]]; then
280+
if [[ -n "${virtme_vsockmount}" ]]; then
281+
mkdir -p "${virtme_vsockmount}"
282+
mount -t 9p -o version=9p2000.L,trans=virtio,access=any "virtme.vsockmount" "${virtme_vsockmount}"
283+
fi
280284
socat "VSOCK-LISTEN:1024,reuseaddr,fork" \
281285
"EXEC:\"${vsock_exec}\",pty,stderr,setsid,sigint,sane,echo=0" &
282286
fi

virtme_ng/run.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,15 +362,17 @@ def make_parser():
362362
parser.add_argument(
363363
"--vsock",
364364
action="store",
365-
const="bash -i",
366365
nargs="?",
366+
metavar="COMMAND",
367+
const="",
367368
help="Enable a VSock to communicate from the host to the device. "
368-
+ "An argument can be optionally specify to start a different shell.",
369+
+ "An argument can be optionally specify to start a different command.",
369370
)
370371

371372
parser.add_argument(
372373
"--vsock-cid",
373374
action="store",
375+
metavar="CID",
374376
type=int,
375377
help="CID for the VSock.",
376378
)

virtme_ng_init

0 commit comments

Comments
 (0)