diff --git a/README.md b/README.md index 001bf25..f37ac51 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,8 @@ When expanding YAML, ComposeSharp uses the process environment first and then th `ComposeProjectContext.Profiles` selects services consistently for project loading and operations that load the Compose file. Services without `profiles` are always selected; a profiled service is selected when any of its profiles is active. An operation that explicitly names a service can select it even when its profile is not active. +The loader can retain fields that the engine does not yet apply. Consult the [Compose field support matrix](docs/compose-field-matrix.md) before relying on a Compose property at runtime. + ## What the engine does today | Area | Current behavior | @@ -139,7 +141,7 @@ The roadmap is organized around implementation honesty rather than pretending ev 2. **2.2 — Docker Engine coverage.** Replace process-backed build/copy/export/commit paths, implement real `top`, Docker event streaming, and meaningful project generation/publishing behavior. 3. **3.0 — dependable orchestration.** Dependency ordering and readiness, safer reconciliation, richer diagnostics, and integration coverage across Linux and Windows Docker environments. -Details, acceptance criteria, and non-goals live in [docs/roadmap.md](docs/roadmap.md). Work is tracked in [GitHub milestones](https://github.com/GaTTGeng/ComposeSharp/milestones). +Details, acceptance criteria, and non-goals live in [docs/roadmap.md](docs/roadmap.md). The [Compose field support matrix](docs/compose-field-matrix.md) records parsed versus applied behavior. Work is tracked in [GitHub milestones](https://github.com/GaTTGeng/ComposeSharp/milestones). ## Build the repository diff --git a/README.zh-CN.md b/README.zh-CN.md index 4afbbda..36d66af 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -92,6 +92,7 @@ builder.Services.AddComposeSharp(); - `PublishAsync` 只为服务镜像打 tag,不会把镜像推送到 registry。 - `LoadMerged` 按字段逐步合并后置文件:标量由后置值覆盖,映射递归合并,列表追加;服务资源、`command` 和 `entrypoint` 有明确的替换规则。它仍不是 Docker Compose 的完整合并算法;精确规则和不支持的 YAML 标签见[合并语义](docs/merge-semantics.md)。 - `ComposeProjectContext.Profiles` 会在加载项目以及加载 Compose 文件的操作中统一选择服务:未配置 `profiles` 的服务始终会被选择;配置了 profile 的服务会在任一 profile 被激活时被选择。显式指定服务的操作即使未激活该服务的 profile,也可以选择它。 +- 加载器可以保留引擎尚未应用的字段。在运行时依赖某个 Compose 属性之前,请查阅 [Compose 字段支持矩阵](docs/compose-field-matrix.md)。 - `depends_on` 已被读取并能体现在依赖图中,但尚未实现完整的启动排序和健康就绪调度。 默认端点在 Windows 是 `npipe://./pipe/docker_engine`,Unix 是 `unix:///var/run/docker.sock`;也可以通过 `SocketPath` 显式指定。 @@ -113,7 +114,7 @@ builder.Services.AddComposeSharp(); 2. **2.2:Docker Engine 覆盖度** — 替换进程式 build/copy/export/commit,实现真实 top、Docker 事件流,以及有意义的 generate/publish 行为。 3. **3.0:可靠编排** — 依赖与健康就绪、保守的 reconcile 策略、诊断信息,以及 Windows/Linux Docker 集成测试。 -每个阶段的验收标准与明确不做的事项见 [docs/roadmap.md](docs/roadmap.md);实现任务见 [GitHub Milestones](https://github.com/GaTTGeng/ComposeSharp/milestones)。欢迎用最小 Compose 文件提交 [兼容性问题](https://github.com/GaTTGeng/ComposeSharp/issues/new?template=compose_compatibility_gap.yml)。 +每个阶段的验收标准与明确不做的事项见 [docs/roadmap.md](docs/roadmap.md);[Compose 字段支持矩阵](docs/compose-field-matrix.md)记录了解析与实际应用的行为;实现任务见 [GitHub Milestones](https://github.com/GaTTGeng/ComposeSharp/milestones)。欢迎用最小 Compose 文件提交 [兼容性问题](https://github.com/GaTTGeng/ComposeSharp/issues/new?template=compose_compatibility_gap.yml)。 ## 构建与参与 diff --git a/docs/compose-field-matrix.md b/docs/compose-field-matrix.md new file mode 100644 index 0000000..c9d9787 --- /dev/null +++ b/docs/compose-field-matrix.md @@ -0,0 +1,79 @@ +# Compose field support matrix + +ComposeSharp is an in-process SDK, not a Docker Compose CLI replacement. The loader deliberately retains more Compose-shaped data than the engine currently sends to Docker. This matrix records that distinction for the fields exposed by `ServiceDefinition` and `ComposeProject`. + +## Status definitions + +| Status | Meaning | +| --- | --- | +| Applied | The loader reads the field and the engine uses it when it creates or operates on resources. | +| Partial | The loader reads the field and the engine uses a documented subset of its value or semantics. | +| Parsed only | The loader exposes the field, but the engine does not currently apply it. | +| Unsupported | The field is exposed for inspection but has no operational behavior. | +| Planned | A related operational change has a tracked issue. It does not imply current support. | + +"Applied" describes the SDK's implementation, not full Docker Compose Specification parity. Explicit operation options can override an applied service value where the API allows it. + +## Service fields + +| Compose field(s) | Model member(s) | Status | Current behavior | +| --- | --- | --- | --- | +| Service key | `Name` | Applied | Identifies the service in resource names and project labels. | +| `image` | `Image` | Applied | Used to create and pull container images. | +| `build` | `Build` | Parsed only / [planned](https://github.com/GaTTGeng/ComposeSharp/issues/14) | The loader retains `context`, `dockerfile`, `args`, cache settings, `target`, `tags`, `labels`, `network`, `extra_hosts`, `privileged`, `shm_size`, `platforms`, `pull`, `no_cache`, and `context_directory`. It does not retain `secrets`, `ssh`, or `additional_contexts`. `BuildAsync` currently combines `Arguments` with `ArgumentList`; a non-null build context causes process startup to fail before Docker receives the settings. | +| `container_name` | `ContainerName` | Applied | Used for a single replica; scaled services retain project-generated names. | +| `command`, `entrypoint` | `Command`, `Entrypoint` | Partial | List syntax is passed to Docker's create-container request. Scalar values are passed as one argument rather than split into a command and arguments. | +| `environment`, `env_file` | `Environment`, `EnvFile` | Partial | Inline environment and values read from scalar or list-of-string `env_file` entries are passed to the container, and their original paths are retained for inspection. Long `env_file` syntax and advanced Compose environment semantics are not implemented. | +| `ports` | `Ports` | Partial | Short `HOST:CONTAINER` string syntax creates a port binding when each container port has one mapping. Container-only entries expose the port but do not create a host binding. Multiple mappings for one container port, long syntax, host IP, ranges, and other per-port options are not modeled. | +| `volumes` | `Volumes` | Partial | Short POSIX bind and named-volume strings are resolved and passed as binds. Long syntax, Windows drive-letter binds, and top-level volume driver/options are not applied. | +| `restart` | `Restart`, `RestartMaxRetries` | Partial | Docker restart policy name is applied. An `on-failure` retry count is parsed but not sent. | +| `healthcheck` | `Healthcheck` | Partial | Disable flag, list-form tests, supported interval/timeout/start-period values, and retries are sent in the create-container request. `start_interval` is not modeled. Durations accept .NET `TimeSpan` syntax or a single whole-number `ms`, `s`, `m`, or `h` unit; fractional and multi-component Compose durations are not accepted. A scalar `test` command is not converted to `CMD-SHELL`. | +| `depends_on` | `DependsOn` | Partial / [planned](https://github.com/GaTTGeng/ComposeSharp/issues/19) | The engine makes a best-effort ordering pass. It does not detect cycles or wait for dependency conditions or health readiness. A targeted lifecycle operation does not add unselected dependencies. | +| `networks` | `Networks` | Partial | The first declared service network becomes the container network mode. Per-network configuration and multi-network attachment are not applied. When a service declares no network and the project has custom networks, it attaches to the first custom network rather than an implicit default network. | +| `extra_hosts` | `ExtraHosts` | Partial | Short list entries are passed to Docker as host entries. Mapping syntax loses the host address during loading and is not supported. | +| `privileged` | `Privileged` | Applied | Passed in the host configuration. | +| `network_mode`, `ipc`, `shm_size` | `NetworkMode`, `Ipc`, `ShmSize` | Partial | Direct Docker modes and integer/K/M/G `shm_size` values are passed in the host configuration. Decimal byte values are not accepted. `network_mode: service:` and `ipc: service:` are not resolved to a service container. `network_mode` takes precedence over the generated project network. | +| `profiles` | `Profiles` | Applied | Service selection uses `ComposeProjectContext.Profiles`; unprofiled services remain selected, and explicitly requested services are selectable. | +| `deploy` | `Deploy` | Partial | Only `deploy.replicas` affects `UpAsync`; resource memory and literal `nano_cpus` values, placement constraints, restart policy, update/rollback settings, labels, and mode are parsed only. Duration fields use the same restricted duration syntax as health checks. Other placement settings, standard `deploy.resources.*.cpus` values, and scalar `endpoint_mode` are not retained. | +| `secrets`, `configs` | `Secrets`, `Configs` | Unsupported | Short string entries are parsed and surfaced, but no secret or config is provisioned or mounted. Long syntax is not retained correctly. | +| `labels` | `Labels` | Applied | Merged into the labels applied to service containers. | +| `logging` | `Logging` | Parsed only | Driver and options are exposed but not sent to Docker. | +| `hostname`, `domainname`, `user`, `working_dir` | `Hostname`, `Domainname`, `User`, `WorkingDir` | Applied | Passed to Docker's create-container request. | +| `tty`, `stdin_open` | `Tty`, `StdinOpen` | Applied | Passed to Docker's create-container request. | +| `stop_signal`, `stop_grace_period` | `StopSignal`, `StopGracePeriod` | Parsed only | Exposed by the loader when the duration uses the supported .NET `TimeSpan` or single whole-number unit syntax; the container create and stop paths do not apply them. | +| `read_only`, `tmpfs` | `ReadOnly`, `Tmpfs` | Applied | Passed in the host configuration. | +| `cap_add`, `cap_drop`, `security_opt` | `CapAdd`, `CapDrop`, `SecurityOpt` | Applied | Passed in the host configuration. | +| `devices` | `Devices` | Partial | Two-segment short mappings are passed in the host configuration. Permission-bearing mappings such as `/dev/sda:/dev/xvdc:rwm` are parsed incorrectly and are not supported. | +| `sysctls` | `Sysctls` | Parsed only | Exposed by the loader but not passed to Docker. | +| `init` | `Init` | Applied | Enables Docker init when the value is `true`. | +| `platform`, `pull_policy` | `Platform`, `PullPolicy` | Parsed only | Exposed by the loader; platform is not passed to create or build, and pull behavior is controlled by operation options. | +| `dns`, `dns_search` | `Dns`, `DnsSearch` | Parsed only | Exposed by the loader but not passed to Docker. | +| `pid`, `mac_address`, `cgroup_parent` | `Pid`, `MacAddress`, `CgroupParent` | Partial | Direct Docker PID modes, MAC address, and cgroup parent are passed to Docker. `pid: service:` is not resolved to a service container. | +| `extends` | `ExtendsService`, `ExtendsFile` | Unsupported | The loader records the reference but does not resolve or merge it. A service that declares only `extends`, without its own `image` or `build`, is rejected during loading. | +| `develop` | `Develop` | Unsupported | Mapping-shaped values are not retained as watch configuration. `WatchAsync` observes build contexts only and does not interpret this field. | +| `links` | `Links` | Parsed only | Exposed by the loader but not passed to Docker. | +| `cpu_shares`, `cpuset` | `CpuShares`, `Cpuset` | Applied | Converted to Docker CPU shares and CPU set host settings. | +| `cpu_quota` | `CpuQuota` | Parsed only | Exposed by the loader but not passed to Docker. | +| `mem_limit`, `memswap_limit`, `mem_reservation` | `Memory`, `MemorySwap`, `MemoryReservation` | Partial | Integer byte values, K/M/G units, and `memswap_limit: -1` are converted and passed in the host configuration. Decimal and other Compose byte formats are not accepted. | +| `oom_kill_disable`, `oom_score_adj` | `OomKillDisable`, `OomScoreAdj` | Parsed only | Values are not passed to Docker. `oom_score_adj` is retained, while `oom_kill_disable` is retained only when `true`; an explicit `false` is indistinguishable from omission. | +| `group_add` | `GroupAdd` | Applied | Passed as supplemental groups in the host configuration. | +| `annotations` | `Annotations` | Parsed only | Exposed by the loader but not sent to Docker. | + +## Top-level project fields + +| Compose field(s) | Model member(s) | Status | Current behavior | +| --- | --- | --- | --- | +| Compose file directory | `WorkingDirectory` | Applied | Resolves Compose-relative paths and bind mounts. | +| `services` | `Services` | Applied | Provides service definitions used by project operations. | +| `volumes` | `Volumes` | Partial | Project-scoped volumes are created with a generated name and project label. Driver, labels, options, and external volumes are not represented; external volume names are rewritten to project-scoped names. | +| `networks` | `Networks` | Partial | Project-scoped bridge networks are created with generated names and project labels. Driver, IPAM, labels, external networks, and options are not represented. | +| `secrets`, `configs` | `Secrets`, `Configs` | Unsupported | Names are loaded and reported by `LoadProject`, but are not provisioned or mounted. | +| `x-*` extensions | `Extensions` | Parsed only | String-valued extensions are retained for inspection and have no engine behavior. | + +## Related work + +- [Issue #14](https://github.com/GaTTGeng/ComposeSharp/issues/14) will replace the process-backed build path with Docker Engine APIs. +- [Issue #19](https://github.com/GaTTGeng/ComposeSharp/issues/19) will make dependency ordering and readiness deliberate and testable. +- [Issue #23](https://github.com/GaTTGeng/ComposeSharp/issues/23) tracks a broader matrix of tested Compose constructs and environments. + +For the loader's multi-file merge rules, see [merge semantics](merge-semantics.md). For planned work and non-goals, see the [roadmap](roadmap.md). diff --git a/docs/roadmap.md b/docs/roadmap.md index 6a7ae1e..1793ea3 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -18,7 +18,7 @@ This is a usable baseline, not a compatibility certification. - A documented and test-backed multi-file merge policy, with incremental movement toward Compose Specification semantics where practical. - Profile selection applied consistently from `ComposeProjectContext`. - Validation messages that name the relevant source file, service, and property. -- Documentation that distinguishes parsed fields from fields actually applied to Docker Engine. +- Documentation that distinguishes parsed fields from fields actually applied to Docker Engine; see the [Compose field support matrix](compose-field-matrix.md). ### Not a goal