Skip to content

Commit

Permalink
virtme-ng: allow to run long commands in graphic mode
Browse files Browse the repository at this point in the history
Use the same syntax to run commands also in graphic mode, for example:

  $ vng -g -- glxgears

This will start glxgears in a graphic session, using the same syntax to
run regular (non-graphic) commands.

Signed-off-by: Andrea Righi <[email protected]>
  • Loading branch information
Andrea Righi committed Nov 7, 2023
1 parent dc14a3a commit 6d65146
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 36 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,23 +219,23 @@ Examples

- Run `glxgears` inside a kernel recompiled in the current directory:
```
$ vng -g glxgears
$ vng -g -- glxgears
(virtme-ng is started in graphical mode)
```

- Execute an `awesome` window manager session with kernel
6.2.0-1003-lowlatency (installed in the system):
```
$ vng -r 6.2.0-1003-lowlatency -g awesome
$ vng -r 6.2.0-1003-lowlatency -g -- awesome
(virtme-ng is started in graphical mode)
```

- Run the `steam` snap (tested in Ubuntu) inside a virtme-ng instance using
the 6.2.0-1003-lowlatency kernel:
```
$ vng -r 6.2.0-1003-lowlatency --snaps --net user -g /snap/bin/steam
$ vng -r 6.2.0-1003-lowlatency --snaps --net user -g -- /snap/bin/steam
(virtme-ng is started in graphical mode)
```
Expand Down
31 changes: 17 additions & 14 deletions virtme/commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -1007,11 +1007,9 @@ def do_it() -> int:
)

def do_script(shellcmd: str, show_boot_console=False) -> None:
if args.graphics is not None:
arg_fail("scripts and --graphics are mutually exclusive")

# Turn off default I/O
qemuargs.extend(arch.qemu_nodisplay_args())
if args.graphics is None:
# Turn off default I/O
qemuargs.extend(arch.qemu_nodisplay_args())

# Configure kernel console output
if show_boot_console:
Expand Down Expand Up @@ -1063,13 +1061,6 @@ def do_script(shellcmd: str, show_boot_console=False) -> None:
# Scripts shouldn't reboot
qemuargs.extend(["-no-reboot"])

# Encode the shell command to base64 to handle special characters (such
# as quotes, double quotes, etc.).
shellcmd = b64encode(shellcmd.encode('utf-8')).decode('utf-8')

# Ask virtme-init to run the script
kernelargs.append(f"virtme.exec=`{shellcmd}`")

# Nasty issue: QEMU will set O_NONBLOCK on fds 0, 1, and 2.
# This isn't inherently bad, but it can cause a problem if
# another process is reading from 1 or writing to 0, which is
Expand All @@ -1087,6 +1078,20 @@ def do_script(shellcmd: str, show_boot_console=False) -> None:
os.dup2(newfd, oldfd)
os.close(newfd)

# Encode the shell command to base64 to handle special characters (such
# as quotes, double quotes, etc.).
shellcmd = b64encode(shellcmd.encode('utf-8')).decode('utf-8')

if args.graphics is not None:
kernelargs.append("virtme_graphics=1")

# Ask virtme-init to run the script
kernelargs.append(f"virtme.exec=`{shellcmd}`")

# Do not break old syntax "-g command"
if args.graphics is not None and args.script_sh is None:
args.script_sh = args.graphics

if args.script_sh is not None:
do_script(args.script_sh, show_boot_console=args.show_boot_console)

Expand All @@ -1100,8 +1105,6 @@ def do_script(shellcmd: str, show_boot_console=False) -> None:
video_args = arch.qemu_display_args()
if video_args:
qemuargs.extend(video_args)
if args.graphics != "":
kernelargs.append("virtme_graphics=%s" % args.graphics)

if args.net:
qemuargs.extend(["-device", "%s,netdev=n0" % arch.virtio_dev_type("net")])
Expand Down
23 changes: 13 additions & 10 deletions virtme/guest/virtme-init
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,17 @@ if [[ -n "${user_cmd}" ]]; then
# Decode shell command (base64) and dump it to a script
echo $user_cmd | base64 -d > /tmp/.virtme-script

# Start the script
log 'starting script'
setsid bash /tmp/.virtme-script </dev/virtio-ports/virtme.stdin >/dev/virtio-ports/virtme.stdout 2>/dev/virtio-ports/virtme.stderr
log "script returned $?"

# Hmm. We should expose the return value somehow.
sync
poweroff -f
exit 0
if [[ ! -n "${virtme_graphics}" ]]; then
# Start the script
log 'starting script'
setsid bash /tmp/.virtme-script </dev/virtio-ports/virtme.stdin >/dev/virtio-ports/virtme.stdout 2>/dev/virtio-ports/virtme.stderr
log "script returned $?"

# Hmm. We should expose the return value somehow.
sync
poweroff -f
exit 0
fi
fi

# Figure out what the main console is
Expand Down Expand Up @@ -330,7 +332,8 @@ if [[ -n "${virtme_graphics}" ]]; then

# Create a .xinitrc to start the requested graphical application.
xinit_rc=/tmp/.xinitrc
echo -e "${pre_exec_cmd}\nexec ${virtme_graphics}" > ${xinit_rc}
echo -e "${pre_exec_cmd}\nexec /tmp/.virtme-script" > ${xinit_rc}
chmod +x /tmp/.virtme-script
if [[ -n "${virtme_user}" ]]; then
chown ${virtme_user}:${virtme_user} $XDG_RUNTIME_DIR
chown ${virtme_user}:${virtme_user} ${xinit_rc}
Expand Down
12 changes: 4 additions & 8 deletions virtme_ng/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,8 @@ def make_parser():
parser.add_argument(
"--graphics",
"-g",
action="store",
nargs="?",
const="",
metavar="BINARY",
help="Show graphical output instead of using a console. "
+ "An argument can be optionally specified to start a graphical application.",
action="store_true",
help="Show graphical output instead of using a console.",
)

parser.add_argument(
Expand Down Expand Up @@ -829,8 +825,8 @@ def _get_virtme_initramfs(self, args):
self.virtme_param["force_initramfs"] = ""

def _get_virtme_graphics(self, args):
if args.graphics is not None:
self.virtme_param["graphics"] = f'--graphics "{args.graphics}"'
if args.graphics:
self.virtme_param["graphics"] = '--graphics'
else:
self.virtme_param["graphics"] = ""

Expand Down
2 changes: 1 addition & 1 deletion virtme_ng_init

0 comments on commit 6d65146

Please sign in to comment.