Add Config.Image on container inspect (#41336)

beena352 committed Aug 13, 2026 at 09:59 UTC 933e1b5cb5640ec5ba8504b91971ccf97d8421ab
4 files changed +13 -2
src/windows/inc/wslc_schema.h
+2 -1
@@ -102,6 +102,7 @@ struct HealthConfig
102
103 struct ContainerConfig
104 {
105 + std::string Image;
106 std::optional<std::vector<std::string>> Env;
107 std::optional<std::vector<std::string>> Cmd;
108 std::optional<std::vector<std::string>> Entrypoint;
@@ -111,7 +112,7 @@ struct ContainerConfig
112 std::optional<HealthConfig> Healthcheck;
113 std::map<std::string, std::string> Labels;
114
114 - NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerConfig, Env, Cmd, Entrypoint, User, WorkingDir, StopTimeout, Healthcheck, Labels);
115 + NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ContainerConfig, Image, Env, Cmd, Entrypoint, User, WorkingDir, StopTimeout, Healthcheck, Labels);
116 };
117
118 struct InspectEndpointIPAMConfig
src/windows/wslcsession/WSLCContainer.cpp
+1
@@ -1566,6 +1566,7 @@ WslcInspectContainer WSLCContainerImpl::BuildInspectContainer(const DockerInspec
1566 }
1567 }
1568
1569 + wslcInspect.Config.Image = m_image;
1570 wslcInspect.Config.Env = dockerInspect.Config.Env;
1571 wslcInspect.Config.Cmd = dockerInspect.Config.Cmd;
1572 wslcInspect.Config.Entrypoint = dockerInspect.Config.Entrypoint;
test/windows/WSLCTests.cpp
+8 -1
@@ -10686,6 +10686,7 @@ class WSLCTests
10686 {
10687 // Docker labels do not have a size limit, so test with a very large label value to validate that the API can handle it.
10688 std::map<std::string, std::string> labels = {{"key1", "value1"}, {"key2", std::string(10000, 'a')}};
10689 + const std::string c_image = "debian:latest";
10690
10691 // Contains-style rather than exact-equality so the test stays green if the base image ever ships with its own labels.
10692 auto verifyUserLabelsPresent = [&](const std::map<std::string, std::string>& observed) {
@@ -10702,7 +10703,7 @@ class WSLCTests
10703
10704 // Test valid labels
10705 {
10705 - WSLCContainerLauncher launcher("debian:latest", "test-labels", {"echo", "OK"});
10706 + WSLCContainerLauncher launcher(c_image, "test-labels", {"echo", "OK"});
10707
10708 for (const auto& [key, value] : labels)
10709 {
@@ -10714,6 +10715,10 @@ class WSLCTests
10715 verifyUserLabelsPresent(containerLabels);
10716 VERIFY_IS_TRUE(containerLabels.find("com.microsoft.wsl.container.metadata") == containerLabels.end());
10717
10718 + const auto inspect = container.Inspect();
10719 + VERIFY_ARE_EQUAL(c_image, inspect.Config.Image);
10720 + VERIFY_ARE_EQUAL(inspect.Image, inspect.Config.Image);
10721 +
10722 // Keep the container alive after the handle is dropped so we can validate labels are persisted across sessions.
10723 container.SetDeleteOnClose(false);
10724 }
@@ -10734,6 +10739,8 @@ class WSLCTests
10739 verifyUserLabelsPresent(inspect.Labels);
10740 VERIFY_ARE_EQUAL(inspect.Config.Labels, inspect.Labels);
10741 VERIFY_IS_TRUE(inspect.Config.Labels.find(c_metadataLabel) == inspect.Config.Labels.end());
10742 + VERIFY_ARE_EQUAL(c_image, inspect.Config.Image);
10743 + VERIFY_ARE_EQUAL(inspect.Image, inspect.Config.Image);
10744 }
10745
10746 // Test nullptr key
test/windows/wslc/e2e/WSLCE2EInspectTests.cpp
+2
@@ -160,6 +160,8 @@ class WSLCE2EInspectTests
160 auto json = nlohmann::json::parse(wsl::shared::string::WideToMultiByte(result.Stdout.value()));
161 VERIFY_IS_TRUE(json.is_array() && !json.empty());
162 VERIFY_IS_TRUE(json[0].contains("Config") && json[0]["Config"].contains("Labels"));
163 + VERIFY_IS_TRUE(json[0]["Config"].contains("Image"));
164 + VERIFY_ARE_EQUAL(wsl::shared::string::WideToMultiByte(DebianImage.NameAndTag()), json[0]["Config"]["Image"].get<std::string>());
165 }
166
167 WSLC_TEST_METHOD(WSLCE2E_Inspect_Container_InheritsImageLabels)