@@ -1549,7 +1549,9 @@ int WslaShell(_In_ std::wstring_view commandLine)
15491549 settings.BootTimeoutMs = 30000 ;
15501550 settings.NetworkingMode = WSLANetworkingModeNAT;
15511551 std::wstring containerRootVhd;
1552+ std::string containerImage;
15521553 bool help = false ;
1554+ std::wstring debugShell;
15531555
15541556 ArgumentParser parser (std::wstring{commandLine}, WSL_BINARY_NAME);
15551557 parser.AddArgument (vhd, L" --vhd" );
@@ -1560,6 +1562,8 @@ int WslaShell(_In_ std::wstring_view commandLine)
15601562 parser.AddArgument (Integer (reinterpret_cast <int &>(settings.NetworkingMode )), L" --networking-mode" );
15611563 parser.AddArgument (Utf8String (fsType), L" --fstype" );
15621564 parser.AddArgument (containerRootVhd, L" --container-vhd" );
1565+ parser.AddArgument (Utf8String (containerImage), L" --image" );
1566+ parser.AddArgument (debugShell, L" --debug-shell" );
15631567 parser.AddArgument (help, L" --help" );
15641568 parser.Parse ();
15651569
@@ -1605,18 +1609,28 @@ int WslaShell(_In_ std::wstring_view commandLine)
16051609 wil::com_ptr<IWSLASession> session;
16061610 settings.RootVhd = vhd.c_str ();
16071611 settings.RootVhdType = fsType.c_str ();
1608- THROW_IF_FAILED (userSession->CreateSession (&sessionSettings, &settings, &session));
1609- THROW_IF_FAILED (session->GetVirtualMachine (&virtualMachine));
16101612
1611- wsl::windows::common::security::ConfigureForCOMImpersonation (userSession.get ());
1612-
1613- if (!containerRootVhd.empty ())
1613+ if (!debugShell.empty ())
1614+ {
1615+ THROW_IF_FAILED (userSession->OpenSessionByName (debugShell.c_str (), &session));
1616+ }
1617+ else
16141618 {
1615- wsl::windows::common::WSLAProcessLauncher initProcessLauncher{shell, {shell, " /etc/lsw-init.sh" }};
1616- auto initProcess = initProcessLauncher.Launch (*session);
1617- THROW_HR_IF (E_FAIL, initProcess.WaitAndCaptureOutput ().Code != 0 );
1619+ THROW_IF_FAILED (userSession->CreateSession (&sessionSettings, &settings, &session));
1620+ THROW_IF_FAILED (session->GetVirtualMachine (&virtualMachine));
1621+
1622+ wsl::windows::common::security::ConfigureForCOMImpersonation (userSession.get ());
1623+
1624+ if (!containerRootVhd.empty ())
1625+ {
1626+ wsl::windows::common::WSLAProcessLauncher initProcessLauncher{shell, {shell, " /etc/lsw-init.sh" }};
1627+ auto initProcess = initProcessLauncher.Launch (*session);
1628+ THROW_HR_IF (E_FAIL, initProcess.WaitAndCaptureOutput ().Code != 0 );
1629+ }
16181630 }
16191631
1632+ std::optional<wil::com_ptr<IWSLAContainer>> container;
1633+ std::optional<wsl::windows::common::ClientRunningWSLAProcess> process;
16201634 // Get the terminal size.
16211635 HANDLE Stdout = GetStdHandle (STD_OUTPUT_HANDLE);
16221636 HANDLE Stdin = GetStdHandle (STD_INPUT_HANDLE);
@@ -1631,7 +1645,36 @@ int WslaShell(_In_ std::wstring_view commandLine)
16311645 launcher.AddFd (WSLA_PROCESS_FD{.Fd = 2 , .Type = WSLAFdTypeTerminalControl});
16321646 launcher.SetTtySize (Info.srWindow .Bottom - Info.srWindow .Top + 1 , Info.srWindow .Right - Info.srWindow .Left + 1 );
16331647
1634- auto process = launcher.Launch (*session);
1648+ if (containerImage.empty ())
1649+ {
1650+ wsl::windows::common::WSLAProcessLauncher launcher{shell, {shell}, {" TERM=xterm-256color" }, ProcessFlags::None};
1651+ launcher.AddFd (WSLA_PROCESS_FD{.Fd = 0 , .Type = WSLAFdTypeTerminalInput});
1652+ launcher.AddFd (WSLA_PROCESS_FD{.Fd = 1 , .Type = WSLAFdTypeTerminalOutput});
1653+ launcher.AddFd (WSLA_PROCESS_FD{.Fd = 2 , .Type = WSLAFdTypeTerminalControl});
1654+
1655+ process = launcher.Launch (*session);
1656+ }
1657+ else
1658+ {
1659+ std::vector<WSLA_PROCESS_FD> fds{
1660+ WSLA_PROCESS_FD{.Fd = 0 , .Type = WSLAFdTypeTerminalInput},
1661+ WSLA_PROCESS_FD{.Fd = 1 , .Type = WSLAFdTypeTerminalOutput},
1662+ WSLA_PROCESS_FD{.Fd = 2 , .Type = WSLAFdTypeTerminalControl},
1663+ };
1664+
1665+ WSLA_CONTAINER_OPTIONS containerOptions{};
1666+ containerOptions.Image = containerImage.c_str ();
1667+ containerOptions.Name = " test-container" ;
1668+ containerOptions.InitProcessOptions .Fds = fds.data ();
1669+ containerOptions.InitProcessOptions .FdsCount = static_cast <DWORD>(fds.size ());
1670+
1671+ container.emplace ();
1672+ THROW_IF_FAILED (session->CreateContainer (&containerOptions, &container.value ()));
1673+
1674+ wil::com_ptr<IWSLAProcess> initProcess;
1675+ THROW_IF_FAILED ((*container)->GetInitProcess (&initProcess));
1676+ process.emplace (std::move (initProcess), std::move (fds));
1677+ }
16351678
16361679 // Configure console for interactive usage.
16371680 {
@@ -1658,7 +1701,7 @@ int WslaShell(_In_ std::wstring_view commandLine)
16581701 auto exitEvent = wil::unique_event (wil::EventOptions::ManualReset);
16591702
16601703 wsl::shared::SocketChannel controlChannel{
1661- wil::unique_socket{(SOCKET)process. GetStdHandle (2 ).release ()}, " TerminalControl" , exitEvent.get ()};
1704+ wil::unique_socket{(SOCKET)process-> GetStdHandle (2 ).release ()}, " TerminalControl" , exitEvent.get ()};
16621705
16631706 std::thread inputThread ([&]() {
16641707 auto updateTerminal = [&controlChannel, &Stdout]() {
@@ -1674,7 +1717,7 @@ int WslaShell(_In_ std::wstring_view commandLine)
16741717 controlChannel.SendMessage (message);
16751718 };
16761719
1677- wsl::windows::common::relay::StandardInputRelay (Stdin, process. GetStdHandle (0 ).get (), updateTerminal, exitEvent.get ());
1720+ wsl::windows::common::relay::StandardInputRelay (Stdin, process-> GetStdHandle (0 ).get (), updateTerminal, exitEvent.get ());
16781721 });
16791722
16801723 auto joinThread = wil::scope_exit_log (WI_DIAGNOSTICS_INFO, [&]() {
@@ -1683,12 +1726,12 @@ int WslaShell(_In_ std::wstring_view commandLine)
16831726 });
16841727
16851728 // Relay the contents of the pipe to stdout.
1686- wsl::windows::common::relay::InterruptableRelay (process. GetStdHandle (1 ).get (), Stdout);
1729+ wsl::windows::common::relay::InterruptableRelay (process-> GetStdHandle (1 ).get (), Stdout);
16871730 }
16881731
1689- process. GetExitEvent ().wait ();
1732+ process-> GetExitEvent ().wait ();
16901733
1691- auto [code, signalled] = process. GetExitState ();
1734+ auto [code, signalled] = process-> GetExitState ();
16921735 wprintf (L" %hs exited with: %i%hs" , shell.c_str (), code, signalled ? " (signalled)" : " " );
16931736
16941737 return code;
0 commit comments