Skip to content

do not merge: wslc compose POC - #41378

Draft
Blue (OneBlue) wants to merge 11 commits into
masterfrom
user/oneblue/compose
Draft

do not merge: wslc compose POC#41378
Blue (OneBlue) wants to merge 11 commits into
masterfrom
user/oneblue/compose

Conversation

@OneBlue

Copy link
Copy Markdown
Collaborator

Summary of the Pull Request

This change is a very simplified implementation for wslc compose. With this, a simple compose.yml file like this runs successfully:

services:
  photoprism:
    image: photoprism/photoprism:latest
    ports:
      - "2342:2342"
    environment:
      PHOTOPRISM_ADMIN_USER: "admin"                 # admin login username
      PHOTOPRISM_ADMIN_PASSWORD: "insecure"          # initial admin password (8-72 characters)
      PHOTOPRISM_AUTH_MODE: "password"               # authentication mode (public, password)
      PHOTOPRISM_DATABASE_DRIVER: "mysql"            # MariaDB 10.5.12+ (MySQL successor) offers significantly better performance compared to SQLite
      PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"     # MariaDB database server (hostname:port)
      PHOTOPRISM_DATABASE_NAME: "photoprism"         # MariaDB database, see MARIADB_DATABASE in the mariadb service
      PHOTOPRISM_DATABASE_USER: "photoprism"         # MariaDB database username, must be the same as MARIADB_USER
      PHOTOPRISM_DATABASE_PASSWORD: "sample-password"       # MariaDB database password, must be the same as MARIADB_PASSWORD
    working_dir: "/photoprism"  
  mariadb:
    image: mariadb:12.3
    environment:
      MARIADB_AUTO_UPGRADE: "1"
      MARIADB_DATABASE: "photoprism"
      MARIADB_USER: "photoprism"
      MARIADB_PASSWORD: "sample-password"
      MARIADB_ROOT_PASSWORD: "sample-password"

PR Checklist

  • Closes: Link to issue #xxx
  • Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
  • Tests: Added/updated if needed and all pass
  • Localization: All end user facing strings can be localized
  • Dev docs: Added/updated if needed
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

Validation Steps Performed

Copilot AI lite review requested due to automatic review settings August 19, 2026 00:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a proof-of-concept wslc compose command and a minimal backing service-side compose session object, along with tests and supporting plumbing (session helpers, CLI wiring, and MSI/IDL updates).

Changes:

  • Add a new compose command tree (create/up/start/attach/stop) and a CLI service implementation to drive compose sessions.
  • Add an IWSLCComposeSession COM interface plus a minimal WSLCComposeSession implementation and IWSLCSession::CreateComposeSession.
  • Add new Windows tests for compose, and refactor shared WSLC test helpers into test/windows/Common.*.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/windows/WSLCTests.cpp Refactors session/image setup to shared test helpers.
test/windows/WSLCComposeTests.cpp Adds new TAEF tests covering compose session lifecycle and container name networking.
test/windows/wslc/WSLCCLICommandUnitTests.cpp Adds a unit test verifying the compose subcommand tree.
test/windows/Common.h Declares new shared WSLC test helper APIs in wsl::test.
test/windows/Common.cpp Implements shared WSLC test helpers (session creation, default settings, load images).
test/windows/CMakeLists.txt Adds WSLCComposeTests.cpp to the Windows test build.
src/windows/wslcsession/WSLCSession.h Adds compose session entry points and supporting internals to WSLCSession.
src/windows/wslcsession/WSLCSession.cpp Implements CreateComposeSession and compose container creation; refactors pull-image internals.
src/windows/wslcsession/WSLCComposeSession.h Introduces the COM class implementing IWSLCComposeSession.
src/windows/wslcsession/WSLCComposeSession.cpp Implements the minimal compose session methods (list/start/stop; attach stubbed).
src/windows/wslcsession/CMakeLists.txt Adds new sources/headers and links yaml-cpp for compose parsing support.
src/windows/wslc/services/ConsoleService.h Adds an overload to relay non-tty output to provided handles.
src/windows/wslc/services/ConsoleService.cpp Implements the new overload and makes stdout/stderr relays conditional.
src/windows/wslc/services/ComposeService.h Adds a CLI-side compose service wrapper.
src/windows/wslc/services/ComposeService.cpp Implements CLI-side compose operations (create/up/start/attach/stop).
src/windows/wslc/commands/RootCommand.cpp Registers compose under the root command.
src/windows/wslc/commands/ComposeCommand.h Declares the compose command hierarchy.
src/windows/wslc/commands/ComposeCommand.cpp Implements compose commands and argument plumbing.
src/windows/service/inc/wslc.idl Adds IWSLCComposeSession and IWSLCSession::CreateComposeSession.
src/windows/common/WSLCContainerLauncher.h Exposes reusable option-storage creation for container launchers.
src/windows/common/WSLCContainerLauncher.cpp Refactors container option building into CreateOptions() to preserve pointer lifetimes.
msipackage/package.wix.in Registers the new compose session interface IID.
localization/strings/en-US/Resources.resw Adds localized strings for compose command help/args and an invalid-file error message.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 10 to 16
# Session and container implementation
ComposeSpec.cpp
ServiceContainerLauncher.cpp
WSLCSession.cpp
WSLCSessionRuntime.cpp
WSLCComposeSession.cpp
WSLCContainer.cpp
Comment on lines +46 to +49
int ComposeService::Attach(Terminal& Terminal, models::Session& Session, const std::wstring& Path)
{
[[maybe_unused]] auto operation = Session.BeginContainerOperation();
auto composeSession = Open(Session, Path);
Comment on lines +101 to +105
HRESULT WSLCComposeSession::Attach()
{
// TODO
return S_OK;
}
Comment on lines +144 to +145
VERIFY_SUCCEEDED(composeSession->Attach());
VERIFY_SUCCEEDED(composeSession->Stop(10));
Copilot AI review requested due to automatic review settings August 19, 2026 17:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 1 comment.

Suppressed comments (3)

src/windows/wslcsession/ComposeSpec.cpp:223

  • YAML::LoadFile is called with Path.string(), which can corrupt non-ASCII/Unicode Windows paths (and fail to open the compose file). Use an explicit UTF-8 conversion for the filesystem path before passing it to yaml-cpp.
    ComposeSpec ParseComposeFile(const std::filesystem::path& Path)
    {
        const auto root = YAML::LoadFile(Path.string());
        const auto services = root["services"];
        if (!services || !services.IsMap() || services.size() == 0)
        {
            ThrowInvalidComposeFile(Path, L"the file must contain a non-empty services map");
        }

src/windows/wslcsession/ComposeSpec.cpp:358

  • ComposeSpec::Parse can reach the end of a non-void function without an explicit return, which can trigger build warnings (and some toolchains treat it as an error) even though ThrowInvalidComposeFile is [[noreturn]]. Add an explicit unreachable/return after the catch to make control-flow obvious to the compiler.
ComposeSpec ComposeSpec::Parse(const std::filesystem::path& Path)
{
    try
    {
        return ParseComposeFile(Path);
    }
    catch (const YAML::Exception& exception)
    {
        ThrowInvalidComposeFile(Path, wsl::shared::string::MultiByteToWide(exception.what()));
    }
}

src/windows/wslc/services/ComposeService.cpp:80

  • ComposeService::Attach unconditionally adds relay handles for stdout/stderr even if the container attach call returned null/invalid handles. ConsoleService::RelayNonTtyProcess was updated to guard against missing stdout/stderr, so this path should do the same to avoid relaying from invalid handles.
        THROW_IF_FAILED(container->Attach(nullptr, &stdinHandle, &stdoutHandle, &stderrHandle));

        // TODO: Add support for stdin, tty processes, stop on ctrl-c.

        io.AddHandle(std::make_unique<wsl::windows::common::io::RelayHandle<wsl::windows::common::io::ReadHandle>>(
            stdoutHandle.Release(), GetStdHandle(STD_OUTPUT_HANDLE)));

        io.AddHandle(std::make_unique<wsl::windows::common::io::RelayHandle<wsl::windows::common::io::ReadHandle>>(
            stderrHandle.Release(), GetStdHandle(STD_ERROR_HANDLE)));
    }

Comment on lines +2306 to +2321
std::string networkName = Spec.ProjectName + "_default"; // TODO: Implement this properly.

// Create a network for the compose session.
// TODO: open an existing network instead of deleting.

auto networkCleanup = DeleteNetworkImpl(networkName.c_str());
THROW_HR_IF_MSG(
networkCleanup,
FAILED(networkCleanup) && networkCleanup != WSLC_E_NETWORK_NOT_FOUND,
"Failed to delete network %hs",
networkName.c_str());

WSLCNetworkOptions networkOptions{};
networkOptions.Name = networkName.c_str();
THROW_IF_FAILED(CreateNetworkImpl(&networkOptions));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants