Skip to content

Commit

Permalink
Merge pull request #26 from arkane-systems/dev-0.11
Browse files Browse the repository at this point in the history
Dev 0.11
  • Loading branch information
cerebrate authored Oct 31, 2022
2 parents c27a176 + 8683985 commit 0937452
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#

# Bottle-Imp version
IMPVERSION = 0.10
IMPVERSION = 0.11

# Determine this makefile's path.
# Be sure to place this BEFORE `include` directives, if any.
Expand Down
2 changes: 1 addition & 1 deletion PKGBUILD
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Maintainer: Alistair Young <avatar@arkane-systems.net>
pkgname=bottle-imp
pkgver=0.10
pkgver=0.11
pkgrel=1
pkgdesc="A helper for WSL's native systemd support."
arch=('x86_64')
Expand Down
40 changes: 36 additions & 4 deletions binsrc/imp/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import helpers

# Global variables
version = "0.10"
version = "0.11"

verbose = False
login = None
Expand Down Expand Up @@ -47,6 +47,8 @@ def parse_command_line():
help='open a login prompt for a systemd user session')
group.add_argument(
'-c', '--command', help='open or connect to a systemd user session, and run the specified command in it\n(preserves working directory)', nargs=argparse.REMAINDER)
group.add_argument('-u', '--shutdown', action='store_true',
help='shut down systemd and the WSL instance')

return parser.parse_args()

Expand Down Expand Up @@ -113,7 +115,8 @@ def do_initialize():
wait_for_systemd()

# Update the base environment with interop-fu.
subprocess.run(['systemctl', 'import-environment', 'WSL_INTEROP'])
subprocess.run(['systemctl', 'import-environment',
'WSL_INTEROP', 'WSL2_GUI_APPS_ENABLED', 'WSL_DISTRO_NAME', 'WSLENV', 'NAME', 'HOSTTYPE'])

# Run wait-forever subprocess.
subprocess.Popen(['/usr/lib/bottle-imp/wait-forever.sh'],
Expand All @@ -128,6 +131,7 @@ def do_initialize():
# Exit
sys.exit(0)


def do_login():
"""Start a systemd login prompt."""
wait_for_systemd()
Expand All @@ -141,6 +145,7 @@ def do_login():
os.execv ('/usr/bin/machinectl', ['machinectl', 'login', '.host'])
# never get here


def do_shell():
"""Start/connect to a systemd user session with a shell."""
wait_for_systemd()
Expand All @@ -151,9 +156,17 @@ def do_shell():
if verbose:
print("imp: starting shell")

os.execv ('/usr/bin/machinectl', ['machinectl', 'shell', '-q', login + '@.host'])
if helpers.get_in_windows_terminal():
os.execv ('/usr/bin/machinectl', ['machinectl',
'-E', 'WT_SESSION', '-E', 'WT_PROFILE_ID',
'shell', '-q', login + '@.host'])
else:
os.execv ('/usr/bin/machinectl', ['machinectl',
'shell', '-q', login + '@.host'])

# never get here


def do_command(commandline):
"""Start/connect to a systemd user session with a command."""
wait_for_systemd()
Expand All @@ -167,10 +180,27 @@ def do_command(commandline):
if len(commandline) == 0:
sys.exit("imp: no command specified")

command = ['machinectl', 'shell', '-q', login + '@.host', '/usr/bin/env', '-C', os.getcwd()] + commandline;
if helpers.get_in_windows_terminal():
command = ['machinectl',
'-E', 'WT_SESSION', '-E', 'WT_PROFILE_ID',
'shell', '-q', login + '@.host', '/usr/bin/env', '-C', os.getcwd()] + commandline;
else:
command = ['machinectl',
'shell', '-q', login + '@.host', '/usr/bin/env', '-C', os.getcwd()] + commandline;

os.execv ('/usr/bin/machinectl', command)


def do_shutdown():
"""Shut down systemd and the WSL instance."""
wait_for_systemd()

if verbose:
print ("imp: shutting down WSL instance")

os.execv('/usr/bin/systemctl', ['systemctl', 'poweroff'])


# Entrypoint
def entrypoint():
"""Entrypoint of the application."""
Expand Down Expand Up @@ -207,6 +237,8 @@ def entrypoint():
do_shell()
elif arguments.login:
do_login()
elif arguments.shutdown:
do_shutdown()
elif arguments.command is not None:
do_command(arguments.command)
else:
Expand Down
9 changes: 9 additions & 0 deletions binsrc/imp/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
import psutil
import pwd


def get_in_windows_terminal():
"""Are we inside a Windows Terminal session?"""
if 'WT_SESSION' in os.environ:
return True
else:
return False


def get_login_session_user():
"""Get the user logged into the current session, pre-setuid."""
# This environment variable is set by the setuid wrapper.
Expand Down
9 changes: 9 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
bottle-imp (0.11) buster bullseye bookworm sid focal jammy; urgency=medium

* Added various environment variables to the passthrough list.
* Pass through Windows Terminal variables on shell/command.
* Add shutdown helper command.
* Added bugs section to documentation.

-- Alistair Young <avatar@arkane-systems.net> Sat, 29 Oct 2022 19:00:01 -0500

bottle-imp (0.10) buster bullseye bookworm sid focal jammy; urgency=medium

* Added fix for /dev/shm / /run/shm inversion.
Expand Down
16 changes: 16 additions & 0 deletions othersrc/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ commands:
-l, --login open a login prompt for a systemd user session
-c ..., --command ...
open or connect to a systemd user session, and run the specified command within it (preserves working directory)
-u, --shutdown shut down systemd and the WSL instance
For more information, see https://github.com/arkane-systems/bottle-imp/
```
Expand All @@ -118,3 +119,18 @@ _imp -c [command]_ runs _command_ inside a _systemd_ login session, then exits.
With either of the above, the _imp -a [user]_ option may be used to specify a particular user to start a shell for, or to run a command as, rather than using the currently logged-in user. For example, _imp -a bongo -s_ would start a shell as the user _bongo_.

_imp -l_ opens a login prompt. This permits you to log in to the WSL distribution via _systemd_ as any user. The login prompt will return when you log out; to terminate the session, press `^]` three times within one second. It follows _login_ semantics, and as such does not preserve the current working directory.

_imp -u_ will shut down _systemd_ cleanly and exit the WSL instance. This uses the _systemctl poweroff_ command to
simulate a normal Linux system shutting down. It is suggested that this be used before shutting down the Windows machine or force-terminating WSL to ensure a clean shutdown of _systemd_ services.

Shutting down the WSL instance in this way causes it to exit completely. You should wait for the instance to show as stopped before attempting to restart it or execute further commands inside it.

## BUGS

1. Using _imp_ to create a session is required for the user login session (and its concomitants, such as a user _systemd_ instance and a session dbus) to be created properly. Simply starting a process with _wsl_ (or using a Linux GUI app shortcut) does not do this, although the problem is less serious than with _genie_, since the process will still be started with _systemd_ as pid 1.

For information about starting Visual Studio Code remote sessions in login sessions, see https://github.com/arkane-systems/bottle-imp/discussions/19 .

2. While the Windows Terminal environment variables, WT_SESSION and WT_PROFILE_ID, will be passed through to shell and command prompt invocations of _imp_, they will not be passed through to login sessions created with _imp -l_, due to a limitation in _machinectl_.

3. _imp_ requires the python package _psutil_, which due to technical limitations of _zipapp_ can't be wrapped into the _imp_ executable. As such, _imp_ depends on this package for the system _python_. If you are inside another python environment, _imp_ may fail unless you install the _psutil_ package into this environment also.
53 changes: 53 additions & 0 deletions othersrc/docs/imp.8
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
.Op -i
.Op -s
.Op -l
.Op -u
.Op -c
.Ar command...
.Sh DESCRIPTION
Expand Down Expand Up @@ -64,6 +65,21 @@ distribution with
installed.
.Pp
Unlike the other options, this preserves the current working directory.
.It Fl u, -shutdown
Shuts down
.Xr systemd 1
cleanly and exits the WSL instance. This uses the
.Ar systemctl poweroff
command to simulate a normal Linux system shutting down. It is suggested that
this be used before shutting down the Windows machine or force-terminating WSL
to ensure a clean shutdown of
.Xr systemd 1
services.
.Pp
Shutting down the WSL instance in this way causes it to exit
.Ar completely.
You should wait for the instance to show as stopped before attempting to restart it
or execute further commands inside it.
.El
.Sh EXIT STATUS
.Nm
Expand All @@ -86,6 +102,43 @@ undefined.
.Xr bootup 7 ,
.Xr systemd-machined 8 ,
.Sh BUGS
1. Using
.Nm
to create a session is required for the user login session (and its concomitants, such as a user
.Xr systemd 1
instance and a session dbus) to be created properly. Simply starting a process with
.Ar wsl
(or using a Linux GUI app shortcut) does not do this, although the problem is less serious than with
.Ar genie
, since the process will still be started with
.Xr systemd 1
as pid 1.
.Pp
2. While the Windows Terminal environment variables, WT_SESSION and WT_PROFILE_ID, will be passed
through to shell and command prompt invocations of
.Nm
, they will not be passed through to login sessions created with
.Ar imp -l
, due to a limitation in
.Xr machinectl 1
.
.Pp
3.
.Nm
requires the Python package
.Ar psutil
, which due to technical limitations of
.Ar zipapp
can't be wrapped into the
.Nm
executable. As such,
.Nm
depends on this package for the system Python. If you are inside another Python environment,
.Nm
may fail unless you install the
.Ar psutil
package into this environment also.
.Pp
If you feel you have found a bug in
.Nm
please submit a bug report at
Expand Down

0 comments on commit 0937452

Please sign in to comment.