diff --git a/pkg/client/compose/project_test.go b/pkg/client/compose/project_test.go index 1dd6436b..46240c0b 100644 --- a/pkg/client/compose/project_test.go +++ b/pkg/client/compose/project_test.go @@ -239,6 +239,25 @@ networks: warnCount: 1, warnContains: []string{"networks"}, }, + { + name: "unsupported depends_on service_completed_successfully", + composeYAML: `services: + migrate: + image: alpine + command: ["true"] + app: + image: nginx + depends_on: + migrate: + condition: service_completed_successfully +`, + warnCount: 1, + warnContains: []string{ + "service_completed_successfully", + "pre-deploy hook", + "https://uncloud.run/docs/guides/deployments/pre-deploy-hooks", + }, + }, { name: "multiple unsupported features", composeYAML: `services: diff --git a/pkg/client/compose/service.go b/pkg/client/compose/service.go index 80a9ae21..dc9839ab 100644 --- a/pkg/client/compose/service.go +++ b/pkg/client/compose/service.go @@ -495,6 +495,21 @@ func validateServicesFeatures(project *types.Project) []error { errs = append(errs, err(service.Name, "networks")) } } + + // Err about depends_on conditions 'service_completed_successfully' that we do not support because services in + // Uncloud are long-running. Services that run to completion need a separate abstraction, e.g. a Job. + // Plus we don't want the lifecycle of a service to control the lifecycle of another one. It should be fully + // owned. Otherwise, it's hard to make the behaviour deterministic when each service could also be deployed and + // managed independently. + for depName, dep := range service.DependsOn { + if dep.Condition == types.ServiceConditionCompletedSuccessfully { + errs = append(errs, fmt.Errorf( + "service '%s': depends_on condition '%s' on service '%s' is not supported, "+ + "use a pre-deploy hook instead: %s", + service.Name, types.ServiceConditionCompletedSuccessfully, depName, + "https://uncloud.run/docs/guides/deployments/pre-deploy-hooks")) + } + } } return errs diff --git a/website/docs/8-compose-file-reference/1-support-matrix.md b/website/docs/8-compose-file-reference/1-support-matrix.md index 9f529228..fd5494c9 100644 --- a/website/docs/8-compose-file-reference/1-support-matrix.md +++ b/website/docs/8-compose-file-reference/1-support-matrix.md @@ -10,74 +10,74 @@ If you rely on a specific Compose feature that is not supported by Uncloud, plea ::: -| Feature | Support Status | Notes | -|----------------------------------|--------------------|----------------------------------------------------------------------------------------------------------------| -| **Services** | | | -| `build` | ✅ Supported | Build context and Dockerfile | -| `cap_add` | ✅ Supported | Additional kernel [capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) | -| `cap_drop` | ✅ Supported | Which kernel [capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) to drop | -| `command` | ✅ Supported | Override container command | -| `configs` | ✅ Supported | File-based and inline configs | -| `cpus` | ✅ Supported | CPU limit | -| `depends_on` | ⚠️ Limited | Services deployed in order but conditions not checked | -| `devices` | ✅ Supported | Device mappings | -| `dns` | ❌ Not supported | Built-in service discovery | -| `dns_search` | ❌ Not supported | Built-in service discovery | -| `entrypoint` | ✅ Supported | Override container entrypoint | -| `env_file` | ✅ Supported | Environment file | -| `environment` | ✅ Supported | Environment variables | -| `gpus` | ✅ Supported | GPU device access | -| `healthcheck` | ✅ Supported | Health check configuration | -| `image` | ✅ Supported | Container image specification | -| `init` | ✅ Supported | Run init process in container | -| `labels` | ❌ Not supported | | -| `links` | ❌ Not supported | Use service names for communication | -| `logging` | ✅ Supported | Defaults to [local](https://docs.docker.com/engine/logging/drivers/local/) log driver | -| `mem_limit` | ✅ Supported | Memory limit | -| `mem_reservation` | ✅ Supported | Memory reservation | -| `mem_swappiness` | ❌ Not supported | | -| `memswap_limit` | ❌ Not supported | | -| `networks` | ❌ Not supported | All containers share cluster network | -| `pid` | ✅ Supported | Set the PID namespace mode, `pid: host` only | -| `ports` | ⚠️ Limited | `mode: host` only, use [`x-ports`](2-extensions.md#x-ports) for HTTP/HTTPS | -| `privileged` | ✅ Supported | Run containers in privileged mode | -| `pull_policy` | ✅ Supported | `always`, `missing`, `never` | -| `secrets` | ❌ Not supported | Use configs or environment variables | -| `security_opt` | ❌ Not supported | | -| `shm_size` | ✅ Supported | Shared memory size | -| `stop_grace_period` | ✅ Supported | Time to wait after SIGTERM before SIGKILL | -| `storage_opt` | ❌ Not supported | | -| `sysctls` | ✅ Supported | Namespaced kernel parameters | -| `ulimits` | ✅ Supported | Resource limits | -| `user` | ✅ Supported | Set container user | -| `volumes` | ✅ Supported | Named volumes, bind mounts, tmpfs | -| **Deploy** | | | -| `labels` | ❌ Not supported | | -| `mode` | ✅ Supported | Either `global` or `replicated` | -| `placement` | ❌ Not supported | Use [`x-machines`](2-extensions.md#x-machines) extension | -| `replicas` | ✅ Supported | Number of container replicas | -| `resources` | ⚠️ Limited | CPU, memory limits and device reservations | -| `restart_policy` | ❌ Not supported | Defaults to `unless-stopped` | -| `rollback_config` | ❌ Not supported | See [#151](https://github.com/psviderski/uncloud/issues/151) | -| `update_config` | ⚠️ Limited | `order` and `monitor` supported. See [rolling deployments](../4-guides/1-deployments/4-rolling-deployments.md) | -| **Volumes** | | | -| Named volumes | ✅ Supported | Docker volumes | -| Bind mounts | ✅ Supported | Host path binding | -| Tmpfs mounts | ✅ Supported | In-memory filesystems | -| Volume labels | ✅ Supported | Custom labels | -| External volumes | ✅ Supported | Must exist before deployment | -| [Volume drivers][volume-drivers] | ✅ Supported | `local` (supports [NFS][volume-nfs], [CIFS/Samba][volume-cifs]) and manually installed third-party drivers | -| **Configs** | | | -| File-based configs | ✅ Supported | Read from file | -| Inline configs | ✅ Supported | Defined in compose file | -| External configs | ❌ Not supported | Not supported | -| Short syntax | ❌ Not supported | Use long syntax only | -| **Extensions** | | | -| `x-context` | ✅ Uncloud-specific | Cluster context override | -| `x-caddy` | ✅ Uncloud-specific | Custom Caddy configuration | -| `x-machines` | ✅ Uncloud-specific | Machine placement constraints | -| `x-ports` | ✅ Uncloud-specific | Service port publishing | -| `x-pre_deploy` | ✅ Uncloud-specific | Pre-deploy hook command | +| Feature | Support Status | Notes | +|----------------------------------|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +| **Services** | | | +| `build` | ✅ Supported | Build context and Dockerfile | +| `cap_add` | ✅ Supported | Additional kernel [capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) | +| `cap_drop` | ✅ Supported | Which kernel [capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) to drop | +| `command` | ✅ Supported | Override container command | +| `configs` | ✅ Supported | File-based and inline configs | +| `cpus` | ✅ Supported | CPU limit | +| `depends_on` | ⚠️ Limited | Deployed in dependency order. Use [pre-deploy hooks](../4-guides/1-deployments/5-pre-deploy-hooks.md) for `service_completed_successfully` | +| `devices` | ✅ Supported | Device mappings | +| `dns` | ❌ Not supported | Built-in service discovery | +| `dns_search` | ❌ Not supported | Built-in service discovery | +| `entrypoint` | ✅ Supported | Override container entrypoint | +| `env_file` | ✅ Supported | Environment file | +| `environment` | ✅ Supported | Environment variables | +| `gpus` | ✅ Supported | GPU device access | +| `healthcheck` | ✅ Supported | Health check configuration | +| `image` | ✅ Supported | Container image specification | +| `init` | ✅ Supported | Run init process in container | +| `labels` | ❌ Not supported | | +| `links` | ❌ Not supported | Use service names for communication | +| `logging` | ✅ Supported | Defaults to [local](https://docs.docker.com/engine/logging/drivers/local/) log driver | +| `mem_limit` | ✅ Supported | Memory limit | +| `mem_reservation` | ✅ Supported | Memory reservation | +| `mem_swappiness` | ❌ Not supported | | +| `memswap_limit` | ❌ Not supported | | +| `networks` | ❌ Not supported | All containers share cluster network | +| `pid` | ✅ Supported | Set the PID namespace mode, `pid: host` only | +| `ports` | ⚠️ Limited | `mode: host` only, use [`x-ports`](2-extensions.md#x-ports) for HTTP/HTTPS | +| `privileged` | ✅ Supported | Run containers in privileged mode | +| `pull_policy` | ✅ Supported | `always`, `missing`, `never` | +| `secrets` | ❌ Not supported | Use configs or environment variables | +| `security_opt` | ❌ Not supported | | +| `shm_size` | ✅ Supported | Shared memory size | +| `stop_grace_period` | ✅ Supported | Time to wait after SIGTERM before SIGKILL | +| `storage_opt` | ❌ Not supported | | +| `sysctls` | ✅ Supported | Namespaced kernel parameters | +| `ulimits` | ✅ Supported | Resource limits | +| `user` | ✅ Supported | Set container user | +| `volumes` | ✅ Supported | Named volumes, bind mounts, tmpfs | +| **Deploy** | | | +| `labels` | ❌ Not supported | | +| `mode` | ✅ Supported | Either `global` or `replicated` | +| `placement` | ❌ Not supported | Use [`x-machines`](2-extensions.md#x-machines) extension | +| `replicas` | ✅ Supported | Number of container replicas | +| `resources` | ⚠️ Limited | CPU, memory limits and device reservations | +| `restart_policy` | ❌ Not supported | Defaults to `unless-stopped` | +| `rollback_config` | ❌ Not supported | See [#151](https://github.com/psviderski/uncloud/issues/151) | +| `update_config` | ⚠️ Limited | `order` and `monitor` supported. See [rolling deployments](../4-guides/1-deployments/4-rolling-deployments.md) | +| **Volumes** | | | +| Named volumes | ✅ Supported | Docker volumes | +| Bind mounts | ✅ Supported | Host path binding | +| Tmpfs mounts | ✅ Supported | In-memory filesystems | +| Volume labels | ✅ Supported | Custom labels | +| External volumes | ✅ Supported | Must exist before deployment | +| [Volume drivers][volume-drivers] | ✅ Supported | `local` (supports [NFS][volume-nfs], [CIFS/Samba][volume-cifs]) and manually installed third-party drivers | +| **Configs** | | | +| File-based configs | ✅ Supported | Read from file | +| Inline configs | ✅ Supported | Defined in compose file | +| External configs | ❌ Not supported | Not supported | +| Short syntax | ❌ Not supported | Use long syntax only | +| **Extensions** | | | +| `x-context` | ✅ Uncloud-specific | Cluster context override | +| `x-caddy` | ✅ Uncloud-specific | Custom Caddy configuration | +| `x-machines` | ✅ Uncloud-specific | Machine placement constraints | +| `x-ports` | ✅ Uncloud-specific | Service port publishing | +| `x-pre_deploy` | ✅ Uncloud-specific | Pre-deploy hook command | [volume-drivers]: https://docs.docker.com/engine/storage/volumes/#use-a-volume-driver