Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
556c9bc4b3
|
|||
|
ad921fd14b
|
|||
|
ae1cec2998
|
|||
|
2f6dba296f
|
|||
|
ae049cf2d3
|
|||
|
e00db9e58d
|
|||
|
51f2611e9d
|
|||
|
84686672ea
|
|||
|
e5db02b4f8
|
|||
|
4dfcc61143
|
|||
|
affcf1bca8
|
|||
|
22d3f569df
|
|||
|
8f3539ed34
|
|||
|
a9b0993ffb
|
|||
|
6a341e426c
|
|||
|
85a83e7580
|
|||
|
d62dc0f349
|
|||
|
1574342e92
|
|||
|
2c679229db
|
|||
|
a4d0f2a547
|
|||
|
4b8e544ab8
|
|||
|
9a08882e28
|
|||
|
afb91c66bd
|
|||
|
ead883f714
|
|||
|
ac45011794
|
|||
|
2b244348ca
|
|||
|
de66fef2d6
|
|||
|
6c16c89379
|
|||
|
e515ffbe0c
|
|||
|
978109d3fc
|
|||
|
17a50d776b
|
|||
|
550dcd1f0c
|
|||
|
cbbeaf6d67
|
|||
|
6dffb91626
|
|||
|
c63bf7b814
|
|||
|
7a9af8015e
|
|||
|
d437e6ff36
|
|||
|
93f1b726ce
|
|||
|
c58c5d3eff
|
|||
|
60e8c7f9a8
|
|||
|
272ddf17c2
|
|||
|
b0bf71aa61
|
|||
|
0cb26df68b
|
|||
|
a7c2eb1d9b
|
|||
|
496a192198
|
|||
|
d9e2c485f4
|
|||
|
ed9c97ca32
|
|||
|
31a46ecbbd
|
|||
|
d3426e5d82
|
|||
|
ed38caecec
|
|||
|
f0cc531ada
|
|||
|
b1a1098fbc
|
|||
|
04c52c8158
|
|||
|
1f14c9ac9a
|
|||
|
6c11473999
|
|||
|
ced1916def
|
|||
|
57d4bdfb79
|
|||
|
dd724e0a3c
|
|||
|
ab1dbea329
|
|||
|
9c90f0a477
|
|||
|
aff3df6fcf
|
|||
|
a71fa531f9
|
|||
|
aeb51614cb
|
|||
|
39b3daf57c
|
|||
|
fe65d2debc
|
|||
|
20f32531b7
|
|||
|
856edbd22e
|
|||
|
bf252c51f0
|
|||
|
821ef2f570
|
|||
|
a3211552a5
|
|||
|
0317c6adea
|
|||
|
2f861a9192
|
|||
|
27ce28e2ea
|
|||
|
d71f86a38b
|
|||
|
b02da21aac
|
|||
|
30b26ca5f0
|
|||
|
d4519e862f
|
|||
|
4fc16646eb
|
|||
|
a26a088c69
|
|||
|
71d9821c4c
|
5
.cargo/config.toml
Normal file
5
.cargo/config.toml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[build]
|
||||||
|
rustc-wrapper = "/opt/homebrew/bin/sccache"
|
||||||
|
|
||||||
|
[registries.sunbeam]
|
||||||
|
index = "sparse+https://src.sunbeam.pt/api/packages/studio/cargo/"
|
||||||
@@ -34,6 +34,17 @@ retries = 2
|
|||||||
[profile.ci.junit]
|
[profile.ci.junit]
|
||||||
path = "target/nextest/ci/junit.xml"
|
path = "target/nextest/ci/junit.xml"
|
||||||
|
|
||||||
|
[profile.cover]
|
||||||
|
# Coverage profile — used with cargo llvm-cov nextest
|
||||||
|
fail-fast = false
|
||||||
|
test-threads = "num-cpus"
|
||||||
|
failure-output = "immediate-final"
|
||||||
|
success-output = "never"
|
||||||
|
slow-timeout = { period = "60s", terminate-after = 2 }
|
||||||
|
|
||||||
|
[profile.cover.junit]
|
||||||
|
path = "target/nextest/cover/junit.xml"
|
||||||
|
|
||||||
# Postgres tests must run serially (shared database state)
|
# Postgres tests must run serially (shared database state)
|
||||||
[[profile.default.overrides]]
|
[[profile.default.overrides]]
|
||||||
filter = "package(wfe-postgres)"
|
filter = "package(wfe-postgres)"
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -3,4 +3,4 @@ Cargo.lock
|
|||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.env
|
.env*
|
||||||
|
|||||||
169
CHANGELOG.md
Normal file
169
CHANGELOG.md
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [1.8.0] - 2026-04-06
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **wfe-kubernetes**: New crate -- Kubernetes executor for running workflow steps as K8s Jobs
|
||||||
|
- Namespace-per-workflow isolation with automatic cleanup
|
||||||
|
- Job manifest builder with env, resources, pull policy, node selector support
|
||||||
|
- Pod log streaming to LogSink with real-time output capture
|
||||||
|
- `##wfe[output key=value]` parsing from Job stdout
|
||||||
|
- Timeout handling with Job cleanup on expiry
|
||||||
|
- `KubernetesServiceProvider`: provisions infrastructure services as K8s Pods + Services with DNS resolution and readiness polling
|
||||||
|
- 100% test coverage on service provider, 91% overall crate coverage
|
||||||
|
- **wfe-core**: `ServiceDefinition`, `ServicePort`, `ReadinessProbe`, `ServiceEndpoint` types for declaring infrastructure services
|
||||||
|
- **wfe-core**: `ServiceProvider` trait for pluggable service provisioning
|
||||||
|
- **wfe-core**: `services` field on `WorkflowDefinition` for declaring required services
|
||||||
|
- **wfe**: Capability-based workflow routing -- hosts check `can_execute()` before accepting workflows
|
||||||
|
- Verifies all step types are registered in the StepRegistry
|
||||||
|
- Verifies ServiceProvider is configured and can provision required services
|
||||||
|
- Re-queues workflows that can't be handled by this host
|
||||||
|
- **wfe**: Service lifecycle in dequeue loop -- provision before execution, teardown after completion/failure
|
||||||
|
- **wfe**: `use_service_provider()` on `WorkflowHostBuilder`
|
||||||
|
- **wfe-containerd**: `ContainerdServiceProvider` for running services via containerd gRPC API on host network
|
||||||
|
- **wfe-yaml**: `services:` block in workflow YAML definitions with readiness probes (exec, tcp, http)
|
||||||
|
- **wfe-yaml**: `kubernetes`/`k8s` step type with lazy client creation
|
||||||
|
|
||||||
|
## [1.7.0] - 2026-04-05
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **wfe-deno**: New crate -- Deno/JS/TS bindings for the WFE workflow engine
|
||||||
|
- Full API surface via 23 deno_core ops: host lifecycle, workflow management, fluent builder, step registration, event publishing
|
||||||
|
- Channel-based execution bridge: JS step functions called from tokio executor via mpsc/oneshot channels
|
||||||
|
- High-level JS API classes: `WorkflowHost`, `WorkflowBuilder`, `ExecutionResult`
|
||||||
|
- 52 tests (26 unit + 26 integration), 93% line coverage
|
||||||
|
- **wfe-core**: `WorkflowBuilder.steps` and `last_step` fields now public
|
||||||
|
|
||||||
|
## [1.6.3] - 2026-04-05
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **wfe-core**: Propagate `step_name` into execution pointers when advancing to next steps, compensation steps, and parallel branch children
|
||||||
|
- **wfe**: Set `step_name` on initial execution pointer when starting a workflow instance
|
||||||
|
|
||||||
|
## [1.6.2] - 2026-04-05
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **wfe-core**: `WorkflowBuilder::add_step_typed()` for adding named, configured steps in parallel branch closures
|
||||||
|
- **wfe-core**: `WorkflowBuilder::wire_outcome()` now public for custom graph wiring
|
||||||
|
|
||||||
|
## [1.6.1] - 2026-04-05
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **wfe-core**: `StepBuilder::config()` for attaching arbitrary JSON configuration to individual steps, readable at runtime via `context.step.step_config`
|
||||||
|
|
||||||
|
## [1.6.0] - 2026-04-01
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **wfe-server**: Headless workflow server (single binary)
|
||||||
|
- gRPC API with 13 RPCs: workflow CRUD, lifecycle streaming, log streaming, log search
|
||||||
|
- HTTP webhooks: GitHub and Gitea with HMAC-SHA256 verification, configurable triggers
|
||||||
|
- OIDC/JWT authentication with JWKS discovery and asymmetric algorithm allowlist
|
||||||
|
- Static bearer token auth with constant-time comparison
|
||||||
|
- Lifecycle event broadcasting via `WatchLifecycle` server-streaming RPC
|
||||||
|
- Real-time log streaming via `StreamLogs` with follow mode and history replay
|
||||||
|
- Full-text log search via OpenSearch with `SearchLogs` RPC
|
||||||
|
- Layered config: CLI flags > env vars > TOML file
|
||||||
|
- **wfe-server-protos**: gRPC service definitions (tonic 0.14, server + client stubs)
|
||||||
|
- **wfe-core**: `LogSink` trait for real-time step output streaming
|
||||||
|
- **wfe-core**: Lifecycle publisher wired into executor (StepStarted, StepCompleted, Error, Completed, Terminated)
|
||||||
|
- **wfe**: `use_log_sink()` on `WorkflowHostBuilder`
|
||||||
|
- **wfe-yaml**: Shell step streaming mode with `tokio::select!` interleaved stdout/stderr
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- JWT algorithm confusion prevention: derive algorithm from JWK, reject symmetric algorithms
|
||||||
|
- Constant-time static token comparison via `subtle` crate
|
||||||
|
- OIDC issuer HTTPS validation to prevent SSRF
|
||||||
|
- Fail-closed on OIDC discovery failure (server won't start with broken auth)
|
||||||
|
- Authenticated generic webhook endpoint
|
||||||
|
- 2MB webhook payload size limit
|
||||||
|
- Config parse errors fail loudly (no silent fallback to open defaults)
|
||||||
|
- Blocked sensitive env var injection (PATH, LD_PRELOAD, etc.) from workflow data
|
||||||
|
- Security regression tests for all critical and high findings
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Shell step streaming path now respects `timeout_ms` with `child.kill()` on timeout
|
||||||
|
- LogSink properly threaded from WorkflowHostBuilder through executor to StepExecutionContext
|
||||||
|
- LogStore.with_search() wired in server main.rs for OpenSearch indexing
|
||||||
|
- OpenSearch `index_chunk` returns Err on HTTP failure instead of swallowing it
|
||||||
|
- Webhook publish failures return 500 instead of 200
|
||||||
|
|
||||||
|
## [1.5.0] - 2026-03-29
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **wfe-rustlang**: New crate with Rust toolchain step executors
|
||||||
|
- Cargo steps: `cargo-build`, `cargo-test`, `cargo-check`, `cargo-clippy`, `cargo-fmt`, `cargo-doc`, `cargo-publish`
|
||||||
|
- External tool steps with auto-install: `cargo-audit`, `cargo-deny`, `cargo-nextest`, `cargo-llvm-cov`
|
||||||
|
- Rustup steps: `rust-install`, `rustup-toolchain`, `rustup-component`, `rustup-target`
|
||||||
|
- `cargo-doc-mdx`: generates MDX documentation from rustdoc JSON output using the `rustdoc-types` crate
|
||||||
|
- **wfe-yaml**: `rustlang` feature flag enabling all cargo/rustup step types
|
||||||
|
- **wfe-yaml**: Schema fields for Rust steps (`package`, `features`, `toolchain`, `profile`, `output_dir`, etc.)
|
||||||
|
- **wfe-containerd**: Remote daemon support via `WFE_IO_DIR` environment variable
|
||||||
|
- **wfe-containerd**: Image chain ID resolution from content store for proper rootfs snapshots
|
||||||
|
- **wfe-containerd**: Docker-default Linux capabilities for root containers
|
||||||
|
- Lima `wfe-test` VM config (Alpine + containerd + BuildKit, TCP socat proxy)
|
||||||
|
- Containerd integration tests running Rust toolchain in containers
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **wfe-containerd**: Empty rootfs — snapshot parent now resolved from image chain ID instead of empty string
|
||||||
|
- **wfe-containerd**: FIFO deadlock with remote daemons — replaced with regular file I/O
|
||||||
|
- **wfe-containerd**: `sh: not found` — use absolute `/bin/sh` path in OCI process spec
|
||||||
|
- **wfe-containerd**: `setgroups: Operation not permitted` — grant capabilities when running as UID 0
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Lima `wfe-test` VM uses Alpine apk packages instead of GitHub release binaries
|
||||||
|
- Container tests use TCP proxy (`http://127.0.0.1:2500`) instead of Unix socket forwarding
|
||||||
|
- CI pipeline (`workflows.yaml`) updated with `wfe-rustlang` in test, package, and publish steps
|
||||||
|
|
||||||
|
879 tests. 88.8% coverage on wfe-rustlang.
|
||||||
|
|
||||||
|
## [1.4.0] - 2026-03-26
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Type-safe `when:` conditions on workflow steps with compile-time validation
|
||||||
|
- Full boolean combinator set: `all` (AND), `any` (OR), `none` (NOR), `one_of` (XOR), `not` (NOT)
|
||||||
|
- Task file includes with cycle detection
|
||||||
|
- Self-hosting CI pipeline (`workflows.yaml`) demonstrating all features
|
||||||
|
- `readFile()` op for deno runtime
|
||||||
|
- Auto-typed `##wfe[output]` annotations (bool, number conversion)
|
||||||
|
- Multi-workflow YAML files, SubWorkflow step type, typed input/output schemas
|
||||||
|
- HostContext for programmatic child workflow invocation
|
||||||
|
- BuildKit image builder and containerd container runner as standalone crates
|
||||||
|
- gRPC clients generated from official upstream proto files (tonic 0.14)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Pipeline coverage step produces valid JSON, deno reads it with `readFile()`
|
||||||
|
- Host context field added to container executor test contexts
|
||||||
|
- `.outputs.` paths resolved flat for child workflows
|
||||||
|
- Pointer status conversion for Skipped in postgres provider
|
||||||
|
|
||||||
|
629 tests. 87.7% coverage.
|
||||||
|
|
||||||
|
## [1.0.0] - 2026-03-23
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **wfe-core**: Workflow engine with step primitives, executor, fluent builder API
|
||||||
|
- **wfe**: WorkflowHost, registry, sync runner, and purger
|
||||||
|
- **wfe-sqlite**: SQLite persistence provider
|
||||||
|
- **wfe-postgres**: PostgreSQL persistence provider
|
||||||
|
- **wfe-opensearch**: OpenSearch search index provider
|
||||||
|
- **wfe-valkey**: Valkey provider for locks, queues, and lifecycle events
|
||||||
|
- **wfe-yaml**: YAML workflow definitions with shell and deno executors
|
||||||
|
- **wfe-yaml**: Deno JS/TS runtime with sandboxed permissions, HTTP ops, npm support via esm.sh
|
||||||
|
- OpenTelemetry tracing support behind `otel` feature flag
|
||||||
|
- In-memory test support providers
|
||||||
29
Cargo.toml
29
Cargo.toml
@@ -1,11 +1,13 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["wfe-core", "wfe-sqlite", "wfe-postgres", "wfe-opensearch", "wfe-valkey", "wfe", "wfe-yaml"]
|
members = ["wfe-core", "wfe-sqlite", "wfe-postgres", "wfe-opensearch", "wfe-valkey", "wfe", "wfe-yaml", "wfe-buildkit", "wfe-containerd", "wfe-containerd-protos", "wfe-buildkit-protos", "wfe-rustlang", "wfe-server-protos", "wfe-server", "wfe-kubernetes", "wfe-deno"]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.1.0"
|
version = "1.8.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
repository = "https://src.sunbeam.pt/studio/wfe"
|
||||||
|
homepage = "https://src.sunbeam.pt/studio/wfe"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
# Core
|
# Core
|
||||||
@@ -36,22 +38,33 @@ redis = { version = "0.27", features = ["tokio-comp", "connection-manager"] }
|
|||||||
opensearch = "2"
|
opensearch = "2"
|
||||||
|
|
||||||
# Internal crates
|
# Internal crates
|
||||||
wfe-core = { path = "wfe-core" }
|
wfe-core = { version = "1.8.0", path = "wfe-core", registry = "sunbeam" }
|
||||||
wfe-sqlite = { path = "wfe-sqlite" }
|
wfe-sqlite = { version = "1.8.0", path = "wfe-sqlite", registry = "sunbeam" }
|
||||||
wfe-postgres = { path = "wfe-postgres" }
|
wfe-postgres = { version = "1.8.0", path = "wfe-postgres", registry = "sunbeam" }
|
||||||
wfe-opensearch = { path = "wfe-opensearch" }
|
wfe-opensearch = { version = "1.8.0", path = "wfe-opensearch", registry = "sunbeam" }
|
||||||
wfe-valkey = { path = "wfe-valkey" }
|
wfe-valkey = { version = "1.8.0", path = "wfe-valkey", registry = "sunbeam" }
|
||||||
wfe-yaml = { path = "wfe-yaml" }
|
wfe-yaml = { version = "1.8.0", path = "wfe-yaml", registry = "sunbeam" }
|
||||||
|
wfe-buildkit = { version = "1.8.0", path = "wfe-buildkit", registry = "sunbeam" }
|
||||||
|
wfe-containerd = { version = "1.8.0", path = "wfe-containerd", registry = "sunbeam" }
|
||||||
|
wfe-rustlang = { version = "1.8.0", path = "wfe-rustlang", registry = "sunbeam" }
|
||||||
|
wfe-kubernetes = { version = "1.8.0", path = "wfe-kubernetes", registry = "sunbeam" }
|
||||||
|
|
||||||
# YAML
|
# YAML
|
||||||
serde_yaml = "0.9"
|
serde_yaml = "0.9"
|
||||||
|
yaml-merge-keys = { version = "0.8", features = ["serde_yaml"] }
|
||||||
regex = "1"
|
regex = "1"
|
||||||
|
|
||||||
# Deno runtime
|
# Deno runtime
|
||||||
deno_core = "0.394"
|
deno_core = "0.394"
|
||||||
|
|
||||||
deno_error = "0.7"
|
deno_error = "0.7"
|
||||||
url = "2"
|
url = "2"
|
||||||
|
|
||||||
|
# Kubernetes
|
||||||
|
kube = { version = "3.1", features = ["runtime", "client", "ws"] }
|
||||||
|
k8s-openapi = { version = "0.27", features = ["latest"] }
|
||||||
|
futures = "0.3"
|
||||||
|
|
||||||
# Dev/Test
|
# Dev/Test
|
||||||
pretty_assertions = "1"
|
pretty_assertions = "1"
|
||||||
rstest = "0.23"
|
rstest = "0.23"
|
||||||
|
|||||||
90
README.md
90
README.md
@@ -1,20 +1,24 @@
|
|||||||
# WFE
|
# WFE
|
||||||
|
|
||||||
A persistent, embeddable workflow engine for Rust. Trait-based, pluggable, built for real infrastructure.
|
A persistent, embeddable workflow engine for Rust. Trait-based, pluggable, built for large, highly complex build, test, deployment, and release pipelines of the highest levels of complexity.
|
||||||
|
|
||||||
> Rust port of [workflow-core](https://github.com/danielgerlag/workflow-core), rebuilt from scratch with async/await, pluggable persistence, and a YAML frontend with shell and Deno executors.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## What is WFE?
|
## What is WFE?
|
||||||
|
|
||||||
WFE is a workflow engine you embed directly into your Rust application. Define workflows as code using a fluent builder API, or as YAML files with shell and JavaScript steps. Workflows persist across restarts, support event-driven pausing, parallel execution, saga compensation, and distributed locking.
|
WFE is a technical love letter from a former [VMware](https://www.vmware.com) and [Pivotal](https://pivotal.io) engineer (@siennathesane). Its internal workflow architecture is based on the amazing [workflow-core](https://github.com/danielgerlag/workflow-core) library by Daniel Gerlag, and the YAML structure and support is based on [Concourse CI](https://concourse-ci.org). WFE is a pluggable, extendable library that can be used to design embedded business workflows, CLI applications, and CI/CD pipelines. It is designed to be embedded into your application, and can scale open-ended with pluggable architectures. You can deploy Cloud Foundry, Kubernetes, or even bootstrap a public cloud with WFE.
|
||||||
|
|
||||||
Built for:
|
You can define workflows as code using a fluent builder API, or as YAML files with shell and JavaScript steps. Workflows persist across restarts, support event-driven pausing, parallel execution, saga compensation, and distributed locking. It also comes with native support for containerd and buildkitd embedded into the application.
|
||||||
|
|
||||||
- **Persistent workflows** — steps survive process restarts. Pick up where you left off.
|
The only thing not included is a server and a web UI (open to contributions that have been agreed upon and discussed ahead of time).
|
||||||
- **Embeddable CLIs** — drop it into a binary, no external orchestrator required.
|
|
||||||
- **Portable CI pipelines** — YAML workflows with shell and Deno steps, variable interpolation, structured outputs.
|
## Why?
|
||||||
|
|
||||||
|
Every CI/CD system [I've](https://src.sunbeam.pt/siennathesane) ever used has been either lovely or terrible. I wanted something that was lovely, but also flexible enough to be used in a variety of contexts. The list of CI systems I've used over the years has been extensive, and they all have their _thing_ that makes them stand out in their own ways. I wanted something that could meet every single requirement I have: a distributed workflow engine that can be embedded into any application, has pluggable executors, a statically-verifiable workflow definition language, a simple, easy to use API, YAML 1.1 merge anchors, YAML 1.2 support, multi-file workflows, can be used as a library, can be used as a CLI, and can be used to write servers.
|
||||||
|
|
||||||
|
With that, I wanted the user experience to be essentially identical for embedded application developers, systems engineers, and CI/CD engineers. Whether you write your workflows in code, YAML, or you have written a web server endpoint that accepts gRPC workflow definitions and you're relying on this library as a hosted service, it should feel like the same piece of software in every context.
|
||||||
|
|
||||||
|
Hell, I'm so dedicated to this being the most useful, most pragmatic, most embeddable workflow engine library ever that I'm willing to accept a C ABI contribution to make it embeddable in any language.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -245,6 +249,76 @@ SQLite tests use temporary files and run everywhere.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Self-hosting CI pipeline
|
||||||
|
|
||||||
|
WFE includes a self-hosting CI pipeline defined in `workflows.yaml` at the repository root. The pipeline uses WFE's own YAML workflow engine to build, test, and publish WFE itself.
|
||||||
|
|
||||||
|
### Pipeline architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
ci (orchestrator)
|
||||||
|
|
|
||||||
|
+-------------------+--------------------+
|
||||||
|
| | |
|
||||||
|
preflight lint test (fan-out)
|
||||||
|
(tool check) (fmt + clippy) |
|
||||||
|
+----------+----------+
|
||||||
|
| | |
|
||||||
|
test-unit test-integration test-containers
|
||||||
|
| (docker compose) (lima VM)
|
||||||
|
| | |
|
||||||
|
+----------+----------+
|
||||||
|
|
|
||||||
|
+---------+---------+
|
||||||
|
| | |
|
||||||
|
cover package tag
|
||||||
|
| | |
|
||||||
|
+---------+---------+
|
||||||
|
|
|
||||||
|
+---------+---------+
|
||||||
|
| |
|
||||||
|
publish release
|
||||||
|
(crates.io) (git tags + notes)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running the pipeline
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Default — uses current directory as workspace
|
||||||
|
cargo run --example run_pipeline -p wfe -- workflows.yaml
|
||||||
|
|
||||||
|
# With explicit configuration
|
||||||
|
WFE_CONFIG='{"workspace_dir":"/path/to/wfe","registry":"sunbeam","git_remote":"origin","coverage_threshold":85}' \
|
||||||
|
cargo run --example run_pipeline -p wfe -- workflows.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### WFE features demonstrated
|
||||||
|
|
||||||
|
The pipeline exercises every major WFE feature:
|
||||||
|
|
||||||
|
- **Workflow composition** — the `ci` orchestrator invokes child workflows (`lint`, `test`, `cover`, `package`, `tag`, `publish`, `release`) using the `workflow` step type.
|
||||||
|
- **Shell executor** — most steps run bash commands with configurable timeouts.
|
||||||
|
- **Deno executor** — the `cover` workflow uses a Deno step to parse coverage JSON; the `release` workflow uses Deno to generate release notes.
|
||||||
|
- **YAML anchors/templates** — `_templates` defines `shell_defaults` and `long_running` anchors, reused across steps via `<<: *shell_defaults`.
|
||||||
|
- **Structured outputs** — steps emit `##wfe[output key=value]` markers to pass data between steps and workflows.
|
||||||
|
- **Variable interpolation** — `((workspace_dir))` syntax passes inputs through workflow composition.
|
||||||
|
- **Error handling** — `on_failure` handlers, `error_behavior` with retry policies, and `ensure` blocks for cleanup (e.g., `docker-down`, `lima-down`).
|
||||||
|
|
||||||
|
### Preflight tool check
|
||||||
|
|
||||||
|
The `preflight` workflow runs first and checks for all required tools: `cargo`, `cargo-nextest`, `cargo-llvm-cov`, `docker`, `limactl`, `buildctl`, and `git`. Essential tools (cargo, nextest, git) cause a hard failure if missing. Optional tools (docker, lima, buildctl, llvm-cov) are reported but do not block the pipeline.
|
||||||
|
|
||||||
|
### Graceful infrastructure skipping
|
||||||
|
|
||||||
|
Integration and container tests handle missing infrastructure without failing:
|
||||||
|
|
||||||
|
- **test-integration**: The `docker-up` step checks if Docker is available. If `docker info` fails, it sets `docker_started=false` and exits cleanly. Subsequent steps (`postgres-tests`, `valkey-tests`, `opensearch-tests`) check this flag and skip if Docker is not running.
|
||||||
|
- **test-containers**: The `lima-up` step checks if `limactl` is installed. If missing, it sets `lima_started=false` and exits cleanly. The `buildkit-tests` and `containerd-tests` steps check this flag and skip accordingly.
|
||||||
|
|
||||||
|
This means the pipeline runs successfully on any machine with the essential Rust toolchain, reporting which optional tests were skipped rather than failing outright.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](LICENSE)
|
[MIT](LICENSE)
|
||||||
|
|||||||
141
test/lima/wfe-test.yaml
Normal file
141
test/lima/wfe-test.yaml
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
# WFE Test VM — Alpine + containerd + BuildKit
|
||||||
|
#
|
||||||
|
# Lightweight VM for running wfe-buildkit and wfe-containerd integration tests.
|
||||||
|
# Provides system-level containerd and BuildKit daemons with Unix sockets
|
||||||
|
# forwarded to the host.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# limactl create --name wfe-test ./test/lima/wfe-test.yaml
|
||||||
|
# limactl start wfe-test
|
||||||
|
#
|
||||||
|
# Sockets (on host after start):
|
||||||
|
# BuildKit: unix://$HOME/.lima/wfe-test/buildkitd.sock
|
||||||
|
# containerd: unix://$HOME/.lima/wfe-test/containerd.sock
|
||||||
|
#
|
||||||
|
# Run tests:
|
||||||
|
# WFE_BUILDKIT_ADDR="unix://$HOME/.lima/wfe-test/buildkitd.sock" \
|
||||||
|
# WFE_CONTAINERD_ADDR="unix://$HOME/.lima/wfe-test/containerd.sock" \
|
||||||
|
# cargo test -p wfe-buildkit -p wfe-containerd --test integration
|
||||||
|
# cargo test -p wfe-yaml --features rustlang,containerd --test rustlang_containerd -- --ignored
|
||||||
|
#
|
||||||
|
# Teardown:
|
||||||
|
# limactl stop wfe-test
|
||||||
|
# limactl delete wfe-test
|
||||||
|
|
||||||
|
message: |
|
||||||
|
WFE integration test VM is ready.
|
||||||
|
|
||||||
|
containerd: http://127.0.0.1:2500 (TCP proxy, use for gRPC)
|
||||||
|
BuildKit: http://127.0.0.1:2501 (TCP proxy, use for gRPC)
|
||||||
|
|
||||||
|
Run tests:
|
||||||
|
WFE_CONTAINERD_ADDR="http://127.0.0.1:2500" \
|
||||||
|
WFE_BUILDKIT_ADDR="http://127.0.0.1:2501" \
|
||||||
|
cargo test -p wfe-yaml --features rustlang,containerd --test rustlang_containerd -- --ignored
|
||||||
|
|
||||||
|
minimumLimaVersion: "2.0.0"
|
||||||
|
|
||||||
|
vmType: vz
|
||||||
|
mountType: virtiofs
|
||||||
|
cpus: 2
|
||||||
|
memory: 4GiB
|
||||||
|
disk: 20GiB
|
||||||
|
|
||||||
|
images:
|
||||||
|
- location: "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/cloud/nocloud_alpine-3.21.6-aarch64-uefi-cloudinit-r0.qcow2"
|
||||||
|
arch: "aarch64"
|
||||||
|
- location: "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/cloud/nocloud_alpine-3.21.6-x86_64-uefi-cloudinit-r0.qcow2"
|
||||||
|
arch: "x86_64"
|
||||||
|
|
||||||
|
mounts:
|
||||||
|
# Share /tmp so the containerd shim can access FIFOs created by the host-side executor
|
||||||
|
- location: /tmp/wfe-io
|
||||||
|
mountPoint: /tmp/wfe-io
|
||||||
|
writable: true
|
||||||
|
|
||||||
|
containerd:
|
||||||
|
system: false
|
||||||
|
user: false
|
||||||
|
|
||||||
|
provision:
|
||||||
|
# 1. Base packages + containerd + buildkit from Alpine repos (musl-compatible)
|
||||||
|
- mode: system
|
||||||
|
script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eux
|
||||||
|
apk update
|
||||||
|
apk add --no-cache \
|
||||||
|
curl bash coreutils findutils grep tar gzip pigz \
|
||||||
|
containerd containerd-openrc \
|
||||||
|
runc \
|
||||||
|
buildkit buildkit-openrc \
|
||||||
|
nerdctl
|
||||||
|
|
||||||
|
# 2. Start containerd
|
||||||
|
- mode: system
|
||||||
|
script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eux
|
||||||
|
rc-update add containerd default 2>/dev/null || true
|
||||||
|
rc-service containerd start 2>/dev/null || true
|
||||||
|
# Wait for socket
|
||||||
|
for i in $(seq 1 15); do
|
||||||
|
[ -S /run/containerd/containerd.sock ] && break
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
chmod 666 /run/containerd/containerd.sock 2>/dev/null || true
|
||||||
|
|
||||||
|
# 3. Start BuildKit (Alpine package names the service "buildkitd")
|
||||||
|
- mode: system
|
||||||
|
script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eux
|
||||||
|
rc-update add buildkitd default 2>/dev/null || true
|
||||||
|
rc-service buildkitd start 2>/dev/null || true
|
||||||
|
|
||||||
|
# 4. Fix socket permissions + TCP proxy for gRPC access (persists across reboots)
|
||||||
|
- mode: system
|
||||||
|
script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eux
|
||||||
|
apk add --no-cache socat
|
||||||
|
mkdir -p /etc/local.d
|
||||||
|
cat > /etc/local.d/fix-sockets.start << 'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
# Wait for daemons
|
||||||
|
for i in $(seq 1 30); do
|
||||||
|
[ -S /run/buildkit/buildkitd.sock ] && break
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
# Fix permissions for Lima socket forwarding
|
||||||
|
chmod 755 /run/buildkit /run/containerd 2>/dev/null
|
||||||
|
chmod 666 /run/buildkit/buildkitd.sock /run/containerd/containerd.sock 2>/dev/null
|
||||||
|
# TCP proxy for gRPC (Lima socket forwarding breaks HTTP/2)
|
||||||
|
socat TCP4-LISTEN:2500,fork,reuseaddr UNIX-CONNECT:/run/containerd/containerd.sock &
|
||||||
|
socat TCP4-LISTEN:2501,fork,reuseaddr UNIX-CONNECT:/run/buildkit/buildkitd.sock &
|
||||||
|
EOF
|
||||||
|
chmod +x /etc/local.d/fix-sockets.start
|
||||||
|
rc-update add local default 2>/dev/null || true
|
||||||
|
/etc/local.d/fix-sockets.start
|
||||||
|
|
||||||
|
probes:
|
||||||
|
- script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eux
|
||||||
|
sudo test -S /run/containerd/containerd.sock
|
||||||
|
sudo chmod 755 /run/containerd 2>/dev/null
|
||||||
|
sudo chmod 666 /run/containerd/containerd.sock 2>/dev/null
|
||||||
|
hint: "Waiting for containerd socket"
|
||||||
|
- script: |
|
||||||
|
#!/bin/sh
|
||||||
|
set -eux
|
||||||
|
sudo test -S /run/buildkit/buildkitd.sock
|
||||||
|
sudo chmod 755 /run/buildkit 2>/dev/null
|
||||||
|
sudo chmod 666 /run/buildkit/buildkitd.sock 2>/dev/null
|
||||||
|
hint: "Waiting for BuildKit socket"
|
||||||
|
|
||||||
|
portForwards:
|
||||||
|
- guestSocket: "/run/buildkit/buildkitd.sock"
|
||||||
|
hostSocket: "{{.Dir}}/buildkitd.sock"
|
||||||
|
- guestSocket: "/run/containerd/containerd.sock"
|
||||||
|
hostSocket: "{{.Dir}}/containerd.sock"
|
||||||
19
wfe-buildkit-protos/Cargo.toml
Normal file
19
wfe-buildkit-protos/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
name = "wfe-buildkit-protos"
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
repository.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
|
description = "Generated gRPC stubs for the full BuildKit API"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tonic = "0.14"
|
||||||
|
tonic-prost = "0.14"
|
||||||
|
prost = "0.14"
|
||||||
|
prost-types = "0.14"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tonic-build = "0.14"
|
||||||
|
tonic-prost-build = "0.14"
|
||||||
|
prost-build = "0.14"
|
||||||
56
wfe-buildkit-protos/build.rs
Normal file
56
wfe-buildkit-protos/build.rs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
// Use Go-style import paths so protoc sees each file only once
|
||||||
|
let proto_dir = PathBuf::from("proto");
|
||||||
|
let go_prefix = "github.com/moby/buildkit";
|
||||||
|
|
||||||
|
let proto_files: Vec<PathBuf> = vec![
|
||||||
|
// Core control service (Solve, Status, ListWorkers, etc.)
|
||||||
|
"api/services/control/control.proto",
|
||||||
|
// Types
|
||||||
|
"api/types/worker.proto",
|
||||||
|
// Solver / LLB definitions
|
||||||
|
"solver/pb/ops.proto",
|
||||||
|
// Source policy
|
||||||
|
"sourcepolicy/pb/policy.proto",
|
||||||
|
// Session protocols
|
||||||
|
"session/auth/auth.proto",
|
||||||
|
"session/filesync/filesync.proto",
|
||||||
|
"session/secrets/secrets.proto",
|
||||||
|
"session/sshforward/ssh.proto",
|
||||||
|
"session/upload/upload.proto",
|
||||||
|
"session/exporter/exporter.proto",
|
||||||
|
// Utilities
|
||||||
|
"util/apicaps/pb/caps.proto",
|
||||||
|
"util/stack/stack.proto",
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.map(|p| proto_dir.join(go_prefix).join(p))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"cargo:warning=Compiling {} buildkit proto files",
|
||||||
|
proto_files.len()
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut prost_config = prost_build::Config::new();
|
||||||
|
prost_config.include_file("mod.rs");
|
||||||
|
|
||||||
|
tonic_prost_build::configure()
|
||||||
|
.build_server(false)
|
||||||
|
.compile_with_config(
|
||||||
|
prost_config,
|
||||||
|
&proto_files,
|
||||||
|
// Include paths for import resolution:
|
||||||
|
// 1. The vendor dir inside buildkit (for Go-style github.com/... imports)
|
||||||
|
// 2. The buildkit root itself (for relative imports)
|
||||||
|
// 3. Our proto/ dir (for google/rpc/status.proto)
|
||||||
|
&[
|
||||||
|
// proto/ has symlinks that resolve Go-style github.com/... imports
|
||||||
|
PathBuf::from("proto"),
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.runhcs.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options";
|
||||||
|
|
||||||
|
// Options are the set of customizations that can be passed at Create time.
|
||||||
|
message Options {
|
||||||
|
// Enable debug tracing (sets the logrus log level to debug). This may be deprecated in the future, prefer
|
||||||
|
// log_level as this will override debug if both of them are set.
|
||||||
|
bool debug = 1;
|
||||||
|
|
||||||
|
enum DebugType {
|
||||||
|
NPIPE = 0;
|
||||||
|
FILE = 1;
|
||||||
|
ETW = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// debug tracing output type
|
||||||
|
DebugType debug_type = 2;
|
||||||
|
|
||||||
|
// registry key root for storage of the runhcs container state
|
||||||
|
string registry_root = 3;
|
||||||
|
|
||||||
|
// sandbox_image is the image to use for the sandbox that matches the
|
||||||
|
// sandbox_platform.
|
||||||
|
string sandbox_image = 4;
|
||||||
|
|
||||||
|
// sandbox_platform is a CRI setting that specifies the platform
|
||||||
|
// architecture for all sandbox's in this runtime. Values are
|
||||||
|
// 'windows/amd64' and 'linux/amd64'.
|
||||||
|
string sandbox_platform = 5;
|
||||||
|
|
||||||
|
enum SandboxIsolation {
|
||||||
|
PROCESS = 0;
|
||||||
|
HYPERVISOR = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sandbox_isolation is a CRI setting that specifies the isolation level of
|
||||||
|
// the sandbox. For Windows runtime PROCESS and HYPERVISOR are valid. For
|
||||||
|
// LCOW only HYPERVISOR is valid and default if omitted.
|
||||||
|
SandboxIsolation sandbox_isolation = 6;
|
||||||
|
|
||||||
|
// boot_files_root_path is the path to the directory containing the LCOW
|
||||||
|
// kernel and root FS files.
|
||||||
|
string boot_files_root_path = 7;
|
||||||
|
|
||||||
|
// vm_processor_count is the default number of processors to create for the
|
||||||
|
// hypervisor isolated utility vm.
|
||||||
|
//
|
||||||
|
// The platform default if omitted is 2, unless the host only has a single
|
||||||
|
// core in which case it is 1.
|
||||||
|
int32 vm_processor_count = 8;
|
||||||
|
|
||||||
|
// vm_memory_size_in_mb is the default amount of memory to assign to the
|
||||||
|
// hypervisor isolated utility vm.
|
||||||
|
//
|
||||||
|
// The platform default is 1024MB if omitted.
|
||||||
|
int32 vm_memory_size_in_mb = 9;
|
||||||
|
|
||||||
|
// GPUVHDPath is the path to the gpu vhd to add to the uvm
|
||||||
|
// when a container requests a gpu
|
||||||
|
string GPUVHDPath = 10;
|
||||||
|
|
||||||
|
// scale_cpu_limits_to_sandbox indicates that container CPU limits should
|
||||||
|
// be adjusted to account for the difference in number of cores between the
|
||||||
|
// host and UVM.
|
||||||
|
bool scale_cpu_limits_to_sandbox = 11;
|
||||||
|
|
||||||
|
// default_container_scratch_size_in_gb is the default scratch size (sandbox.vhdx)
|
||||||
|
// to be used for containers. Every container will get a sandbox of `size_in_gb` assigned
|
||||||
|
// instead of the default of 20GB.
|
||||||
|
int32 default_container_scratch_size_in_gb = 12;
|
||||||
|
|
||||||
|
// default_vm_scratch_size_in_gb is the default scratch size (sandbox.vhdx)
|
||||||
|
// to be used for the UVM. This only applies to WCOW as LCOW doesn't mount a scratch
|
||||||
|
// specifically for the UVM.
|
||||||
|
int32 default_vm_scratch_size_in_gb = 13;
|
||||||
|
|
||||||
|
// share_scratch specifies if we'd like to reuse scratch space between multiple containers.
|
||||||
|
// This currently only affects LCOW. The sandbox containers scratch space is re-used for all
|
||||||
|
// subsequent containers launched in the pod.
|
||||||
|
bool share_scratch = 14;
|
||||||
|
|
||||||
|
// NCProxyAddr is the address of the network configuration proxy service. If omitted
|
||||||
|
// the network is setup locally.
|
||||||
|
string NCProxyAddr = 15;
|
||||||
|
|
||||||
|
// log_level specifies the logrus log level for the shim. Supported values are a string representation of the
|
||||||
|
// logrus log levels: "trace", "debug", "info", "warn", "error", "fatal", "panic". This setting will override
|
||||||
|
// the `debug` field if both are specified, unless the level specified is also "debug", as these are equivalent.
|
||||||
|
string log_level = 16;
|
||||||
|
|
||||||
|
// io_retry_timeout_in_sec is the timeout in seconds for how long to try and reconnect to an upstream IO provider if a connection is lost.
|
||||||
|
// The typical example is if Containerd has restarted but is expected to come back online. A 0 for this field is interpreted as an infinite
|
||||||
|
// timeout.
|
||||||
|
int32 io_retry_timeout_in_sec = 17;
|
||||||
|
|
||||||
|
// default_container_annotations specifies a set of annotations that should be set for every workload container
|
||||||
|
map<string, string> default_container_annotations = 18;
|
||||||
|
|
||||||
|
// no_inherit_host_timezone specifies to skip inheriting the hosts time zone for WCOW UVMs and instead default to
|
||||||
|
// UTC.
|
||||||
|
bool no_inherit_host_timezone = 19;
|
||||||
|
|
||||||
|
// scrub_logs enables removing environment variables and other potentially sensitive information from logs
|
||||||
|
bool scrub_logs = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessDetails contains additional information about a process. This is the additional
|
||||||
|
// info returned in the Pids query.
|
||||||
|
message ProcessDetails {
|
||||||
|
string image_name = 1;
|
||||||
|
google.protobuf.Timestamp created_at = 2;
|
||||||
|
uint64 kernel_time_100_ns = 3;
|
||||||
|
uint64 memory_commit_bytes = 4;
|
||||||
|
uint64 memory_working_set_private_bytes = 5;
|
||||||
|
uint64 memory_working_set_shared_bytes = 6;
|
||||||
|
uint32 process_id = 7;
|
||||||
|
uint64 user_time_100_ns = 8;
|
||||||
|
string exec_id = 9;
|
||||||
|
}
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package io.containerd.cgroups.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/cgroups/cgroup1/stats";
|
||||||
|
|
||||||
|
message Metrics {
|
||||||
|
repeated HugetlbStat hugetlb = 1;
|
||||||
|
PidsStat pids = 2;
|
||||||
|
CPUStat cpu = 3;
|
||||||
|
MemoryStat memory = 4;
|
||||||
|
BlkIOStat blkio = 5;
|
||||||
|
RdmaStat rdma = 6;
|
||||||
|
repeated NetworkStat network = 7;
|
||||||
|
CgroupStats cgroup_stats = 8;
|
||||||
|
MemoryOomControl memory_oom_control = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message HugetlbStat {
|
||||||
|
uint64 usage = 1;
|
||||||
|
uint64 max = 2;
|
||||||
|
uint64 failcnt = 3;
|
||||||
|
string pagesize = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PidsStat {
|
||||||
|
uint64 current = 1;
|
||||||
|
uint64 limit = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CPUStat {
|
||||||
|
CPUUsage usage = 1;
|
||||||
|
Throttle throttling = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CPUUsage {
|
||||||
|
// values in nanoseconds
|
||||||
|
uint64 total = 1;
|
||||||
|
uint64 kernel = 2;
|
||||||
|
uint64 user = 3;
|
||||||
|
repeated uint64 per_cpu = 4;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
message Throttle {
|
||||||
|
uint64 periods = 1;
|
||||||
|
uint64 throttled_periods = 2;
|
||||||
|
uint64 throttled_time = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MemoryStat {
|
||||||
|
uint64 cache = 1;
|
||||||
|
uint64 rss = 2;
|
||||||
|
uint64 rss_huge = 3;
|
||||||
|
uint64 mapped_file = 4;
|
||||||
|
uint64 dirty = 5;
|
||||||
|
uint64 writeback = 6;
|
||||||
|
uint64 pg_pg_in = 7;
|
||||||
|
uint64 pg_pg_out = 8;
|
||||||
|
uint64 pg_fault = 9;
|
||||||
|
uint64 pg_maj_fault = 10;
|
||||||
|
uint64 inactive_anon = 11;
|
||||||
|
uint64 active_anon = 12;
|
||||||
|
uint64 inactive_file = 13;
|
||||||
|
uint64 active_file = 14;
|
||||||
|
uint64 unevictable = 15;
|
||||||
|
uint64 hierarchical_memory_limit = 16;
|
||||||
|
uint64 hierarchical_swap_limit = 17;
|
||||||
|
uint64 total_cache = 18;
|
||||||
|
uint64 total_rss = 19;
|
||||||
|
uint64 total_rss_huge = 20;
|
||||||
|
uint64 total_mapped_file = 21;
|
||||||
|
uint64 total_dirty = 22;
|
||||||
|
uint64 total_writeback = 23;
|
||||||
|
uint64 total_pg_pg_in = 24;
|
||||||
|
uint64 total_pg_pg_out = 25;
|
||||||
|
uint64 total_pg_fault = 26;
|
||||||
|
uint64 total_pg_maj_fault = 27;
|
||||||
|
uint64 total_inactive_anon = 28;
|
||||||
|
uint64 total_active_anon = 29;
|
||||||
|
uint64 total_inactive_file = 30;
|
||||||
|
uint64 total_active_file = 31;
|
||||||
|
uint64 total_unevictable = 32;
|
||||||
|
MemoryEntry usage = 33;
|
||||||
|
MemoryEntry swap = 34;
|
||||||
|
MemoryEntry kernel = 35;
|
||||||
|
MemoryEntry kernel_tcp = 36;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
message MemoryEntry {
|
||||||
|
uint64 limit = 1;
|
||||||
|
uint64 usage = 2;
|
||||||
|
uint64 max = 3;
|
||||||
|
uint64 failcnt = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MemoryOomControl {
|
||||||
|
uint64 oom_kill_disable = 1;
|
||||||
|
uint64 under_oom = 2;
|
||||||
|
uint64 oom_kill = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BlkIOStat {
|
||||||
|
repeated BlkIOEntry io_service_bytes_recursive = 1;
|
||||||
|
repeated BlkIOEntry io_serviced_recursive = 2;
|
||||||
|
repeated BlkIOEntry io_queued_recursive = 3;
|
||||||
|
repeated BlkIOEntry io_service_time_recursive = 4;
|
||||||
|
repeated BlkIOEntry io_wait_time_recursive = 5;
|
||||||
|
repeated BlkIOEntry io_merged_recursive = 6;
|
||||||
|
repeated BlkIOEntry io_time_recursive = 7;
|
||||||
|
repeated BlkIOEntry sectors_recursive = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BlkIOEntry {
|
||||||
|
string op = 1;
|
||||||
|
string device = 2;
|
||||||
|
uint64 major = 3;
|
||||||
|
uint64 minor = 4;
|
||||||
|
uint64 value = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RdmaStat {
|
||||||
|
repeated RdmaEntry current = 1;
|
||||||
|
repeated RdmaEntry limit = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RdmaEntry {
|
||||||
|
string device = 1;
|
||||||
|
uint32 hca_handles = 2;
|
||||||
|
uint32 hca_objects = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NetworkStat {
|
||||||
|
string name = 1;
|
||||||
|
uint64 rx_bytes = 2;
|
||||||
|
uint64 rx_packets = 3;
|
||||||
|
uint64 rx_errors = 4;
|
||||||
|
uint64 rx_dropped = 5;
|
||||||
|
uint64 tx_bytes = 6;
|
||||||
|
uint64 tx_packets = 7;
|
||||||
|
uint64 tx_errors = 8;
|
||||||
|
uint64 tx_dropped = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CgroupStats exports per-cgroup statistics.
|
||||||
|
message CgroupStats {
|
||||||
|
// number of tasks sleeping
|
||||||
|
uint64 nr_sleeping = 1;
|
||||||
|
// number of tasks running
|
||||||
|
uint64 nr_running = 2;
|
||||||
|
// number of tasks in stopped state
|
||||||
|
uint64 nr_stopped = 3;
|
||||||
|
// number of tasks in uninterruptible state
|
||||||
|
uint64 nr_uninterruptible = 4;
|
||||||
|
// number of tasks waiting on IO
|
||||||
|
uint64 nr_io_wait = 5;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message ContainerCreate {
|
||||||
|
string id = 1;
|
||||||
|
string image = 2;
|
||||||
|
message Runtime {
|
||||||
|
string name = 1;
|
||||||
|
google.protobuf.Any options = 2;
|
||||||
|
}
|
||||||
|
Runtime runtime = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ContainerUpdate {
|
||||||
|
string id = 1;
|
||||||
|
string image = 2;
|
||||||
|
map<string, string> labels = 3;
|
||||||
|
string snapshot_key = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ContainerDelete {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message ContentCreate {
|
||||||
|
string digest = 1;
|
||||||
|
int64 size = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ContentDelete {
|
||||||
|
string digest = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.images.v1;
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message ImageCreate {
|
||||||
|
string name = 1;
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ImageUpdate {
|
||||||
|
string name = 1;
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ImageDelete {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message NamespaceCreate {
|
||||||
|
string name = 1;
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NamespaceUpdate {
|
||||||
|
string name = 1;
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NamespaceDelete {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
|
||||||
|
message SandboxCreate {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SandboxStart {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SandboxExit {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
uint32 exit_status = 2;
|
||||||
|
google.protobuf.Timestamp exited_at = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message SnapshotPrepare {
|
||||||
|
string key = 1;
|
||||||
|
string parent = 2;
|
||||||
|
string snapshotter = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SnapshotCommit {
|
||||||
|
string key = 1;
|
||||||
|
string name = 2;
|
||||||
|
string snapshotter = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SnapshotRemove {
|
||||||
|
string key = 1;
|
||||||
|
string snapshotter = 5;
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/mount.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message TaskCreate {
|
||||||
|
string container_id = 1;
|
||||||
|
string bundle = 2;
|
||||||
|
repeated containerd.types.Mount rootfs = 3;
|
||||||
|
TaskIO io = 4;
|
||||||
|
string checkpoint = 5;
|
||||||
|
uint32 pid = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskStart {
|
||||||
|
string container_id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskDelete {
|
||||||
|
string container_id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
uint32 exit_status = 3;
|
||||||
|
google.protobuf.Timestamp exited_at = 4;
|
||||||
|
// id is the specific exec. By default if omitted will be `""` thus matches
|
||||||
|
// the init exec of the task matching `container_id`.
|
||||||
|
string id = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskIO {
|
||||||
|
string stdin = 1;
|
||||||
|
string stdout = 2;
|
||||||
|
string stderr = 3;
|
||||||
|
bool terminal = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskExit {
|
||||||
|
string container_id = 1;
|
||||||
|
string id = 2;
|
||||||
|
uint32 pid = 3;
|
||||||
|
uint32 exit_status = 4;
|
||||||
|
google.protobuf.Timestamp exited_at = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskOOM {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskExecAdded {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskExecStarted {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
uint32 pid = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskPaused {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskResumed {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskCheckpointed {
|
||||||
|
string container_id = 1;
|
||||||
|
string checkpoint = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.runtime.sandbox.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/mount.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/platform.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/metrics.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/runtime/sandbox/v1;sandbox";
|
||||||
|
|
||||||
|
// Sandbox is an optional interface that shim may implement to support sandboxes environments.
|
||||||
|
// A typical example of sandbox is microVM or pause container - an entity that groups containers and/or
|
||||||
|
// holds resources relevant for this group.
|
||||||
|
service Sandbox {
|
||||||
|
// CreateSandbox will be called right after sandbox shim instance launched.
|
||||||
|
// It is a good place to initialize sandbox environment.
|
||||||
|
rpc CreateSandbox(CreateSandboxRequest) returns (CreateSandboxResponse);
|
||||||
|
|
||||||
|
// StartSandbox will start a previously created sandbox.
|
||||||
|
rpc StartSandbox(StartSandboxRequest) returns (StartSandboxResponse);
|
||||||
|
|
||||||
|
// Platform queries the platform the sandbox is going to run containers on.
|
||||||
|
// containerd will use this to generate a proper OCI spec.
|
||||||
|
rpc Platform(PlatformRequest) returns (PlatformResponse);
|
||||||
|
|
||||||
|
// StopSandbox will stop existing sandbox instance
|
||||||
|
rpc StopSandbox(StopSandboxRequest) returns (StopSandboxResponse);
|
||||||
|
|
||||||
|
// WaitSandbox blocks until sandbox exits.
|
||||||
|
rpc WaitSandbox(WaitSandboxRequest) returns (WaitSandboxResponse);
|
||||||
|
|
||||||
|
// SandboxStatus will return current status of the running sandbox instance
|
||||||
|
rpc SandboxStatus(SandboxStatusRequest) returns (SandboxStatusResponse);
|
||||||
|
|
||||||
|
// PingSandbox is a lightweight API call to check whether sandbox alive.
|
||||||
|
rpc PingSandbox(PingRequest) returns (PingResponse);
|
||||||
|
|
||||||
|
// ShutdownSandbox must shutdown shim instance.
|
||||||
|
rpc ShutdownSandbox(ShutdownSandboxRequest) returns (ShutdownSandboxResponse);
|
||||||
|
|
||||||
|
// SandboxMetrics retrieves metrics about a sandbox instance.
|
||||||
|
rpc SandboxMetrics(SandboxMetricsRequest) returns (SandboxMetricsResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
string bundle_path = 2;
|
||||||
|
repeated containerd.types.Mount rootfs = 3;
|
||||||
|
google.protobuf.Any options = 4;
|
||||||
|
string netns_path = 5;
|
||||||
|
map<string, string> annotations = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateSandboxResponse {}
|
||||||
|
|
||||||
|
message StartSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartSandboxResponse {
|
||||||
|
uint32 pid = 1;
|
||||||
|
google.protobuf.Timestamp created_at = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PlatformRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PlatformResponse {
|
||||||
|
containerd.types.Platform platform = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StopSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
uint32 timeout_secs = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StopSandboxResponse {}
|
||||||
|
|
||||||
|
message UpdateSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
google.protobuf.Any resources = 2;
|
||||||
|
map<string, string> annotations = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitSandboxResponse {
|
||||||
|
uint32 exit_status = 1;
|
||||||
|
google.protobuf.Timestamp exited_at = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateSandboxResponse {}
|
||||||
|
|
||||||
|
message SandboxStatusRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
bool verbose = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SandboxStatusResponse {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
string state = 3;
|
||||||
|
map<string, string> info = 4;
|
||||||
|
google.protobuf.Timestamp created_at = 5;
|
||||||
|
google.protobuf.Timestamp exited_at = 6;
|
||||||
|
google.protobuf.Any extra = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PingRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PingResponse {}
|
||||||
|
|
||||||
|
message ShutdownSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShutdownSandboxResponse {}
|
||||||
|
|
||||||
|
message SandboxMetricsRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SandboxMetricsResponse {
|
||||||
|
containerd.types.Metric metrics = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.containers.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/containers/v1;containers";
|
||||||
|
|
||||||
|
// Containers provides metadata storage for containers used in the execution
|
||||||
|
// service.
|
||||||
|
//
|
||||||
|
// The objects here provide an state-independent view of containers for use in
|
||||||
|
// management and resource pinning. From that perspective, containers do not
|
||||||
|
// have a "state" but rather this is the set of resources that will be
|
||||||
|
// considered in use by the container.
|
||||||
|
//
|
||||||
|
// From the perspective of the execution service, these objects represent the
|
||||||
|
// base parameters for creating a container process.
|
||||||
|
//
|
||||||
|
// In general, when looking to add fields for this type, first ask yourself
|
||||||
|
// whether or not the function of the field has to do with runtime execution or
|
||||||
|
// is invariant of the runtime state of the container. If it has to do with
|
||||||
|
// runtime, or changes as the "container" is started and stops, it probably
|
||||||
|
// doesn't belong on this object.
|
||||||
|
service Containers {
|
||||||
|
rpc Get(GetContainerRequest) returns (GetContainerResponse);
|
||||||
|
rpc List(ListContainersRequest) returns (ListContainersResponse);
|
||||||
|
rpc ListStream(ListContainersRequest) returns (stream ListContainerMessage);
|
||||||
|
rpc Create(CreateContainerRequest) returns (CreateContainerResponse);
|
||||||
|
rpc Update(UpdateContainerRequest) returns (UpdateContainerResponse);
|
||||||
|
rpc Delete(DeleteContainerRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Container {
|
||||||
|
// ID is the user-specified identifier.
|
||||||
|
//
|
||||||
|
// This field may not be updated.
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
// Labels provides an area to include arbitrary data on containers.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
//
|
||||||
|
// Note that to add a new value to this field, read the existing set and
|
||||||
|
// include the entire result in the update call.
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
|
||||||
|
// Image contains the reference of the image used to build the
|
||||||
|
// specification and snapshots for running this container.
|
||||||
|
//
|
||||||
|
// If this field is updated, the spec and rootfs needed to updated, as well.
|
||||||
|
string image = 3;
|
||||||
|
|
||||||
|
message Runtime {
|
||||||
|
// Name is the name of the runtime.
|
||||||
|
string name = 1;
|
||||||
|
// Options specify additional runtime initialization options.
|
||||||
|
google.protobuf.Any options = 2;
|
||||||
|
}
|
||||||
|
// Runtime specifies which runtime to use for executing this container.
|
||||||
|
Runtime runtime = 4;
|
||||||
|
|
||||||
|
// Spec to be used when creating the container. This is runtime specific.
|
||||||
|
google.protobuf.Any spec = 5;
|
||||||
|
|
||||||
|
// Snapshotter specifies the snapshotter name used for rootfs
|
||||||
|
string snapshotter = 6;
|
||||||
|
|
||||||
|
// SnapshotKey specifies the snapshot key to use for the container's root
|
||||||
|
// filesystem. When starting a task from this container, a caller should
|
||||||
|
// look up the mounts from the snapshot service and include those on the
|
||||||
|
// task create request.
|
||||||
|
//
|
||||||
|
// Snapshots referenced in this field will not be garbage collected.
|
||||||
|
//
|
||||||
|
// This field is set to empty when the rootfs is not a snapshot.
|
||||||
|
//
|
||||||
|
// This field may be updated.
|
||||||
|
string snapshot_key = 7;
|
||||||
|
|
||||||
|
// CreatedAt is the time the container was first created.
|
||||||
|
google.protobuf.Timestamp created_at = 8;
|
||||||
|
|
||||||
|
// UpdatedAt is the last time the container was mutated.
|
||||||
|
google.protobuf.Timestamp updated_at = 9;
|
||||||
|
|
||||||
|
// Extensions allow clients to provide zero or more blobs that are directly
|
||||||
|
// associated with the container. One may provide protobuf, json, or other
|
||||||
|
// encoding formats. The primary use of this is to further decorate the
|
||||||
|
// container object with fields that may be specific to a client integration.
|
||||||
|
//
|
||||||
|
// The key portion of this map should identify a "name" for the extension
|
||||||
|
// that should be unique against other extensions. When updating extension
|
||||||
|
// data, one should only update the specified extension using field paths
|
||||||
|
// to select a specific map key.
|
||||||
|
map<string, google.protobuf.Any> extensions = 10;
|
||||||
|
|
||||||
|
// Sandbox ID this container belongs to.
|
||||||
|
string sandbox = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetContainerRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetContainerResponse {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContainersRequest {
|
||||||
|
// Filters contains one or more filters using the syntax defined in the
|
||||||
|
// containerd filter package.
|
||||||
|
//
|
||||||
|
// The returned result will be those that match any of the provided
|
||||||
|
// filters. Expanded, containers that match the following will be
|
||||||
|
// returned:
|
||||||
|
//
|
||||||
|
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||||
|
//
|
||||||
|
// If filters is zero-length or nil, all items will be returned.
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContainersResponse {
|
||||||
|
repeated Container containers = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateContainerRequest {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateContainerResponse {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateContainerRequest updates the metadata on one or more container.
|
||||||
|
//
|
||||||
|
// The operation should follow semantics described in
|
||||||
|
// https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/field-mask,
|
||||||
|
// unless otherwise qualified.
|
||||||
|
message UpdateContainerRequest {
|
||||||
|
// Container provides the target values, as declared by the mask, for the update.
|
||||||
|
//
|
||||||
|
// The ID field must be set.
|
||||||
|
Container container = 1;
|
||||||
|
|
||||||
|
// UpdateMask specifies which fields to perform the update on. If empty,
|
||||||
|
// the operation applies to all fields.
|
||||||
|
google.protobuf.FieldMask update_mask = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateContainerResponse {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteContainerRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContainerMessage {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,330 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.content.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/content/v1;content";
|
||||||
|
|
||||||
|
// Content provides access to a content addressable storage system.
|
||||||
|
service Content {
|
||||||
|
// Info returns information about a committed object.
|
||||||
|
//
|
||||||
|
// This call can be used for getting the size of content and checking for
|
||||||
|
// existence.
|
||||||
|
rpc Info(InfoRequest) returns (InfoResponse);
|
||||||
|
|
||||||
|
// Update updates content metadata.
|
||||||
|
//
|
||||||
|
// This call can be used to manage the mutable content labels. The
|
||||||
|
// immutable metadata such as digest, size, and committed at cannot
|
||||||
|
// be updated.
|
||||||
|
rpc Update(UpdateRequest) returns (UpdateResponse);
|
||||||
|
|
||||||
|
// List streams the entire set of content as Info objects and closes the
|
||||||
|
// stream.
|
||||||
|
//
|
||||||
|
// Typically, this will yield a large response, chunked into messages.
|
||||||
|
// Clients should make provisions to ensure they can handle the entire data
|
||||||
|
// set.
|
||||||
|
rpc List(ListContentRequest) returns (stream ListContentResponse);
|
||||||
|
|
||||||
|
// Delete will delete the referenced object.
|
||||||
|
rpc Delete(DeleteContentRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// Read allows one to read an object based on the offset into the content.
|
||||||
|
//
|
||||||
|
// The requested data may be returned in one or more messages.
|
||||||
|
rpc Read(ReadContentRequest) returns (stream ReadContentResponse);
|
||||||
|
|
||||||
|
// Status returns the status for a single reference.
|
||||||
|
rpc Status(StatusRequest) returns (StatusResponse);
|
||||||
|
|
||||||
|
// ListStatuses returns the status of ongoing object ingestions, started via
|
||||||
|
// Write.
|
||||||
|
//
|
||||||
|
// Only those matching the regular expression will be provided in the
|
||||||
|
// response. If the provided regular expression is empty, all ingestions
|
||||||
|
// will be provided.
|
||||||
|
rpc ListStatuses(ListStatusesRequest) returns (ListStatusesResponse);
|
||||||
|
|
||||||
|
// Write begins or resumes writes to a resource identified by a unique ref.
|
||||||
|
// Only one active stream may exist at a time for each ref.
|
||||||
|
//
|
||||||
|
// Once a write stream has started, it may only write to a single ref, thus
|
||||||
|
// once a stream is started, the ref may be omitted on subsequent writes.
|
||||||
|
//
|
||||||
|
// For any write transaction represented by a ref, only a single write may
|
||||||
|
// be made to a given offset. If overlapping writes occur, it is an error.
|
||||||
|
// Writes should be sequential and implementations may throw an error if
|
||||||
|
// this is required.
|
||||||
|
//
|
||||||
|
// If expected_digest is set and already part of the content store, the
|
||||||
|
// write will fail.
|
||||||
|
//
|
||||||
|
// When completed, the commit flag should be set to true. If expected size
|
||||||
|
// or digest is set, the content will be validated against those values.
|
||||||
|
rpc Write(stream WriteContentRequest) returns (stream WriteContentResponse);
|
||||||
|
|
||||||
|
// Abort cancels the ongoing write named in the request. Any resources
|
||||||
|
// associated with the write will be collected.
|
||||||
|
rpc Abort(AbortRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Info {
|
||||||
|
// Digest is the hash identity of the blob.
|
||||||
|
string digest = 1;
|
||||||
|
|
||||||
|
// Size is the total number of bytes in the blob.
|
||||||
|
int64 size = 2;
|
||||||
|
|
||||||
|
// CreatedAt provides the time at which the blob was committed.
|
||||||
|
google.protobuf.Timestamp created_at = 3;
|
||||||
|
|
||||||
|
// UpdatedAt provides the time the info was last updated.
|
||||||
|
google.protobuf.Timestamp updated_at = 4;
|
||||||
|
|
||||||
|
// Labels are arbitrary data on snapshots.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InfoRequest {
|
||||||
|
string digest = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InfoResponse {
|
||||||
|
Info info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateRequest {
|
||||||
|
Info info = 1;
|
||||||
|
|
||||||
|
// UpdateMask specifies which fields to perform the update on. If empty,
|
||||||
|
// the operation applies to all fields.
|
||||||
|
//
|
||||||
|
// In info, Digest, Size, and CreatedAt are immutable,
|
||||||
|
// other field may be updated using this mask.
|
||||||
|
// If no mask is provided, all mutable field are updated.
|
||||||
|
google.protobuf.FieldMask update_mask = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateResponse {
|
||||||
|
Info info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContentRequest {
|
||||||
|
// Filters contains one or more filters using the syntax defined in the
|
||||||
|
// containerd filter package.
|
||||||
|
//
|
||||||
|
// The returned result will be those that match any of the provided
|
||||||
|
// filters. Expanded, containers that match the following will be
|
||||||
|
// returned:
|
||||||
|
//
|
||||||
|
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||||
|
//
|
||||||
|
// If filters is zero-length or nil, all items will be returned.
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContentResponse {
|
||||||
|
repeated Info info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteContentRequest {
|
||||||
|
// Digest specifies which content to delete.
|
||||||
|
string digest = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadContentRequest defines the fields that make up a request to read a portion of
|
||||||
|
// data from a stored object.
|
||||||
|
message ReadContentRequest {
|
||||||
|
// Digest is the hash identity to read.
|
||||||
|
string digest = 1;
|
||||||
|
|
||||||
|
// Offset specifies the number of bytes from the start at which to begin
|
||||||
|
// the read. If zero or less, the read will be from the start. This uses
|
||||||
|
// standard zero-indexed semantics.
|
||||||
|
int64 offset = 2;
|
||||||
|
|
||||||
|
// size is the total size of the read. If zero, the entire blob will be
|
||||||
|
// returned by the service.
|
||||||
|
int64 size = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadContentResponse carries byte data for a read request.
|
||||||
|
message ReadContentResponse {
|
||||||
|
int64 offset = 1; // offset of the returned data
|
||||||
|
bytes data = 2; // actual data
|
||||||
|
}
|
||||||
|
|
||||||
|
message Status {
|
||||||
|
google.protobuf.Timestamp started_at = 1;
|
||||||
|
google.protobuf.Timestamp updated_at = 2;
|
||||||
|
string ref = 3;
|
||||||
|
int64 offset = 4;
|
||||||
|
int64 total = 5;
|
||||||
|
string expected = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message StatusRequest {
|
||||||
|
string ref = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatusResponse {
|
||||||
|
Status status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListStatusesRequest {
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListStatusesResponse {
|
||||||
|
repeated Status statuses = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteAction defines the behavior of a WriteRequest.
|
||||||
|
enum WriteAction {
|
||||||
|
// WriteActionStat instructs the writer to return the current status while
|
||||||
|
// holding the lock on the write.
|
||||||
|
STAT = 0;
|
||||||
|
|
||||||
|
// WriteActionWrite sets the action for the write request to write data.
|
||||||
|
//
|
||||||
|
// Any data included will be written at the provided offset. The
|
||||||
|
// transaction will be left open for further writes.
|
||||||
|
//
|
||||||
|
// This is the default.
|
||||||
|
WRITE = 1;
|
||||||
|
|
||||||
|
// WriteActionCommit will write any outstanding data in the message and
|
||||||
|
// commit the write, storing it under the digest.
|
||||||
|
//
|
||||||
|
// This can be used in a single message to send the data, verify it and
|
||||||
|
// commit it.
|
||||||
|
//
|
||||||
|
// This action will always terminate the write.
|
||||||
|
COMMIT = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteContentRequest writes data to the request ref at offset.
|
||||||
|
message WriteContentRequest {
|
||||||
|
// Action sets the behavior of the write.
|
||||||
|
//
|
||||||
|
// When this is a write and the ref is not yet allocated, the ref will be
|
||||||
|
// allocated and the data will be written at offset.
|
||||||
|
//
|
||||||
|
// If the action is write and the ref is allocated, it will accept data to
|
||||||
|
// an offset that has not yet been written.
|
||||||
|
//
|
||||||
|
// If the action is write and there is no data, the current write status
|
||||||
|
// will be returned. This works differently from status because the stream
|
||||||
|
// holds a lock.
|
||||||
|
WriteAction action = 1;
|
||||||
|
|
||||||
|
// Ref identifies the pre-commit object to write to.
|
||||||
|
string ref = 2;
|
||||||
|
|
||||||
|
// Total can be set to have the service validate the total size of the
|
||||||
|
// committed content.
|
||||||
|
//
|
||||||
|
// The latest value before or with the commit action message will be use to
|
||||||
|
// validate the content. If the offset overflows total, the service may
|
||||||
|
// report an error. It is only required on one message for the write.
|
||||||
|
//
|
||||||
|
// If the value is zero or less, no validation of the final content will be
|
||||||
|
// performed.
|
||||||
|
int64 total = 3;
|
||||||
|
|
||||||
|
// Expected can be set to have the service validate the final content against
|
||||||
|
// the provided digest.
|
||||||
|
//
|
||||||
|
// If the digest is already present in the object store, an AlreadyExists
|
||||||
|
// error will be returned.
|
||||||
|
//
|
||||||
|
// Only the latest version will be used to check the content against the
|
||||||
|
// digest. It is only required to include it on a single message, before or
|
||||||
|
// with the commit action message.
|
||||||
|
string expected = 4;
|
||||||
|
|
||||||
|
// Offset specifies the number of bytes from the start at which to begin
|
||||||
|
// the write. For most implementations, this means from the start of the
|
||||||
|
// file. This uses standard, zero-indexed semantics.
|
||||||
|
//
|
||||||
|
// If the action is write, the remote may remove all previously written
|
||||||
|
// data after the offset. Implementations may support arbitrary offsets but
|
||||||
|
// MUST support reseting this value to zero with a write. If an
|
||||||
|
// implementation does not support a write at a particular offset, an
|
||||||
|
// OutOfRange error must be returned.
|
||||||
|
int64 offset = 5;
|
||||||
|
|
||||||
|
// Data is the actual bytes to be written.
|
||||||
|
//
|
||||||
|
// If this is empty and the message is not a commit, a response will be
|
||||||
|
// returned with the current write state.
|
||||||
|
bytes data = 6;
|
||||||
|
|
||||||
|
// Labels are arbitrary data on snapshots.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteContentResponse is returned on the culmination of a write call.
|
||||||
|
message WriteContentResponse {
|
||||||
|
// Action contains the action for the final message of the stream. A writer
|
||||||
|
// should confirm that they match the intended result.
|
||||||
|
WriteAction action = 1;
|
||||||
|
|
||||||
|
// StartedAt provides the time at which the write began.
|
||||||
|
//
|
||||||
|
// This must be set for stat and commit write actions. All other write
|
||||||
|
// actions may omit this.
|
||||||
|
google.protobuf.Timestamp started_at = 2;
|
||||||
|
|
||||||
|
// UpdatedAt provides the last time of a successful write.
|
||||||
|
//
|
||||||
|
// This must be set for stat and commit write actions. All other write
|
||||||
|
// actions may omit this.
|
||||||
|
google.protobuf.Timestamp updated_at = 3;
|
||||||
|
|
||||||
|
// Offset is the current committed size for the write.
|
||||||
|
int64 offset = 4;
|
||||||
|
|
||||||
|
// Total provides the current, expected total size of the write.
|
||||||
|
//
|
||||||
|
// We include this to provide consistency with the Status structure on the
|
||||||
|
// client writer.
|
||||||
|
//
|
||||||
|
// This is only valid on the Stat and Commit response.
|
||||||
|
int64 total = 5;
|
||||||
|
|
||||||
|
// Digest, if present, includes the digest up to the currently committed
|
||||||
|
// bytes. If action is commit, this field will be set. It is implementation
|
||||||
|
// defined if this is set for other actions.
|
||||||
|
string digest = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AbortRequest {
|
||||||
|
string ref = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.diff.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/mount.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/descriptor.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/diff/v1;diff";
|
||||||
|
|
||||||
|
// Diff service creates and applies diffs
|
||||||
|
service Diff {
|
||||||
|
// Apply applies the content associated with the provided digests onto
|
||||||
|
// the provided mounts. Archive content will be extracted and
|
||||||
|
// decompressed if necessary.
|
||||||
|
rpc Apply(ApplyRequest) returns (ApplyResponse);
|
||||||
|
|
||||||
|
// Diff creates a diff between the given mounts and uploads the result
|
||||||
|
// to the content store.
|
||||||
|
rpc Diff(DiffRequest) returns (DiffResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message ApplyRequest {
|
||||||
|
// Diff is the descriptor of the diff to be extracted
|
||||||
|
containerd.types.Descriptor diff = 1;
|
||||||
|
|
||||||
|
repeated containerd.types.Mount mounts = 2;
|
||||||
|
|
||||||
|
map<string, google.protobuf.Any> payloads = 3;
|
||||||
|
// SyncFs is to synchronize the underlying filesystem containing files.
|
||||||
|
bool sync_fs = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ApplyResponse {
|
||||||
|
// Applied is the descriptor for the object which was applied.
|
||||||
|
// If the input was a compressed blob then the result will be
|
||||||
|
// the descriptor for the uncompressed blob.
|
||||||
|
containerd.types.Descriptor applied = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DiffRequest {
|
||||||
|
// Left are the mounts which represent the older copy
|
||||||
|
// in which is the base of the computed changes.
|
||||||
|
repeated containerd.types.Mount left = 1;
|
||||||
|
|
||||||
|
// Right are the mounts which represents the newer copy
|
||||||
|
// in which changes from the left were made into.
|
||||||
|
repeated containerd.types.Mount right = 2;
|
||||||
|
|
||||||
|
// MediaType is the media type descriptor for the created diff
|
||||||
|
// object
|
||||||
|
string media_type = 3;
|
||||||
|
|
||||||
|
// Ref identifies the pre-commit content store object. This
|
||||||
|
// reference can be used to get the status from the content store.
|
||||||
|
string ref = 4;
|
||||||
|
|
||||||
|
// Labels are the labels to apply to the generated content
|
||||||
|
// on content store commit.
|
||||||
|
map<string, string> labels = 5;
|
||||||
|
|
||||||
|
// SourceDateEpoch specifies the timestamp used to provide control for reproducibility.
|
||||||
|
// See also https://reproducible-builds.org/docs/source-date-epoch/ .
|
||||||
|
//
|
||||||
|
// Since containerd v2.0, the whiteout timestamps are set to zero (1970-01-01),
|
||||||
|
// not to the source date epoch.
|
||||||
|
google.protobuf.Timestamp source_date_epoch = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DiffResponse {
|
||||||
|
// Diff is the descriptor of the diff which can be applied
|
||||||
|
containerd.types.Descriptor diff = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.events.v1;
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/event.proto";
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/events/v1;events";
|
||||||
|
|
||||||
|
service Events {
|
||||||
|
// Publish an event to a topic.
|
||||||
|
//
|
||||||
|
// The event will be packed into a timestamp envelope with the namespace
|
||||||
|
// introspected from the context. The envelope will then be dispatched.
|
||||||
|
rpc Publish(PublishRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// Forward sends an event that has already been packaged into an envelope
|
||||||
|
// with a timestamp and namespace.
|
||||||
|
//
|
||||||
|
// This is useful if earlier timestamping is required or when forwarding on
|
||||||
|
// behalf of another component, namespace or publisher.
|
||||||
|
rpc Forward(ForwardRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// Subscribe to a stream of events, possibly returning only that match any
|
||||||
|
// of the provided filters.
|
||||||
|
//
|
||||||
|
// Unlike many other methods in containerd, subscribers will get messages
|
||||||
|
// from all namespaces unless otherwise specified. If this is not desired,
|
||||||
|
// a filter can be provided in the format 'namespace==<namespace>' to
|
||||||
|
// restrict the received events.
|
||||||
|
rpc Subscribe(SubscribeRequest) returns (stream containerd.types.Envelope);
|
||||||
|
}
|
||||||
|
|
||||||
|
message PublishRequest {
|
||||||
|
string topic = 1;
|
||||||
|
google.protobuf.Any event = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ForwardRequest {
|
||||||
|
containerd.types.Envelope envelope = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SubscribeRequest {
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.images.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/descriptor.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/images/v1;images";
|
||||||
|
|
||||||
|
// Images is a service that allows one to register images with containerd.
|
||||||
|
//
|
||||||
|
// In containerd, an image is merely the mapping of a name to a content root,
|
||||||
|
// described by a descriptor. The behavior and state of image is purely
|
||||||
|
// dictated by the type of the descriptor.
|
||||||
|
//
|
||||||
|
// From the perspective of this service, these references are mostly shallow,
|
||||||
|
// in that the existence of the required content won't be validated until
|
||||||
|
// required by consuming services.
|
||||||
|
//
|
||||||
|
// As such, this can really be considered a "metadata service".
|
||||||
|
service Images {
|
||||||
|
// Get returns an image by name.
|
||||||
|
rpc Get(GetImageRequest) returns (GetImageResponse);
|
||||||
|
|
||||||
|
// List returns a list of all images known to containerd.
|
||||||
|
rpc List(ListImagesRequest) returns (ListImagesResponse);
|
||||||
|
|
||||||
|
// Create an image record in the metadata store.
|
||||||
|
//
|
||||||
|
// The name of the image must be unique.
|
||||||
|
rpc Create(CreateImageRequest) returns (CreateImageResponse);
|
||||||
|
|
||||||
|
// Update assigns the name to a given target image based on the provided
|
||||||
|
// image.
|
||||||
|
rpc Update(UpdateImageRequest) returns (UpdateImageResponse);
|
||||||
|
|
||||||
|
// Delete deletes the image by name.
|
||||||
|
rpc Delete(DeleteImageRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Image {
|
||||||
|
// Name provides a unique name for the image.
|
||||||
|
//
|
||||||
|
// Containerd treats this as the primary identifier.
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
// Labels provides free form labels for the image. These are runtime only
|
||||||
|
// and do not get inherited into the package image in any way.
|
||||||
|
//
|
||||||
|
// Labels may be updated using the field mask.
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
|
||||||
|
// Target describes the content entry point of the image.
|
||||||
|
containerd.types.Descriptor target = 3;
|
||||||
|
|
||||||
|
// CreatedAt is the time the image was first created.
|
||||||
|
google.protobuf.Timestamp created_at = 7;
|
||||||
|
|
||||||
|
// UpdatedAt is the last time the image was mutated.
|
||||||
|
google.protobuf.Timestamp updated_at = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetImageRequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetImageResponse {
|
||||||
|
Image image = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateImageRequest {
|
||||||
|
Image image = 1;
|
||||||
|
|
||||||
|
google.protobuf.Timestamp source_date_epoch = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateImageResponse {
|
||||||
|
Image image = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateImageRequest {
|
||||||
|
// Image provides a full or partial image for update.
|
||||||
|
//
|
||||||
|
// The name field must be set or an error will be returned.
|
||||||
|
Image image = 1;
|
||||||
|
|
||||||
|
// UpdateMask specifies which fields to perform the update on. If empty,
|
||||||
|
// the operation applies to all fields.
|
||||||
|
google.protobuf.FieldMask update_mask = 2;
|
||||||
|
|
||||||
|
google.protobuf.Timestamp source_date_epoch = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateImageResponse {
|
||||||
|
Image image = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListImagesRequest {
|
||||||
|
// Filters contains one or more filters using the syntax defined in the
|
||||||
|
// containerd filter package.
|
||||||
|
//
|
||||||
|
// The returned result will be those that match any of the provided
|
||||||
|
// filters. Expanded, images that match the following will be
|
||||||
|
// returned:
|
||||||
|
//
|
||||||
|
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||||
|
//
|
||||||
|
// If filters is zero-length or nil, all items will be returned.
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListImagesResponse {
|
||||||
|
repeated Image images = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteImageRequest {
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
// Sync indicates that the delete and cleanup should be done
|
||||||
|
// synchronously before returning to the caller
|
||||||
|
//
|
||||||
|
// Default is false
|
||||||
|
bool sync = 2;
|
||||||
|
|
||||||
|
// Target value for image to be deleted
|
||||||
|
//
|
||||||
|
// If image descriptor does not match the same digest,
|
||||||
|
// the delete operation will return "not found" error.
|
||||||
|
optional containerd.types.Descriptor target = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.introspection.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/introspection.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/platform.proto";
|
||||||
|
import "google/rpc/status.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/introspection/v1;introspection";
|
||||||
|
|
||||||
|
service Introspection {
|
||||||
|
// Plugins returns a list of plugins in containerd.
|
||||||
|
//
|
||||||
|
// Clients can use this to detect features and capabilities when using
|
||||||
|
// containerd.
|
||||||
|
rpc Plugins(PluginsRequest) returns (PluginsResponse);
|
||||||
|
// Server returns information about the containerd server
|
||||||
|
rpc Server(google.protobuf.Empty) returns (ServerResponse);
|
||||||
|
// PluginInfo returns information directly from a plugin if the plugin supports it
|
||||||
|
rpc PluginInfo(PluginInfoRequest) returns (PluginInfoResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Plugin {
|
||||||
|
// Type defines the type of plugin.
|
||||||
|
//
|
||||||
|
// See package plugin for a list of possible values. Non core plugins may
|
||||||
|
// define their own values during registration.
|
||||||
|
string type = 1;
|
||||||
|
|
||||||
|
// ID identifies the plugin uniquely in the system.
|
||||||
|
string id = 2;
|
||||||
|
|
||||||
|
// Requires lists the plugin types required by this plugin.
|
||||||
|
repeated string requires = 3;
|
||||||
|
|
||||||
|
// Platforms enumerates the platforms this plugin will support.
|
||||||
|
//
|
||||||
|
// If values are provided here, the plugin will only be operable under the
|
||||||
|
// provided platforms.
|
||||||
|
//
|
||||||
|
// If this is empty, the plugin will work across all platforms.
|
||||||
|
//
|
||||||
|
// If the plugin prefers certain platforms over others, they should be
|
||||||
|
// listed from most to least preferred.
|
||||||
|
repeated types.Platform platforms = 4;
|
||||||
|
|
||||||
|
// Exports allows plugins to provide values about state or configuration to
|
||||||
|
// interested parties.
|
||||||
|
//
|
||||||
|
// One example is exposing the configured path of a snapshotter plugin.
|
||||||
|
map<string, string> exports = 5;
|
||||||
|
|
||||||
|
// Capabilities allows plugins to communicate feature switches to allow
|
||||||
|
// clients to detect features that may not be on be default or may be
|
||||||
|
// different from version to version.
|
||||||
|
//
|
||||||
|
// Use this sparingly.
|
||||||
|
repeated string capabilities = 6;
|
||||||
|
|
||||||
|
// InitErr will be set if the plugin fails initialization.
|
||||||
|
//
|
||||||
|
// This means the plugin may have been registered but a non-terminal error
|
||||||
|
// was encountered during initialization.
|
||||||
|
//
|
||||||
|
// Plugins that have this value set cannot be used.
|
||||||
|
google.rpc.Status init_err = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PluginsRequest {
|
||||||
|
// Filters contains one or more filters using the syntax defined in the
|
||||||
|
// containerd filter package.
|
||||||
|
//
|
||||||
|
// The returned result will be those that match any of the provided
|
||||||
|
// filters. Expanded, plugins that match the following will be
|
||||||
|
// returned:
|
||||||
|
//
|
||||||
|
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||||
|
//
|
||||||
|
// If filters is zero-length or nil, all items will be returned.
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PluginsResponse {
|
||||||
|
repeated Plugin plugins = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ServerResponse {
|
||||||
|
string uuid = 1;
|
||||||
|
uint64 pid = 2;
|
||||||
|
uint64 pidns = 3; // PID namespace, such as 4026531836
|
||||||
|
repeated DeprecationWarning deprecations = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeprecationWarning {
|
||||||
|
string id = 1;
|
||||||
|
string message = 2;
|
||||||
|
google.protobuf.Timestamp last_occurrence = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PluginInfoRequest {
|
||||||
|
string type = 1;
|
||||||
|
string id = 2;
|
||||||
|
|
||||||
|
// Options may be used to request extra dynamic information from
|
||||||
|
// a plugin.
|
||||||
|
// This object is determined by the plugin and the plugin may return
|
||||||
|
// NotImplemented or InvalidArgument if it is not supported
|
||||||
|
google.protobuf.Any options = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PluginInfoResponse {
|
||||||
|
Plugin plugin = 1;
|
||||||
|
google.protobuf.Any extra = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.leases.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/leases/v1;leases";
|
||||||
|
|
||||||
|
// Leases service manages resources leases within the metadata store.
|
||||||
|
service Leases {
|
||||||
|
// Create creates a new lease for managing changes to metadata. A lease
|
||||||
|
// can be used to protect objects from being removed.
|
||||||
|
rpc Create(CreateRequest) returns (CreateResponse);
|
||||||
|
|
||||||
|
// Delete deletes the lease and makes any unreferenced objects created
|
||||||
|
// during the lease eligible for garbage collection if not referenced
|
||||||
|
// or retained by other resources during the lease.
|
||||||
|
rpc Delete(DeleteRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// List lists all active leases, returning the full list of
|
||||||
|
// leases and optionally including the referenced resources.
|
||||||
|
rpc List(ListRequest) returns (ListResponse);
|
||||||
|
|
||||||
|
// AddResource references the resource by the provided lease.
|
||||||
|
rpc AddResource(AddResourceRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// DeleteResource dereferences the resource by the provided lease.
|
||||||
|
rpc DeleteResource(DeleteResourceRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// ListResources lists all the resources referenced by the lease.
|
||||||
|
rpc ListResources(ListResourcesRequest) returns (ListResourcesResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lease is an object which retains resources while it exists.
|
||||||
|
message Lease {
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
google.protobuf.Timestamp created_at = 2;
|
||||||
|
|
||||||
|
map<string, string> labels = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateRequest {
|
||||||
|
// ID is used to identity the lease, when the id is not set the service
|
||||||
|
// generates a random identifier for the lease.
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
map<string, string> labels = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateResponse {
|
||||||
|
Lease lease = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteRequest {
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
// Sync indicates that the delete and cleanup should be done
|
||||||
|
// synchronously before returning to the caller
|
||||||
|
//
|
||||||
|
// Default is false
|
||||||
|
bool sync = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListRequest {
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListResponse {
|
||||||
|
repeated Lease leases = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Resource {
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
// For snapshotter resource, there are many snapshotter types here, like
|
||||||
|
// overlayfs, devmapper etc. The type will be formatted with type,
|
||||||
|
// like "snapshotter/overlayfs".
|
||||||
|
string type = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AddResourceRequest {
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
Resource resource = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteResourceRequest {
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
Resource resource = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListResourcesRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListResourcesResponse {
|
||||||
|
repeated Resource resources = 1 ;
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.mounts.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/mount.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/mounts/v1;mounts";
|
||||||
|
|
||||||
|
// Mounts service manages mounts
|
||||||
|
service Mounts {
|
||||||
|
rpc Activate(ActivateRequest) returns (ActivateResponse);
|
||||||
|
rpc Deactivate(DeactivateRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Info(InfoRequest) returns (InfoResponse);
|
||||||
|
rpc Update(UpdateRequest) returns (UpdateResponse);
|
||||||
|
rpc List(ListRequest) returns (stream ListMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
message ActivateRequest {
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
repeated containerd.types.Mount mounts = 2;
|
||||||
|
|
||||||
|
map<string, string> labels = 3;
|
||||||
|
|
||||||
|
bool temporary = 4;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
message ActivateResponse {
|
||||||
|
containerd.types.ActivationInfo info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeactivateRequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InfoRequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InfoResponse {
|
||||||
|
containerd.types.ActivationInfo info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateRequest {
|
||||||
|
containerd.types.ActivationInfo info = 1;
|
||||||
|
|
||||||
|
google.protobuf.FieldMask update_mask = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateResponse {
|
||||||
|
containerd.types.ActivationInfo info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListRequest {
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListMessage {
|
||||||
|
containerd.types.ActivationInfo info = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.namespaces.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/namespaces/v1;namespaces";
|
||||||
|
|
||||||
|
// Namespaces provides the ability to manipulate containerd namespaces.
|
||||||
|
//
|
||||||
|
// All objects in the system are required to be a member of a namespace. If a
|
||||||
|
// namespace is deleted, all objects, including containers, images and
|
||||||
|
// snapshots, will be deleted, as well.
|
||||||
|
//
|
||||||
|
// Unless otherwise noted, operations in containerd apply only to the namespace
|
||||||
|
// supplied per request.
|
||||||
|
//
|
||||||
|
// I hope this goes without saying, but namespaces are themselves NOT
|
||||||
|
// namespaced.
|
||||||
|
service Namespaces {
|
||||||
|
rpc Get(GetNamespaceRequest) returns (GetNamespaceResponse);
|
||||||
|
rpc List(ListNamespacesRequest) returns (ListNamespacesResponse);
|
||||||
|
rpc Create(CreateNamespaceRequest) returns (CreateNamespaceResponse);
|
||||||
|
rpc Update(UpdateNamespaceRequest) returns (UpdateNamespaceResponse);
|
||||||
|
rpc Delete(DeleteNamespaceRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Namespace {
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
// Labels provides an area to include arbitrary data on namespaces.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
//
|
||||||
|
// Note that to add a new value to this field, read the existing set and
|
||||||
|
// include the entire result in the update call.
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetNamespaceRequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetNamespaceResponse {
|
||||||
|
Namespace namespace = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListNamespacesRequest {
|
||||||
|
string filter = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListNamespacesResponse {
|
||||||
|
repeated Namespace namespaces = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateNamespaceRequest {
|
||||||
|
Namespace namespace = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateNamespaceResponse {
|
||||||
|
Namespace namespace = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNamespaceRequest updates the metadata for a namespace.
|
||||||
|
//
|
||||||
|
// The operation should follow semantics described in
|
||||||
|
// https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/field-mask,
|
||||||
|
// unless otherwise qualified.
|
||||||
|
message UpdateNamespaceRequest {
|
||||||
|
// Namespace provides the target value, as declared by the mask, for the update.
|
||||||
|
//
|
||||||
|
// The namespace field must be set.
|
||||||
|
Namespace namespace = 1;
|
||||||
|
|
||||||
|
// UpdateMask specifies which fields to perform the update on. If empty,
|
||||||
|
// the operation applies to all fields.
|
||||||
|
//
|
||||||
|
// For the most part, this applies only to selectively updating labels on
|
||||||
|
// the namespace. While field masks are typically limited to ascii alphas
|
||||||
|
// and digits, we just take everything after the "labels." as the map key.
|
||||||
|
google.protobuf.FieldMask update_mask = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateNamespaceResponse {
|
||||||
|
Namespace namespace = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteNamespaceRequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
// Sandbox is a v2 runtime extension that allows more complex execution environments for containers.
|
||||||
|
// This adds a notion of groups of containers that share same lifecycle and/or resources.
|
||||||
|
// A few good fits for sandbox can be:
|
||||||
|
// - A "pause" container in k8s, that acts as a parent process for child containers to hold network namespace.
|
||||||
|
// - (micro)VMs that launch a VM process and executes containers inside guest OS.
|
||||||
|
// containerd in this case remains implementation agnostic and delegates sandbox handling to runtimes.
|
||||||
|
// See proposal and discussion here: https://github.com/containerd/containerd/issues/4131
|
||||||
|
package containerd.services.sandbox.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/sandbox.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/mount.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/platform.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/metrics.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/sandbox/v1;sandbox";
|
||||||
|
|
||||||
|
// Store provides a metadata storage interface for sandboxes. Similarly to `Containers`,
|
||||||
|
// sandbox object includes info required to start a new instance, but no runtime state.
|
||||||
|
// When running a new sandbox instance, store objects are used as base type to create from.
|
||||||
|
service Store {
|
||||||
|
rpc Create(StoreCreateRequest) returns (StoreCreateResponse);
|
||||||
|
rpc Update(StoreUpdateRequest) returns (StoreUpdateResponse);
|
||||||
|
rpc Delete(StoreDeleteRequest) returns (StoreDeleteResponse);
|
||||||
|
rpc List(StoreListRequest) returns (StoreListResponse);
|
||||||
|
rpc Get(StoreGetRequest) returns (StoreGetResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message StoreCreateRequest {
|
||||||
|
containerd.types.Sandbox sandbox = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StoreCreateResponse {
|
||||||
|
containerd.types.Sandbox sandbox = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StoreUpdateRequest {
|
||||||
|
containerd.types.Sandbox sandbox = 1;
|
||||||
|
repeated string fields = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StoreUpdateResponse {
|
||||||
|
containerd.types.Sandbox sandbox = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StoreDeleteRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StoreDeleteResponse {}
|
||||||
|
|
||||||
|
message StoreListRequest {
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StoreListResponse {
|
||||||
|
repeated containerd.types.Sandbox list = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StoreGetRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StoreGetResponse {
|
||||||
|
containerd.types.Sandbox sandbox = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controller is an interface to manage runtime sandbox instances.
|
||||||
|
service Controller {
|
||||||
|
rpc Create(ControllerCreateRequest) returns (ControllerCreateResponse);
|
||||||
|
rpc Start(ControllerStartRequest) returns (ControllerStartResponse);
|
||||||
|
rpc Platform(ControllerPlatformRequest) returns (ControllerPlatformResponse);
|
||||||
|
rpc Stop(ControllerStopRequest) returns (ControllerStopResponse);
|
||||||
|
rpc Wait(ControllerWaitRequest) returns (ControllerWaitResponse);
|
||||||
|
rpc Status(ControllerStatusRequest) returns (ControllerStatusResponse);
|
||||||
|
rpc Shutdown(ControllerShutdownRequest) returns (ControllerShutdownResponse);
|
||||||
|
rpc Metrics(ControllerMetricsRequest) returns (ControllerMetricsResponse);
|
||||||
|
rpc Update(ControllerUpdateRequest) returns (ControllerUpdateResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerCreateRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
repeated containerd.types.Mount rootfs = 2;
|
||||||
|
google.protobuf.Any options = 3;
|
||||||
|
string netns_path = 4;
|
||||||
|
map<string, string> annotations = 5;
|
||||||
|
containerd.types.Sandbox sandbox = 6;
|
||||||
|
string sandboxer = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerCreateResponse {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerStartRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
string sandboxer = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerStartResponse {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
google.protobuf.Timestamp created_at = 3;
|
||||||
|
map<string, string> labels = 4;
|
||||||
|
// Address of the sandbox for containerd to connect,
|
||||||
|
// for calling Task or other APIs serving in the sandbox.
|
||||||
|
// it is in the form of ttrpc+unix://path/to/uds or grpc+vsock://<vsock cid>:<port>.
|
||||||
|
string address = 5;
|
||||||
|
uint32 version = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerPlatformRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
string sandboxer = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerPlatformResponse {
|
||||||
|
containerd.types.Platform platform = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerStopRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
uint32 timeout_secs = 2;
|
||||||
|
string sandboxer = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerStopResponse {}
|
||||||
|
|
||||||
|
message ControllerWaitRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
string sandboxer = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerWaitResponse {
|
||||||
|
uint32 exit_status = 1;
|
||||||
|
google.protobuf.Timestamp exited_at = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerStatusRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
bool verbose = 2;
|
||||||
|
string sandboxer = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerStatusResponse {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
string state = 3;
|
||||||
|
map<string, string> info = 4;
|
||||||
|
google.protobuf.Timestamp created_at = 5;
|
||||||
|
google.protobuf.Timestamp exited_at = 6;
|
||||||
|
google.protobuf.Any extra = 7;
|
||||||
|
// Address of the sandbox for containerd to connect,
|
||||||
|
// for calling Task or other APIs serving in the sandbox.
|
||||||
|
// it is in the form of ttrpc+unix://path/to/uds or grpc+vsock://<vsock cid>:<port>.
|
||||||
|
string address = 8;
|
||||||
|
uint32 version = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerShutdownRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
string sandboxer = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerShutdownResponse {}
|
||||||
|
|
||||||
|
message ControllerMetricsRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
string sandboxer = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerMetricsResponse {
|
||||||
|
types.Metric metrics = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerUpdateRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
string sandboxer = 2;
|
||||||
|
containerd.types.Sandbox sandbox = 3;
|
||||||
|
repeated string fields = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ControllerUpdateResponse {
|
||||||
|
}
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.snapshots.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/mount.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/snapshots/v1;snapshots";
|
||||||
|
|
||||||
|
// Snapshot service manages snapshots
|
||||||
|
service Snapshots {
|
||||||
|
rpc Prepare(PrepareSnapshotRequest) returns (PrepareSnapshotResponse);
|
||||||
|
rpc View(ViewSnapshotRequest) returns (ViewSnapshotResponse);
|
||||||
|
rpc Mounts(MountsRequest) returns (MountsResponse);
|
||||||
|
rpc Commit(CommitSnapshotRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Remove(RemoveSnapshotRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Stat(StatSnapshotRequest) returns (StatSnapshotResponse);
|
||||||
|
rpc Update(UpdateSnapshotRequest) returns (UpdateSnapshotResponse);
|
||||||
|
rpc List(ListSnapshotsRequest) returns (stream ListSnapshotsResponse);
|
||||||
|
rpc Usage(UsageRequest) returns (UsageResponse);
|
||||||
|
rpc Cleanup(CleanupRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message PrepareSnapshotRequest {
|
||||||
|
string snapshotter = 1;
|
||||||
|
string key = 2;
|
||||||
|
string parent = 3;
|
||||||
|
|
||||||
|
// Labels are arbitrary data on snapshots.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PrepareSnapshotResponse {
|
||||||
|
repeated containerd.types.Mount mounts = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ViewSnapshotRequest {
|
||||||
|
string snapshotter = 1;
|
||||||
|
string key = 2;
|
||||||
|
string parent = 3;
|
||||||
|
|
||||||
|
// Labels are arbitrary data on snapshots.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ViewSnapshotResponse {
|
||||||
|
repeated containerd.types.Mount mounts = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MountsRequest {
|
||||||
|
string snapshotter = 1;
|
||||||
|
string key = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MountsResponse {
|
||||||
|
repeated containerd.types.Mount mounts = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RemoveSnapshotRequest {
|
||||||
|
string snapshotter = 1;
|
||||||
|
string key = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CommitSnapshotRequest {
|
||||||
|
string snapshotter = 1;
|
||||||
|
string name = 2;
|
||||||
|
string key = 3;
|
||||||
|
|
||||||
|
// Labels are arbitrary data on snapshots.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 4;
|
||||||
|
|
||||||
|
string parent = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatSnapshotRequest {
|
||||||
|
string snapshotter = 1;
|
||||||
|
string key = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Kind {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
VIEW = 1;
|
||||||
|
ACTIVE = 2;
|
||||||
|
COMMITTED = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Info {
|
||||||
|
string name = 1;
|
||||||
|
string parent = 2;
|
||||||
|
Kind kind = 3;
|
||||||
|
|
||||||
|
// CreatedAt provides the time at which the snapshot was created.
|
||||||
|
google.protobuf.Timestamp created_at = 4;
|
||||||
|
|
||||||
|
// UpdatedAt provides the time the info was last updated.
|
||||||
|
google.protobuf.Timestamp updated_at = 5;
|
||||||
|
|
||||||
|
// Labels are arbitrary data on snapshots.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatSnapshotResponse {
|
||||||
|
Info info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateSnapshotRequest {
|
||||||
|
string snapshotter = 1;
|
||||||
|
Info info = 2;
|
||||||
|
|
||||||
|
// UpdateMask specifies which fields to perform the update on. If empty,
|
||||||
|
// the operation applies to all fields.
|
||||||
|
//
|
||||||
|
// In info, Name, Parent, Kind, Created are immutable,
|
||||||
|
// other field may be updated using this mask.
|
||||||
|
// If no mask is provided, all mutable field are updated.
|
||||||
|
google.protobuf.FieldMask update_mask = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateSnapshotResponse {
|
||||||
|
Info info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListSnapshotsRequest{
|
||||||
|
string snapshotter = 1;
|
||||||
|
|
||||||
|
// Filters contains one or more filters using the syntax defined in the
|
||||||
|
// containerd filter package.
|
||||||
|
//
|
||||||
|
// The returned result will be those that match any of the provided
|
||||||
|
// filters. Expanded, images that match the following will be
|
||||||
|
// returned:
|
||||||
|
//
|
||||||
|
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||||
|
//
|
||||||
|
// If filters is zero-length or nil, all items will be returned.
|
||||||
|
repeated string filters = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListSnapshotsResponse {
|
||||||
|
repeated Info info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UsageRequest {
|
||||||
|
string snapshotter = 1;
|
||||||
|
string key = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UsageResponse {
|
||||||
|
int64 size = 1;
|
||||||
|
int64 inodes = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CleanupRequest {
|
||||||
|
string snapshotter = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.streaming.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/streaming/v1;streaming";
|
||||||
|
|
||||||
|
service Streaming {
|
||||||
|
rpc Stream(stream google.protobuf.Any) returns (stream google.protobuf.Any);
|
||||||
|
}
|
||||||
|
|
||||||
|
message StreamInit {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,227 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.tasks.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/mount.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/metrics.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/descriptor.proto";
|
||||||
|
import "github.com/containerd/containerd/api/types/task/task.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/tasks/v1;tasks";
|
||||||
|
|
||||||
|
service Tasks {
|
||||||
|
// Create a task.
|
||||||
|
rpc Create(CreateTaskRequest) returns (CreateTaskResponse);
|
||||||
|
|
||||||
|
// Start a process.
|
||||||
|
rpc Start(StartRequest) returns (StartResponse);
|
||||||
|
|
||||||
|
// Delete a task and on disk state.
|
||||||
|
rpc Delete(DeleteTaskRequest) returns (DeleteResponse);
|
||||||
|
|
||||||
|
rpc DeleteProcess(DeleteProcessRequest) returns (DeleteResponse);
|
||||||
|
|
||||||
|
rpc Get(GetRequest) returns (GetResponse);
|
||||||
|
|
||||||
|
rpc List(ListTasksRequest) returns (ListTasksResponse);
|
||||||
|
|
||||||
|
// Kill a task or process.
|
||||||
|
rpc Kill(KillRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
rpc Exec(ExecProcessRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
rpc ResizePty(ResizePtyRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
rpc CloseIO(CloseIORequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
rpc Pause(PauseTaskRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
rpc Resume(ResumeTaskRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
rpc ListPids(ListPidsRequest) returns (ListPidsResponse);
|
||||||
|
|
||||||
|
rpc Checkpoint(CheckpointTaskRequest) returns (CheckpointTaskResponse);
|
||||||
|
|
||||||
|
rpc Update(UpdateTaskRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
rpc Metrics(MetricsRequest) returns (MetricsResponse);
|
||||||
|
|
||||||
|
rpc Wait(WaitRequest) returns (WaitResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateTaskRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
|
||||||
|
// RootFS provides the pre-chroot mounts to perform in the shim before
|
||||||
|
// executing the container task.
|
||||||
|
//
|
||||||
|
// These are for mounts that cannot be performed in the user namespace.
|
||||||
|
// Typically, these mounts should be resolved from snapshots specified on
|
||||||
|
// the container object.
|
||||||
|
repeated containerd.types.Mount rootfs = 3;
|
||||||
|
|
||||||
|
string stdin = 4;
|
||||||
|
string stdout = 5;
|
||||||
|
string stderr = 6;
|
||||||
|
bool terminal = 7;
|
||||||
|
|
||||||
|
containerd.types.Descriptor checkpoint = 8;
|
||||||
|
|
||||||
|
google.protobuf.Any options = 9;
|
||||||
|
|
||||||
|
string runtime_path = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateTaskResponse {
|
||||||
|
string container_id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartResponse {
|
||||||
|
uint32 pid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteTaskRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteResponse {
|
||||||
|
string id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
uint32 exit_status = 3;
|
||||||
|
google.protobuf.Timestamp exited_at = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteProcessRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetResponse {
|
||||||
|
containerd.v1.types.Process process = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListTasksRequest {
|
||||||
|
string filter = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListTasksResponse {
|
||||||
|
repeated containerd.v1.types.Process tasks = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message KillRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
uint32 signal = 3;
|
||||||
|
bool all = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExecProcessRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
string stdin = 2;
|
||||||
|
string stdout = 3;
|
||||||
|
string stderr = 4;
|
||||||
|
bool terminal = 5;
|
||||||
|
// Spec for starting a process in the target container.
|
||||||
|
//
|
||||||
|
// For runc, this is a process spec, for example.
|
||||||
|
google.protobuf.Any spec = 6;
|
||||||
|
// id of the exec process
|
||||||
|
string exec_id = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExecProcessResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResizePtyRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
uint32 width = 3;
|
||||||
|
uint32 height = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CloseIORequest {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
bool stdin = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PauseTaskRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResumeTaskRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListPidsRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListPidsResponse {
|
||||||
|
// Processes includes the process ID and additional process information
|
||||||
|
repeated containerd.v1.types.ProcessInfo processes = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckpointTaskRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
string parent_checkpoint = 2;
|
||||||
|
google.protobuf.Any options = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckpointTaskResponse {
|
||||||
|
repeated containerd.types.Descriptor descriptors = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateTaskRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
google.protobuf.Any resources = 2;
|
||||||
|
map<string, string> annotations = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MetricsRequest {
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MetricsResponse {
|
||||||
|
repeated types.Metric metrics = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitRequest {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitResponse {
|
||||||
|
uint32 exit_status = 1;
|
||||||
|
google.protobuf.Timestamp exited_at = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.transfer.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/transfer/v1;transfer";
|
||||||
|
|
||||||
|
service Transfer {
|
||||||
|
rpc Transfer(TransferRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message TransferRequest {
|
||||||
|
google.protobuf.Any source = 1;
|
||||||
|
google.protobuf.Any destination = 2;
|
||||||
|
TransferOptions options = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TransferOptions {
|
||||||
|
string progress_stream = 1;
|
||||||
|
// Progress min interval
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.version.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
|
||||||
|
// TODO(stevvooe): Should version service actually be versioned?
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/version/v1;version";
|
||||||
|
|
||||||
|
service Version {
|
||||||
|
rpc Version(google.protobuf.Empty) returns (VersionResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message VersionResponse {
|
||||||
|
string version = 1;
|
||||||
|
string revision = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types;
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types;types";
|
||||||
|
|
||||||
|
// Descriptor describes a blob in a content store.
|
||||||
|
//
|
||||||
|
// This descriptor can be used to reference content from an
|
||||||
|
// oci descriptor found in a manifest.
|
||||||
|
// See https://godoc.org/github.com/opencontainers/image-spec/specs-go/v1#Descriptor
|
||||||
|
message Descriptor {
|
||||||
|
string media_type = 1;
|
||||||
|
string digest = 2;
|
||||||
|
int64 size = 3;
|
||||||
|
map<string, string> annotations = 5;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types;
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/fieldpath.proto";
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types;types";
|
||||||
|
|
||||||
|
message Envelope {
|
||||||
|
option (containerd.types.fieldpath) = true;
|
||||||
|
google.protobuf.Timestamp timestamp = 1;
|
||||||
|
string namespace = 2;
|
||||||
|
string topic = 3;
|
||||||
|
google.protobuf.Any event = 4;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// Protocol Buffers for Go with Gadgets
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||||
|
// http://github.com/gogo/protobuf
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
package containerd.types;
|
||||||
|
|
||||||
|
import "google/protobuf/descriptor.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types;types";
|
||||||
|
|
||||||
|
extend google.protobuf.FileOptions {
|
||||||
|
optional bool fieldpath_all = 63300;
|
||||||
|
}
|
||||||
|
|
||||||
|
extend google.protobuf.MessageOptions {
|
||||||
|
optional bool fieldpath = 64400;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types;types";
|
||||||
|
|
||||||
|
message RuntimeRequest {
|
||||||
|
string runtime_path = 1;
|
||||||
|
// Options correspond to CreateTaskRequest.options.
|
||||||
|
// This is needed to pass the runc binary path, etc.
|
||||||
|
google.protobuf.Any options = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RuntimeVersion {
|
||||||
|
string version = 1;
|
||||||
|
string revision = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RuntimeInfo {
|
||||||
|
string name = 1;
|
||||||
|
RuntimeVersion version = 2;
|
||||||
|
// Options correspond to RuntimeInfoRequest.Options (contains runc binary path, etc.)
|
||||||
|
google.protobuf.Any options = 3;
|
||||||
|
// OCI-compatible runtimes should use https://github.com/opencontainers/runtime-spec/blob/main/features.md
|
||||||
|
google.protobuf.Any features = 4;
|
||||||
|
// Annotations of the shim. Irrelevant to features.Annotations.
|
||||||
|
map<string, string> annotations = 5;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types;types";
|
||||||
|
|
||||||
|
message Metric {
|
||||||
|
google.protobuf.Timestamp timestamp = 1;
|
||||||
|
string id = 2;
|
||||||
|
google.protobuf.Any data = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types;
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types;types";
|
||||||
|
|
||||||
|
// Mount describes mounts for a container.
|
||||||
|
//
|
||||||
|
// This type is the lingua franca of ContainerD. All services provide mounts
|
||||||
|
// to be used with the container at creation time.
|
||||||
|
//
|
||||||
|
// The Mount type follows the structure of the mount syscall, including a type,
|
||||||
|
// source, target and options.
|
||||||
|
message Mount {
|
||||||
|
// Type defines the nature of the mount.
|
||||||
|
string type = 1;
|
||||||
|
|
||||||
|
// Source specifies the name of the mount. Depending on mount type, this
|
||||||
|
// may be a volume name or a host path, or even ignored.
|
||||||
|
string source = 2;
|
||||||
|
|
||||||
|
// Target path in container
|
||||||
|
string target = 3;
|
||||||
|
|
||||||
|
// Options specifies zero or more fstab style mount options.
|
||||||
|
repeated string options = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ActiveMount {
|
||||||
|
Mount mount = 1;
|
||||||
|
|
||||||
|
google.protobuf.Timestamp mounted_at = 2;
|
||||||
|
|
||||||
|
string mount_point = 3;
|
||||||
|
|
||||||
|
map<string, string> data = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ActivationInfo {
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
repeated ActiveMount active = 2;
|
||||||
|
|
||||||
|
repeated Mount system = 3;
|
||||||
|
|
||||||
|
map<string, string> labels = 4;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types;
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types;types";
|
||||||
|
|
||||||
|
// Platform follows the structure of the OCI platform specification, from
|
||||||
|
// descriptors.
|
||||||
|
message Platform {
|
||||||
|
string os = 1;
|
||||||
|
string architecture = 2;
|
||||||
|
string variant = 3;
|
||||||
|
string os_version = 4;
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.runc.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types/runc/options;options";
|
||||||
|
|
||||||
|
message Options {
|
||||||
|
// disable pivot root when creating a container
|
||||||
|
bool no_pivot_root = 1;
|
||||||
|
// create a new keyring for the container
|
||||||
|
bool no_new_keyring = 2;
|
||||||
|
// place the shim in a cgroup
|
||||||
|
string shim_cgroup = 3;
|
||||||
|
// set the I/O's pipes uid
|
||||||
|
uint32 io_uid = 4;
|
||||||
|
// set the I/O's pipes gid
|
||||||
|
uint32 io_gid = 5;
|
||||||
|
// binary name of the runc binary
|
||||||
|
string binary_name = 6;
|
||||||
|
// runc root directory
|
||||||
|
string root = 7;
|
||||||
|
// criu binary path.
|
||||||
|
//
|
||||||
|
// Removed in containerd v2.0: string criu_path = 8;
|
||||||
|
reserved 8;
|
||||||
|
// enable systemd cgroups
|
||||||
|
bool systemd_cgroup = 9;
|
||||||
|
// criu image path
|
||||||
|
string criu_image_path = 10;
|
||||||
|
// criu work path
|
||||||
|
string criu_work_path = 11;
|
||||||
|
// task api address, can be a unix domain socket, or vsock address.
|
||||||
|
// it is in the form of ttrpc+unix://path/to/uds or grpc+vsock://<vsock cid>:<port>.
|
||||||
|
string task_api_address = 12;
|
||||||
|
// task api version, currently supported value is 2 and 3.
|
||||||
|
uint32 task_api_version = 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckpointOptions {
|
||||||
|
// exit the container after a checkpoint
|
||||||
|
bool exit = 1;
|
||||||
|
// checkpoint open tcp connections
|
||||||
|
bool open_tcp = 2;
|
||||||
|
// checkpoint external unix sockets
|
||||||
|
bool external_unix_sockets = 3;
|
||||||
|
// checkpoint terminals (ptys)
|
||||||
|
bool terminal = 4;
|
||||||
|
// allow checkpointing of file locks
|
||||||
|
bool file_locks = 5;
|
||||||
|
// restore provided namespaces as empty namespaces
|
||||||
|
repeated string empty_namespaces = 6;
|
||||||
|
// set the cgroups mode, soft, full, strict
|
||||||
|
string cgroups_mode = 7;
|
||||||
|
// checkpoint image path
|
||||||
|
string image_path = 8;
|
||||||
|
// checkpoint work path
|
||||||
|
string work_path = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ProcessDetails {
|
||||||
|
// exec process id if the process is managed by a shim
|
||||||
|
string exec_id = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// To regenerate api.pb.go run `make protos`
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package runtimeoptions.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types/runtimeoptions/v1;runtimeoptions";
|
||||||
|
|
||||||
|
message Options {
|
||||||
|
// TypeUrl specifies the type of the content inside the config file.
|
||||||
|
string type_url = 1;
|
||||||
|
// ConfigPath specifies the filesystem location of the config file
|
||||||
|
// used by the runtime.
|
||||||
|
string config_path = 2;
|
||||||
|
// Blob specifies an in-memory TOML blob passed from containerd's configuration section
|
||||||
|
// for this runtime. This will be used if config_path is not specified.
|
||||||
|
bytes config_body = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types;types";
|
||||||
|
|
||||||
|
// Sandbox represents a sandbox metadata object that keeps all info required by controller to
|
||||||
|
// work with a particular instance.
|
||||||
|
message Sandbox {
|
||||||
|
// SandboxID is a unique instance identifier within namespace
|
||||||
|
string sandbox_id = 1;
|
||||||
|
message Runtime {
|
||||||
|
// Name is the name of the runtime.
|
||||||
|
string name = 1;
|
||||||
|
// Options specify additional runtime initialization options for the shim (this data will be available in StartShim).
|
||||||
|
// Typically this data expected to be runtime shim implementation specific.
|
||||||
|
google.protobuf.Any options = 2;
|
||||||
|
}
|
||||||
|
// Runtime specifies which runtime to use for executing this container.
|
||||||
|
Runtime runtime = 2;
|
||||||
|
// Spec is sandbox configuration (kin of OCI runtime spec), spec's data will be written to a config.json file in the
|
||||||
|
// bundle directory (similary to OCI spec).
|
||||||
|
google.protobuf.Any spec = 3;
|
||||||
|
// Labels provides an area to include arbitrary data on containers.
|
||||||
|
map<string, string> labels = 4;
|
||||||
|
// CreatedAt is the time the container was first created.
|
||||||
|
google.protobuf.Timestamp created_at = 5;
|
||||||
|
// UpdatedAt is the last time the container was mutated.
|
||||||
|
google.protobuf.Timestamp updated_at = 6;
|
||||||
|
// Extensions allow clients to provide optional blobs that can be handled by runtime.
|
||||||
|
map<string, google.protobuf.Any> extensions = 7;
|
||||||
|
// Sandboxer is the name of the sandbox controller who manages the sandbox.
|
||||||
|
string sandboxer = 10;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.v1.types;
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types/task";
|
||||||
|
|
||||||
|
enum Status {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
CREATED = 1;
|
||||||
|
RUNNING = 2;
|
||||||
|
STOPPED = 3;
|
||||||
|
PAUSED = 4;
|
||||||
|
PAUSING = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Process {
|
||||||
|
string container_id = 1;
|
||||||
|
string id = 2;
|
||||||
|
uint32 pid = 3;
|
||||||
|
Status status = 4;
|
||||||
|
string stdin = 5;
|
||||||
|
string stdout = 6;
|
||||||
|
string stderr = 7;
|
||||||
|
bool terminal = 8;
|
||||||
|
uint32 exit_status = 9;
|
||||||
|
google.protobuf.Timestamp exited_at = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ProcessInfo {
|
||||||
|
// PID is the process ID.
|
||||||
|
uint32 pid = 1;
|
||||||
|
// Info contains additional process information.
|
||||||
|
//
|
||||||
|
// Info varies by platform.
|
||||||
|
google.protobuf.Any info = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types.transfer;
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/platform.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types/transfer";
|
||||||
|
|
||||||
|
message ImageStore {
|
||||||
|
string name = 1;
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
|
||||||
|
// Content filters
|
||||||
|
|
||||||
|
repeated types.Platform platforms = 3;
|
||||||
|
bool all_metadata = 4;
|
||||||
|
uint32 manifest_limit = 5;
|
||||||
|
|
||||||
|
// Import naming
|
||||||
|
|
||||||
|
// extra_references are used to set image names on imports of sub-images from the index
|
||||||
|
repeated ImageReference extra_references = 6;
|
||||||
|
|
||||||
|
// Unpack Configuration, multiple allowed
|
||||||
|
|
||||||
|
repeated UnpackConfiguration unpacks = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UnpackConfiguration {
|
||||||
|
// platform is the platform to unpack for, used for resolving manifest and snapshotter
|
||||||
|
// if not provided
|
||||||
|
types.Platform platform = 1;
|
||||||
|
|
||||||
|
// snapshotter to unpack to, if not provided default for platform shoudl be used
|
||||||
|
string snapshotter = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageReference is used to create or find a reference for an image
|
||||||
|
message ImageReference {
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
// is_prefix determines whether the Name should be considered
|
||||||
|
// a prefix (without tag or digest).
|
||||||
|
// For lookup, this may allow matching multiple tags.
|
||||||
|
// For store, this must have a tag or digest added.
|
||||||
|
bool is_prefix = 2;
|
||||||
|
|
||||||
|
// allow_overwrite allows overwriting or ignoring the name if
|
||||||
|
// another reference is provided (such as through an annotation).
|
||||||
|
// Only used if IsPrefix is true.
|
||||||
|
bool allow_overwrite = 3;
|
||||||
|
|
||||||
|
// add_digest adds the manifest digest to the reference.
|
||||||
|
// For lookup, this allows matching tags with any digest.
|
||||||
|
// For store, this allows adding the digest to the name.
|
||||||
|
// Only used if IsPrefix is true.
|
||||||
|
bool add_digest = 4;
|
||||||
|
|
||||||
|
// skip_named_digest only considers digest references which do not
|
||||||
|
// have a non-digested named reference.
|
||||||
|
// For lookup, this will deduplicate digest references when there is a named match.
|
||||||
|
// For store, this only adds this digest reference when there is no matching full
|
||||||
|
// name reference from the prefix.
|
||||||
|
// Only used if IsPrefix is true.
|
||||||
|
bool skip_named_digest = 5;
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types.transfer;
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types/transfer";
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/platform.proto";
|
||||||
|
|
||||||
|
message ImageImportStream {
|
||||||
|
// Stream is used to identify the binary input stream for the import operation.
|
||||||
|
// The stream uses the transfer binary stream protocol with the client as the sender.
|
||||||
|
// The binary data is expected to be a raw tar stream.
|
||||||
|
string stream = 1;
|
||||||
|
|
||||||
|
string media_type = 2;
|
||||||
|
|
||||||
|
bool force_compress = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ImageExportStream {
|
||||||
|
// Stream is used to identify the binary output stream for the export operation.
|
||||||
|
// The stream uses the transfer binary stream protocol with the server as the sender.
|
||||||
|
// The binary data is expected to be a raw tar stream.
|
||||||
|
string stream = 1;
|
||||||
|
|
||||||
|
string media_type = 2;
|
||||||
|
|
||||||
|
// The specified platforms
|
||||||
|
repeated types.Platform platforms = 3;
|
||||||
|
// Whether to include all platforms
|
||||||
|
bool all_platforms = 4;
|
||||||
|
// Skips the creation of the Docker compatible manifest.json file
|
||||||
|
bool skip_compatibility_manifest = 5;
|
||||||
|
// Excludes non-distributable blobs such as Windows base layers.
|
||||||
|
bool skip_non_distributable = 6;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types.transfer;
|
||||||
|
|
||||||
|
import "github.com/containerd/containerd/api/types/descriptor.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types/transfer";
|
||||||
|
|
||||||
|
message Progress {
|
||||||
|
string event = 1;
|
||||||
|
string name = 2;
|
||||||
|
repeated string parents = 3;
|
||||||
|
int64 progress = 4;
|
||||||
|
int64 total = 5;
|
||||||
|
containerd.types.Descriptor desc = 6;
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types.transfer;
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types/transfer";
|
||||||
|
|
||||||
|
message OCIRegistry {
|
||||||
|
string reference = 1;
|
||||||
|
RegistryResolver resolver = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum HTTPDebug {
|
||||||
|
DISABLED = 0;
|
||||||
|
// Enable HTTP debugging
|
||||||
|
DEBUG = 1;
|
||||||
|
// Enable HTTP requests tracing
|
||||||
|
TRACE = 2;
|
||||||
|
// Enable both HTTP debugging and requests tracing
|
||||||
|
BOTH = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RegistryResolver {
|
||||||
|
// auth_stream is used to refer to a stream which auth callbacks may be
|
||||||
|
// made on.
|
||||||
|
string auth_stream = 1;
|
||||||
|
|
||||||
|
// Headers
|
||||||
|
map<string, string> headers = 2;
|
||||||
|
|
||||||
|
string host_dir = 3;
|
||||||
|
|
||||||
|
string default_scheme = 4;
|
||||||
|
// Force skip verify
|
||||||
|
// CA callback? Client TLS callback?
|
||||||
|
|
||||||
|
// Whether to debug/trace HTTP requests to OCI registry.
|
||||||
|
HTTPDebug http_debug = 5;
|
||||||
|
|
||||||
|
// Stream ID to use for HTTP logs (when logs are streamed to client).
|
||||||
|
// When empty, logs are written to containerd logs.
|
||||||
|
string logs_stream = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuthRequest is sent as a callback on a stream
|
||||||
|
message AuthRequest {
|
||||||
|
// host is the registry host
|
||||||
|
string host = 1;
|
||||||
|
|
||||||
|
// reference is the namespace and repository name requested from the registry
|
||||||
|
string reference = 2;
|
||||||
|
|
||||||
|
// wwwauthenticate is the HTTP WWW-Authenticate header values returned from the registry
|
||||||
|
repeated string wwwauthenticate = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AuthType {
|
||||||
|
NONE = 0;
|
||||||
|
|
||||||
|
// CREDENTIALS is used to exchange username/password for access token
|
||||||
|
// using an oauth or "Docker Registry Token" server
|
||||||
|
CREDENTIALS = 1;
|
||||||
|
|
||||||
|
// REFRESH is used to exchange secret for access token using an oauth
|
||||||
|
// or "Docker Registry Token" server
|
||||||
|
REFRESH = 2;
|
||||||
|
|
||||||
|
// HEADER is used to set the HTTP Authorization header to secret
|
||||||
|
// directly for the registry.
|
||||||
|
// Value should be `<auth-scheme> <authorization-parameters>`
|
||||||
|
HEADER = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AuthResponse {
|
||||||
|
AuthType authType = 1;
|
||||||
|
string secret = 2;
|
||||||
|
string username = 3;
|
||||||
|
google.protobuf.Timestamp expire_at = 4;
|
||||||
|
// TODO: Stream error
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.types.transfer;
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/types/transfer";
|
||||||
|
|
||||||
|
message Data {
|
||||||
|
bytes data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WindowUpdate {
|
||||||
|
int32 update = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package proto;
|
||||||
|
option go_package = "github.com/containerd/continuity/proto;proto";
|
||||||
|
|
||||||
|
// Manifest specifies the entries in a container bundle, keyed and sorted by
|
||||||
|
// path.
|
||||||
|
message Manifest {
|
||||||
|
repeated Resource resource = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Resource {
|
||||||
|
// Path specifies the path from the bundle root. If more than one
|
||||||
|
// path is present, the entry may represent a hardlink, rather than using
|
||||||
|
// a link target. The path format is operating system specific.
|
||||||
|
repeated string path = 1;
|
||||||
|
|
||||||
|
// NOTE(stevvooe): Need to define clear precedence for user/group/uid/gid precedence.
|
||||||
|
|
||||||
|
// Uid specifies the user id for the resource.
|
||||||
|
int64 uid = 2;
|
||||||
|
|
||||||
|
// Gid specifies the group id for the resource.
|
||||||
|
int64 gid = 3;
|
||||||
|
|
||||||
|
// user and group are not currently used but their field numbers have been
|
||||||
|
// reserved for future use. As such, they are marked as deprecated.
|
||||||
|
string user = 4 [deprecated=true]; // "deprecated" stands for "reserved" here
|
||||||
|
string group = 5 [deprecated=true]; // "deprecated" stands for "reserved" here
|
||||||
|
|
||||||
|
// Mode defines the file mode and permissions. We've used the same
|
||||||
|
// bit-packing from Go's os package,
|
||||||
|
// http://golang.org/pkg/os/#FileMode, since they've done the work of
|
||||||
|
// creating a cross-platform layout.
|
||||||
|
uint32 mode = 6;
|
||||||
|
|
||||||
|
// NOTE(stevvooe): Beyond here, we start defining type specific fields.
|
||||||
|
|
||||||
|
// Size specifies the size in bytes of the resource. This is only valid
|
||||||
|
// for regular files.
|
||||||
|
uint64 size = 7;
|
||||||
|
|
||||||
|
// Digest specifies the content digest of the target file. Only valid for
|
||||||
|
// regular files. The strings are formatted in OCI style, i.e. <alg>:<encoded>.
|
||||||
|
// For detailed information about the format, please refer to OCI Image Spec:
|
||||||
|
// https://github.com/opencontainers/image-spec/blob/master/descriptor.md#digests-and-verification
|
||||||
|
// The digests are sorted in lexical order and implementations may choose
|
||||||
|
// which algorithms they prefer.
|
||||||
|
repeated string digest = 8;
|
||||||
|
|
||||||
|
// Target defines the target of a hard or soft link. Absolute links start
|
||||||
|
// with a slash and specify the resource relative to the bundle root.
|
||||||
|
// Relative links do not start with a slash and are relative to the
|
||||||
|
// resource path.
|
||||||
|
string target = 9;
|
||||||
|
|
||||||
|
// Major specifies the major device number for character and block devices.
|
||||||
|
uint64 major = 10;
|
||||||
|
|
||||||
|
// Minor specifies the minor device number for character and block devices.
|
||||||
|
uint64 minor = 11;
|
||||||
|
|
||||||
|
// Xattr provides storage for extended attributes for the target resource.
|
||||||
|
repeated XAttr xattr = 12;
|
||||||
|
|
||||||
|
// Ads stores one or more alternate data streams for the target resource.
|
||||||
|
repeated ADSEntry ads = 13;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// XAttr encodes extended attributes for a resource.
|
||||||
|
message XAttr {
|
||||||
|
// Name specifies the attribute name.
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
// Data specifies the associated data for the attribute.
|
||||||
|
bytes data = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADSEntry encodes information for a Windows Alternate Data Stream.
|
||||||
|
message ADSEntry {
|
||||||
|
// Name specifices the stream name.
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
// Data specifies the stream data.
|
||||||
|
// See also the description about the digest below.
|
||||||
|
bytes data = 2;
|
||||||
|
|
||||||
|
// Digest is a CAS representation of the stream data.
|
||||||
|
//
|
||||||
|
// At least one of data or digest MUST be specified, and either one of them
|
||||||
|
// SHOULD be specified.
|
||||||
|
//
|
||||||
|
// How to access the actual data using the digest is implementation-specific,
|
||||||
|
// and implementations can choose not to implement digest.
|
||||||
|
// So, digest SHOULD be used only when the stream data is large.
|
||||||
|
string digest = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package ttrpc;
|
||||||
|
|
||||||
|
import "proto/status.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/ttrpc";
|
||||||
|
|
||||||
|
message Request {
|
||||||
|
string service = 1;
|
||||||
|
string method = 2;
|
||||||
|
bytes payload = 3;
|
||||||
|
int64 timeout_nano = 4;
|
||||||
|
repeated KeyValue metadata = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Response {
|
||||||
|
Status status = 1;
|
||||||
|
bytes payload = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StringList {
|
||||||
|
repeated string list = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message KeyValue {
|
||||||
|
string key = 1;
|
||||||
|
string value = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package ttrpc;
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/ttrpc/internal";
|
||||||
|
|
||||||
|
message TestPayload {
|
||||||
|
string foo = 1;
|
||||||
|
int64 deadline = 2;
|
||||||
|
string metadata = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message EchoPayload {
|
||||||
|
int64 seq = 1;
|
||||||
|
string msg = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2017 Google LLC. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package configpb;
|
||||||
|
|
||||||
|
option go_package = "github.com/google/certificate-transparency-go/client/multilog/configpb";
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
// TemporalLogConfig is a set of LogShardConfig messages, whose
|
||||||
|
// time limits should be contiguous.
|
||||||
|
message TemporalLogConfig {
|
||||||
|
repeated LogShardConfig shard = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogShardConfig describes the acceptable date range for a single shard of a temporal
|
||||||
|
// log.
|
||||||
|
message LogShardConfig {
|
||||||
|
string uri = 1;
|
||||||
|
|
||||||
|
// The log's public key in DER-encoded PKIX form.
|
||||||
|
bytes public_key_der = 2;
|
||||||
|
|
||||||
|
// not_after_start defines the start of the range of acceptable NotAfter
|
||||||
|
// values, inclusive.
|
||||||
|
// Leaving this unset implies no lower bound to the range.
|
||||||
|
google.protobuf.Timestamp not_after_start = 3;
|
||||||
|
// not_after_limit defines the end of the range of acceptable NotAfter values,
|
||||||
|
// exclusive.
|
||||||
|
// Leaving this unset implies no upper bound to the range.
|
||||||
|
google.protobuf.Timestamp not_after_limit = 4;
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package grpc.gateway.protoc_gen_openapiv2.options;
|
||||||
|
|
||||||
|
import "google/protobuf/descriptor.proto";
|
||||||
|
import "protoc-gen-openapiv2/options/openapiv2.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options";
|
||||||
|
|
||||||
|
extend google.protobuf.FileOptions {
|
||||||
|
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||||
|
//
|
||||||
|
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||||
|
// different descriptor messages.
|
||||||
|
Swagger openapiv2_swagger = 1042;
|
||||||
|
}
|
||||||
|
extend google.protobuf.MethodOptions {
|
||||||
|
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||||
|
//
|
||||||
|
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||||
|
// different descriptor messages.
|
||||||
|
Operation openapiv2_operation = 1042;
|
||||||
|
}
|
||||||
|
extend google.protobuf.MessageOptions {
|
||||||
|
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||||
|
//
|
||||||
|
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||||
|
// different descriptor messages.
|
||||||
|
Schema openapiv2_schema = 1042;
|
||||||
|
}
|
||||||
|
extend google.protobuf.EnumOptions {
|
||||||
|
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||||
|
//
|
||||||
|
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||||
|
// different descriptor messages.
|
||||||
|
EnumSchema openapiv2_enum = 1042;
|
||||||
|
}
|
||||||
|
extend google.protobuf.ServiceOptions {
|
||||||
|
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||||
|
//
|
||||||
|
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||||
|
// different descriptor messages.
|
||||||
|
Tag openapiv2_tag = 1042;
|
||||||
|
}
|
||||||
|
extend google.protobuf.FieldOptions {
|
||||||
|
// ID assigned by protobuf-global-extension-registry@google.com for gRPC-Gateway project.
|
||||||
|
//
|
||||||
|
// All IDs are the same, as assigned. It is okay that they are the same, as they extend
|
||||||
|
// different descriptor messages.
|
||||||
|
JSONSchema openapiv2_field = 1042;
|
||||||
|
}
|
||||||
@@ -0,0 +1,762 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package grpc.gateway.protoc_gen_openapiv2.options;
|
||||||
|
|
||||||
|
import "google/protobuf/struct.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options";
|
||||||
|
|
||||||
|
// Scheme describes the schemes supported by the OpenAPI Swagger
|
||||||
|
// and Operation objects.
|
||||||
|
enum Scheme {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
HTTP = 1;
|
||||||
|
HTTPS = 2;
|
||||||
|
WS = 3;
|
||||||
|
WSS = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Swagger` is a representation of OpenAPI v2 specification's Swagger object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#swaggerObject
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||||
|
// info: {
|
||||||
|
// title: "Echo API";
|
||||||
|
// version: "1.0";
|
||||||
|
// description: "";
|
||||||
|
// contact: {
|
||||||
|
// name: "gRPC-Gateway project";
|
||||||
|
// url: "https://github.com/grpc-ecosystem/grpc-gateway";
|
||||||
|
// email: "none@example.com";
|
||||||
|
// };
|
||||||
|
// license: {
|
||||||
|
// name: "BSD 3-Clause License";
|
||||||
|
// url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/main/LICENSE";
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
// schemes: HTTPS;
|
||||||
|
// consumes: "application/json";
|
||||||
|
// produces: "application/json";
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
message Swagger {
|
||||||
|
// Specifies the OpenAPI Specification version being used. It can be
|
||||||
|
// used by the OpenAPI UI and other clients to interpret the API listing. The
|
||||||
|
// value MUST be "2.0".
|
||||||
|
string swagger = 1;
|
||||||
|
// Provides metadata about the API. The metadata can be used by the
|
||||||
|
// clients if needed.
|
||||||
|
Info info = 2;
|
||||||
|
// The host (name or ip) serving the API. This MUST be the host only and does
|
||||||
|
// not include the scheme nor sub-paths. It MAY include a port. If the host is
|
||||||
|
// not included, the host serving the documentation is to be used (including
|
||||||
|
// the port). The host does not support path templating.
|
||||||
|
string host = 3;
|
||||||
|
// The base path on which the API is served, which is relative to the host. If
|
||||||
|
// it is not included, the API is served directly under the host. The value
|
||||||
|
// MUST start with a leading slash (/). The basePath does not support path
|
||||||
|
// templating.
|
||||||
|
// Note that using `base_path` does not change the endpoint paths that are
|
||||||
|
// generated in the resulting OpenAPI file. If you wish to use `base_path`
|
||||||
|
// with relatively generated OpenAPI paths, the `base_path` prefix must be
|
||||||
|
// manually removed from your `google.api.http` paths and your code changed to
|
||||||
|
// serve the API from the `base_path`.
|
||||||
|
string base_path = 4;
|
||||||
|
// The transfer protocol of the API. Values MUST be from the list: "http",
|
||||||
|
// "https", "ws", "wss". If the schemes is not included, the default scheme to
|
||||||
|
// be used is the one used to access the OpenAPI definition itself.
|
||||||
|
repeated Scheme schemes = 5;
|
||||||
|
// A list of MIME types the APIs can consume. This is global to all APIs but
|
||||||
|
// can be overridden on specific API calls. Value MUST be as described under
|
||||||
|
// Mime Types.
|
||||||
|
repeated string consumes = 6;
|
||||||
|
// A list of MIME types the APIs can produce. This is global to all APIs but
|
||||||
|
// can be overridden on specific API calls. Value MUST be as described under
|
||||||
|
// Mime Types.
|
||||||
|
repeated string produces = 7;
|
||||||
|
// field 8 is reserved for 'paths'.
|
||||||
|
reserved 8;
|
||||||
|
// field 9 is reserved for 'definitions', which at this time are already
|
||||||
|
// exposed as and customizable as proto messages.
|
||||||
|
reserved 9;
|
||||||
|
// An object to hold responses that can be used across operations. This
|
||||||
|
// property does not define global responses for all operations.
|
||||||
|
map<string, Response> responses = 10;
|
||||||
|
// Security scheme definitions that can be used across the specification.
|
||||||
|
SecurityDefinitions security_definitions = 11;
|
||||||
|
// A declaration of which security schemes are applied for the API as a whole.
|
||||||
|
// The list of values describes alternative security schemes that can be used
|
||||||
|
// (that is, there is a logical OR between the security requirements).
|
||||||
|
// Individual operations can override this definition.
|
||||||
|
repeated SecurityRequirement security = 12;
|
||||||
|
// A list of tags for API documentation control. Tags can be used for logical
|
||||||
|
// grouping of operations by resources or any other qualifier.
|
||||||
|
repeated Tag tags = 13;
|
||||||
|
// Additional external documentation.
|
||||||
|
ExternalDocumentation external_docs = 14;
|
||||||
|
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||||
|
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||||
|
map<string, google.protobuf.Value> extensions = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Operation` is a representation of OpenAPI v2 specification's Operation object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#operationObject
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// service EchoService {
|
||||||
|
// rpc Echo(SimpleMessage) returns (SimpleMessage) {
|
||||||
|
// option (google.api.http) = {
|
||||||
|
// get: "/v1/example/echo/{id}"
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
// summary: "Get a message.";
|
||||||
|
// operation_id: "getMessage";
|
||||||
|
// tags: "echo";
|
||||||
|
// responses: {
|
||||||
|
// key: "200"
|
||||||
|
// value: {
|
||||||
|
// description: "OK";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
message Operation {
|
||||||
|
// A list of tags for API documentation control. Tags can be used for logical
|
||||||
|
// grouping of operations by resources or any other qualifier.
|
||||||
|
repeated string tags = 1;
|
||||||
|
// A short summary of what the operation does. For maximum readability in the
|
||||||
|
// swagger-ui, this field SHOULD be less than 120 characters.
|
||||||
|
string summary = 2;
|
||||||
|
// A verbose explanation of the operation behavior. GFM syntax can be used for
|
||||||
|
// rich text representation.
|
||||||
|
string description = 3;
|
||||||
|
// Additional external documentation for this operation.
|
||||||
|
ExternalDocumentation external_docs = 4;
|
||||||
|
// Unique string used to identify the operation. The id MUST be unique among
|
||||||
|
// all operations described in the API. Tools and libraries MAY use the
|
||||||
|
// operationId to uniquely identify an operation, therefore, it is recommended
|
||||||
|
// to follow common programming naming conventions.
|
||||||
|
string operation_id = 5;
|
||||||
|
// A list of MIME types the operation can consume. This overrides the consumes
|
||||||
|
// definition at the OpenAPI Object. An empty value MAY be used to clear the
|
||||||
|
// global definition. Value MUST be as described under Mime Types.
|
||||||
|
repeated string consumes = 6;
|
||||||
|
// A list of MIME types the operation can produce. This overrides the produces
|
||||||
|
// definition at the OpenAPI Object. An empty value MAY be used to clear the
|
||||||
|
// global definition. Value MUST be as described under Mime Types.
|
||||||
|
repeated string produces = 7;
|
||||||
|
// field 8 is reserved for 'parameters'.
|
||||||
|
reserved 8;
|
||||||
|
// The list of possible responses as they are returned from executing this
|
||||||
|
// operation.
|
||||||
|
map<string, Response> responses = 9;
|
||||||
|
// The transfer protocol for the operation. Values MUST be from the list:
|
||||||
|
// "http", "https", "ws", "wss". The value overrides the OpenAPI Object
|
||||||
|
// schemes definition.
|
||||||
|
repeated Scheme schemes = 10;
|
||||||
|
// Declares this operation to be deprecated. Usage of the declared operation
|
||||||
|
// should be refrained. Default value is false.
|
||||||
|
bool deprecated = 11;
|
||||||
|
// A declaration of which security schemes are applied for this operation. The
|
||||||
|
// list of values describes alternative security schemes that can be used
|
||||||
|
// (that is, there is a logical OR between the security requirements). This
|
||||||
|
// definition overrides any declared top-level security. To remove a top-level
|
||||||
|
// security declaration, an empty array can be used.
|
||||||
|
repeated SecurityRequirement security = 12;
|
||||||
|
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||||
|
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||||
|
map<string, google.protobuf.Value> extensions = 13;
|
||||||
|
// Custom parameters such as HTTP request headers.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/describing-parameters/
|
||||||
|
// and https://swagger.io/specification/v2/#parameter-object.
|
||||||
|
Parameters parameters = 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Parameters` is a representation of OpenAPI v2 specification's parameters object.
|
||||||
|
// Note: This technically breaks compatibility with the OpenAPI 2 definition structure as we only
|
||||||
|
// allow header parameters to be set here since we do not want users specifying custom non-header
|
||||||
|
// parameters beyond those inferred from the Protobuf schema.
|
||||||
|
// See: https://swagger.io/specification/v2/#parameter-object
|
||||||
|
message Parameters {
|
||||||
|
// `Headers` is one or more HTTP header parameter.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/describing-parameters/#header-parameters
|
||||||
|
repeated HeaderParameter headers = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `HeaderParameter` a HTTP header parameter.
|
||||||
|
// See: https://swagger.io/specification/v2/#parameter-object
|
||||||
|
message HeaderParameter {
|
||||||
|
// `Type` is a supported HTTP header type.
|
||||||
|
// See https://swagger.io/specification/v2/#parameterType.
|
||||||
|
enum Type {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
STRING = 1;
|
||||||
|
NUMBER = 2;
|
||||||
|
INTEGER = 3;
|
||||||
|
BOOLEAN = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Name` is the header name.
|
||||||
|
string name = 1;
|
||||||
|
// `Description` is a short description of the header.
|
||||||
|
string description = 2;
|
||||||
|
// `Type` is the type of the object. The value MUST be one of "string", "number", "integer", or "boolean". The "array" type is not supported.
|
||||||
|
// See: https://swagger.io/specification/v2/#parameterType.
|
||||||
|
Type type = 3;
|
||||||
|
// `Format` The extending format for the previously mentioned type.
|
||||||
|
string format = 4;
|
||||||
|
// `Required` indicates if the header is optional
|
||||||
|
bool required = 5;
|
||||||
|
// field 6 is reserved for 'items', but in OpenAPI-specific way.
|
||||||
|
reserved 6;
|
||||||
|
// field 7 is reserved `Collection Format`. Determines the format of the array if type array is used.
|
||||||
|
reserved 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Header` is a representation of OpenAPI v2 specification's Header object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#headerObject
|
||||||
|
//
|
||||||
|
message Header {
|
||||||
|
// `Description` is a short description of the header.
|
||||||
|
string description = 1;
|
||||||
|
// The type of the object. The value MUST be one of "string", "number", "integer", or "boolean". The "array" type is not supported.
|
||||||
|
string type = 2;
|
||||||
|
// `Format` The extending format for the previously mentioned type.
|
||||||
|
string format = 3;
|
||||||
|
// field 4 is reserved for 'items', but in OpenAPI-specific way.
|
||||||
|
reserved 4;
|
||||||
|
// field 5 is reserved `Collection Format` Determines the format of the array if type array is used.
|
||||||
|
reserved 5;
|
||||||
|
// `Default` Declares the value of the header that the server will use if none is provided.
|
||||||
|
// See: https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-6.2.
|
||||||
|
// Unlike JSON Schema this value MUST conform to the defined type for the header.
|
||||||
|
string default = 6;
|
||||||
|
// field 7 is reserved for 'maximum'.
|
||||||
|
reserved 7;
|
||||||
|
// field 8 is reserved for 'exclusiveMaximum'.
|
||||||
|
reserved 8;
|
||||||
|
// field 9 is reserved for 'minimum'.
|
||||||
|
reserved 9;
|
||||||
|
// field 10 is reserved for 'exclusiveMinimum'.
|
||||||
|
reserved 10;
|
||||||
|
// field 11 is reserved for 'maxLength'.
|
||||||
|
reserved 11;
|
||||||
|
// field 12 is reserved for 'minLength'.
|
||||||
|
reserved 12;
|
||||||
|
// 'Pattern' See https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.2.3.
|
||||||
|
string pattern = 13;
|
||||||
|
// field 14 is reserved for 'maxItems'.
|
||||||
|
reserved 14;
|
||||||
|
// field 15 is reserved for 'minItems'.
|
||||||
|
reserved 15;
|
||||||
|
// field 16 is reserved for 'uniqueItems'.
|
||||||
|
reserved 16;
|
||||||
|
// field 17 is reserved for 'enum'.
|
||||||
|
reserved 17;
|
||||||
|
// field 18 is reserved for 'multipleOf'.
|
||||||
|
reserved 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Response` is a representation of OpenAPI v2 specification's Response object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responseObject
|
||||||
|
//
|
||||||
|
message Response {
|
||||||
|
// `Description` is a short description of the response.
|
||||||
|
// GFM syntax can be used for rich text representation.
|
||||||
|
string description = 1;
|
||||||
|
// `Schema` optionally defines the structure of the response.
|
||||||
|
// If `Schema` is not provided, it means there is no content to the response.
|
||||||
|
Schema schema = 2;
|
||||||
|
// `Headers` A list of headers that are sent with the response.
|
||||||
|
// `Header` name is expected to be a string in the canonical format of the MIME header key
|
||||||
|
// See: https://golang.org/pkg/net/textproto/#CanonicalMIMEHeaderKey
|
||||||
|
map<string, Header> headers = 3;
|
||||||
|
// `Examples` gives per-mimetype response examples.
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#example-object
|
||||||
|
map<string, string> examples = 4;
|
||||||
|
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||||
|
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||||
|
map<string, google.protobuf.Value> extensions = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Info` is a representation of OpenAPI v2 specification's Info object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#infoObject
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||||
|
// info: {
|
||||||
|
// title: "Echo API";
|
||||||
|
// version: "1.0";
|
||||||
|
// description: "";
|
||||||
|
// contact: {
|
||||||
|
// name: "gRPC-Gateway project";
|
||||||
|
// url: "https://github.com/grpc-ecosystem/grpc-gateway";
|
||||||
|
// email: "none@example.com";
|
||||||
|
// };
|
||||||
|
// license: {
|
||||||
|
// name: "BSD 3-Clause License";
|
||||||
|
// url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/main/LICENSE";
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
message Info {
|
||||||
|
// The title of the application.
|
||||||
|
string title = 1;
|
||||||
|
// A short description of the application. GFM syntax can be used for rich
|
||||||
|
// text representation.
|
||||||
|
string description = 2;
|
||||||
|
// The Terms of Service for the API.
|
||||||
|
string terms_of_service = 3;
|
||||||
|
// The contact information for the exposed API.
|
||||||
|
Contact contact = 4;
|
||||||
|
// The license information for the exposed API.
|
||||||
|
License license = 5;
|
||||||
|
// Provides the version of the application API (not to be confused
|
||||||
|
// with the specification version).
|
||||||
|
string version = 6;
|
||||||
|
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||||
|
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||||
|
map<string, google.protobuf.Value> extensions = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Contact` is a representation of OpenAPI v2 specification's Contact object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#contactObject
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||||
|
// info: {
|
||||||
|
// ...
|
||||||
|
// contact: {
|
||||||
|
// name: "gRPC-Gateway project";
|
||||||
|
// url: "https://github.com/grpc-ecosystem/grpc-gateway";
|
||||||
|
// email: "none@example.com";
|
||||||
|
// };
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
message Contact {
|
||||||
|
// The identifying name of the contact person/organization.
|
||||||
|
string name = 1;
|
||||||
|
// The URL pointing to the contact information. MUST be in the format of a
|
||||||
|
// URL.
|
||||||
|
string url = 2;
|
||||||
|
// The email address of the contact person/organization. MUST be in the format
|
||||||
|
// of an email address.
|
||||||
|
string email = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `License` is a representation of OpenAPI v2 specification's License object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#licenseObject
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||||
|
// info: {
|
||||||
|
// ...
|
||||||
|
// license: {
|
||||||
|
// name: "BSD 3-Clause License";
|
||||||
|
// url: "https://github.com/grpc-ecosystem/grpc-gateway/blob/main/LICENSE";
|
||||||
|
// };
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
message License {
|
||||||
|
// The license name used for the API.
|
||||||
|
string name = 1;
|
||||||
|
// A URL to the license used for the API. MUST be in the format of a URL.
|
||||||
|
string url = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `ExternalDocumentation` is a representation of OpenAPI v2 specification's
|
||||||
|
// ExternalDocumentation object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#externalDocumentationObject
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||||
|
// ...
|
||||||
|
// external_docs: {
|
||||||
|
// description: "More about gRPC-Gateway";
|
||||||
|
// url: "https://github.com/grpc-ecosystem/grpc-gateway";
|
||||||
|
// }
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
message ExternalDocumentation {
|
||||||
|
// A short description of the target documentation. GFM syntax can be used for
|
||||||
|
// rich text representation.
|
||||||
|
string description = 1;
|
||||||
|
// The URL for the target documentation. Value MUST be in the format
|
||||||
|
// of a URL.
|
||||||
|
string url = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Schema` is a representation of OpenAPI v2 specification's Schema object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
|
||||||
|
//
|
||||||
|
message Schema {
|
||||||
|
JSONSchema json_schema = 1;
|
||||||
|
// Adds support for polymorphism. The discriminator is the schema property
|
||||||
|
// name that is used to differentiate between other schema that inherit this
|
||||||
|
// schema. The property name used MUST be defined at this schema and it MUST
|
||||||
|
// be in the required property list. When used, the value MUST be the name of
|
||||||
|
// this schema or any schema that inherits it.
|
||||||
|
string discriminator = 2;
|
||||||
|
// Relevant only for Schema "properties" definitions. Declares the property as
|
||||||
|
// "read only". This means that it MAY be sent as part of a response but MUST
|
||||||
|
// NOT be sent as part of the request. Properties marked as readOnly being
|
||||||
|
// true SHOULD NOT be in the required list of the defined schema. Default
|
||||||
|
// value is false.
|
||||||
|
bool read_only = 3;
|
||||||
|
// field 4 is reserved for 'xml'.
|
||||||
|
reserved 4;
|
||||||
|
// Additional external documentation for this schema.
|
||||||
|
ExternalDocumentation external_docs = 5;
|
||||||
|
// A free-form property to include an example of an instance for this schema in JSON.
|
||||||
|
// This is copied verbatim to the output.
|
||||||
|
string example = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `EnumSchema` is subset of fields from the OpenAPI v2 specification's Schema object.
|
||||||
|
// Only fields that are applicable to Enums are included
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_enum) = {
|
||||||
|
// ...
|
||||||
|
// title: "MyEnum";
|
||||||
|
// description:"This is my nice enum";
|
||||||
|
// example: "ZERO";
|
||||||
|
// required: true;
|
||||||
|
// ...
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
message EnumSchema {
|
||||||
|
// A short description of the schema.
|
||||||
|
string description = 1;
|
||||||
|
string default = 2;
|
||||||
|
// The title of the schema.
|
||||||
|
string title = 3;
|
||||||
|
bool required = 4;
|
||||||
|
bool read_only = 5;
|
||||||
|
// Additional external documentation for this schema.
|
||||||
|
ExternalDocumentation external_docs = 6;
|
||||||
|
string example = 7;
|
||||||
|
// Ref is used to define an external reference to include in the message.
|
||||||
|
// This could be a fully qualified proto message reference, and that type must
|
||||||
|
// be imported into the protofile. If no message is identified, the Ref will
|
||||||
|
// be used verbatim in the output.
|
||||||
|
// For example:
|
||||||
|
// `ref: ".google.protobuf.Timestamp"`.
|
||||||
|
string ref = 8;
|
||||||
|
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||||
|
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||||
|
map<string, google.protobuf.Value> extensions = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `JSONSchema` represents properties from JSON Schema taken, and as used, in
|
||||||
|
// the OpenAPI v2 spec.
|
||||||
|
//
|
||||||
|
// This includes changes made by OpenAPI v2.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
|
||||||
|
//
|
||||||
|
// See also: https://cswr.github.io/JsonSchema/spec/basic_types/,
|
||||||
|
// https://github.com/json-schema-org/json-schema-spec/blob/master/schema.json
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// message SimpleMessage {
|
||||||
|
// option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
|
||||||
|
// json_schema: {
|
||||||
|
// title: "SimpleMessage"
|
||||||
|
// description: "A simple message."
|
||||||
|
// required: ["id"]
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// // Id represents the message identifier.
|
||||||
|
// string id = 1; [
|
||||||
|
// (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
|
// description: "The unique identifier of the simple message."
|
||||||
|
// }];
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
message JSONSchema {
|
||||||
|
// field 1 is reserved for '$id', omitted from OpenAPI v2.
|
||||||
|
reserved 1;
|
||||||
|
// field 2 is reserved for '$schema', omitted from OpenAPI v2.
|
||||||
|
reserved 2;
|
||||||
|
// Ref is used to define an external reference to include in the message.
|
||||||
|
// This could be a fully qualified proto message reference, and that type must
|
||||||
|
// be imported into the protofile. If no message is identified, the Ref will
|
||||||
|
// be used verbatim in the output.
|
||||||
|
// For example:
|
||||||
|
// `ref: ".google.protobuf.Timestamp"`.
|
||||||
|
string ref = 3;
|
||||||
|
// field 4 is reserved for '$comment', omitted from OpenAPI v2.
|
||||||
|
reserved 4;
|
||||||
|
// The title of the schema.
|
||||||
|
string title = 5;
|
||||||
|
// A short description of the schema.
|
||||||
|
string description = 6;
|
||||||
|
string default = 7;
|
||||||
|
bool read_only = 8;
|
||||||
|
// A free-form property to include a JSON example of this field. This is copied
|
||||||
|
// verbatim to the output swagger.json. Quotes must be escaped.
|
||||||
|
// This property is the same for 2.0 and 3.0.0 https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/3.0.0.md#schemaObject https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#schemaObject
|
||||||
|
string example = 9;
|
||||||
|
double multiple_of = 10;
|
||||||
|
// Maximum represents an inclusive upper limit for a numeric instance. The
|
||||||
|
// value of MUST be a number,
|
||||||
|
double maximum = 11;
|
||||||
|
bool exclusive_maximum = 12;
|
||||||
|
// minimum represents an inclusive lower limit for a numeric instance. The
|
||||||
|
// value of MUST be a number,
|
||||||
|
double minimum = 13;
|
||||||
|
bool exclusive_minimum = 14;
|
||||||
|
uint64 max_length = 15;
|
||||||
|
uint64 min_length = 16;
|
||||||
|
string pattern = 17;
|
||||||
|
// field 18 is reserved for 'additionalItems', omitted from OpenAPI v2.
|
||||||
|
reserved 18;
|
||||||
|
// field 19 is reserved for 'items', but in OpenAPI-specific way.
|
||||||
|
// TODO(ivucica): add 'items'?
|
||||||
|
reserved 19;
|
||||||
|
uint64 max_items = 20;
|
||||||
|
uint64 min_items = 21;
|
||||||
|
bool unique_items = 22;
|
||||||
|
// field 23 is reserved for 'contains', omitted from OpenAPI v2.
|
||||||
|
reserved 23;
|
||||||
|
uint64 max_properties = 24;
|
||||||
|
uint64 min_properties = 25;
|
||||||
|
repeated string required = 26;
|
||||||
|
// field 27 is reserved for 'additionalProperties', but in OpenAPI-specific
|
||||||
|
// way. TODO(ivucica): add 'additionalProperties'?
|
||||||
|
reserved 27;
|
||||||
|
// field 28 is reserved for 'definitions', omitted from OpenAPI v2.
|
||||||
|
reserved 28;
|
||||||
|
// field 29 is reserved for 'properties', but in OpenAPI-specific way.
|
||||||
|
// TODO(ivucica): add 'additionalProperties'?
|
||||||
|
reserved 29;
|
||||||
|
// following fields are reserved, as the properties have been omitted from
|
||||||
|
// OpenAPI v2:
|
||||||
|
// patternProperties, dependencies, propertyNames, const
|
||||||
|
reserved 30 to 33;
|
||||||
|
// Items in 'array' must be unique.
|
||||||
|
repeated string array = 34;
|
||||||
|
|
||||||
|
enum JSONSchemaSimpleTypes {
|
||||||
|
UNKNOWN = 0;
|
||||||
|
ARRAY = 1;
|
||||||
|
BOOLEAN = 2;
|
||||||
|
INTEGER = 3;
|
||||||
|
NULL = 4;
|
||||||
|
NUMBER = 5;
|
||||||
|
OBJECT = 6;
|
||||||
|
STRING = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
repeated JSONSchemaSimpleTypes type = 35;
|
||||||
|
// `Format`
|
||||||
|
string format = 36;
|
||||||
|
// following fields are reserved, as the properties have been omitted from
|
||||||
|
// OpenAPI v2: contentMediaType, contentEncoding, if, then, else
|
||||||
|
reserved 37 to 41;
|
||||||
|
// field 42 is reserved for 'allOf', but in OpenAPI-specific way.
|
||||||
|
// TODO(ivucica): add 'allOf'?
|
||||||
|
reserved 42;
|
||||||
|
// following fields are reserved, as the properties have been omitted from
|
||||||
|
// OpenAPI v2:
|
||||||
|
// anyOf, oneOf, not
|
||||||
|
reserved 43 to 45;
|
||||||
|
// Items in `enum` must be unique https://tools.ietf.org/html/draft-fge-json-schema-validation-00#section-5.5.1
|
||||||
|
repeated string enum = 46;
|
||||||
|
|
||||||
|
// Additional field level properties used when generating the OpenAPI v2 file.
|
||||||
|
FieldConfiguration field_configuration = 1001;
|
||||||
|
|
||||||
|
// 'FieldConfiguration' provides additional field level properties used when generating the OpenAPI v2 file.
|
||||||
|
// These properties are not defined by OpenAPIv2, but they are used to control the generation.
|
||||||
|
message FieldConfiguration {
|
||||||
|
// Alternative parameter name when used as path parameter. If set, this will
|
||||||
|
// be used as the complete parameter name when this field is used as a path
|
||||||
|
// parameter. Use this to avoid having auto generated path parameter names
|
||||||
|
// for overlapping paths.
|
||||||
|
string path_param_name = 47;
|
||||||
|
// Declares this field to be deprecated. Allows for the generated OpenAPI
|
||||||
|
// parameter to be marked as deprecated without affecting the proto field.
|
||||||
|
bool deprecated = 49;
|
||||||
|
}
|
||||||
|
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||||
|
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||||
|
map<string, google.protobuf.Value> extensions = 48;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Tag` is a representation of OpenAPI v2 specification's Tag object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#tagObject
|
||||||
|
//
|
||||||
|
message Tag {
|
||||||
|
// The name of the tag. Use it to allow override of the name of a
|
||||||
|
// global Tag object, then use that name to reference the tag throughout the
|
||||||
|
// OpenAPI file.
|
||||||
|
string name = 1;
|
||||||
|
// A short description for the tag. GFM syntax can be used for rich text
|
||||||
|
// representation.
|
||||||
|
string description = 2;
|
||||||
|
// Additional external documentation for this tag.
|
||||||
|
ExternalDocumentation external_docs = 3;
|
||||||
|
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||||
|
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||||
|
map<string, google.protobuf.Value> extensions = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `SecurityDefinitions` is a representation of OpenAPI v2 specification's
|
||||||
|
// Security Definitions object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityDefinitionsObject
|
||||||
|
//
|
||||||
|
// A declaration of the security schemes available to be used in the
|
||||||
|
// specification. This does not enforce the security schemes on the operations
|
||||||
|
// and only serves to provide the relevant details for each scheme.
|
||||||
|
message SecurityDefinitions {
|
||||||
|
// A single security scheme definition, mapping a "name" to the scheme it
|
||||||
|
// defines.
|
||||||
|
map<string, SecurityScheme> security = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `SecurityScheme` is a representation of OpenAPI v2 specification's
|
||||||
|
// Security Scheme object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securitySchemeObject
|
||||||
|
//
|
||||||
|
// Allows the definition of a security scheme that can be used by the
|
||||||
|
// operations. Supported schemes are basic authentication, an API key (either as
|
||||||
|
// a header or as a query parameter) and OAuth2's common flows (implicit,
|
||||||
|
// password, application and access code).
|
||||||
|
message SecurityScheme {
|
||||||
|
// The type of the security scheme. Valid values are "basic",
|
||||||
|
// "apiKey" or "oauth2".
|
||||||
|
enum Type {
|
||||||
|
TYPE_INVALID = 0;
|
||||||
|
TYPE_BASIC = 1;
|
||||||
|
TYPE_API_KEY = 2;
|
||||||
|
TYPE_OAUTH2 = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The location of the API key. Valid values are "query" or "header".
|
||||||
|
enum In {
|
||||||
|
IN_INVALID = 0;
|
||||||
|
IN_QUERY = 1;
|
||||||
|
IN_HEADER = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The flow used by the OAuth2 security scheme. Valid values are
|
||||||
|
// "implicit", "password", "application" or "accessCode".
|
||||||
|
enum Flow {
|
||||||
|
FLOW_INVALID = 0;
|
||||||
|
FLOW_IMPLICIT = 1;
|
||||||
|
FLOW_PASSWORD = 2;
|
||||||
|
FLOW_APPLICATION = 3;
|
||||||
|
FLOW_ACCESS_CODE = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The type of the security scheme. Valid values are "basic",
|
||||||
|
// "apiKey" or "oauth2".
|
||||||
|
Type type = 1;
|
||||||
|
// A short description for security scheme.
|
||||||
|
string description = 2;
|
||||||
|
// The name of the header or query parameter to be used.
|
||||||
|
// Valid for apiKey.
|
||||||
|
string name = 3;
|
||||||
|
// The location of the API key. Valid values are "query" or
|
||||||
|
// "header".
|
||||||
|
// Valid for apiKey.
|
||||||
|
In in = 4;
|
||||||
|
// The flow used by the OAuth2 security scheme. Valid values are
|
||||||
|
// "implicit", "password", "application" or "accessCode".
|
||||||
|
// Valid for oauth2.
|
||||||
|
Flow flow = 5;
|
||||||
|
// The authorization URL to be used for this flow. This SHOULD be in
|
||||||
|
// the form of a URL.
|
||||||
|
// Valid for oauth2/implicit and oauth2/accessCode.
|
||||||
|
string authorization_url = 6;
|
||||||
|
// The token URL to be used for this flow. This SHOULD be in the
|
||||||
|
// form of a URL.
|
||||||
|
// Valid for oauth2/password, oauth2/application and oauth2/accessCode.
|
||||||
|
string token_url = 7;
|
||||||
|
// The available scopes for the OAuth2 security scheme.
|
||||||
|
// Valid for oauth2.
|
||||||
|
Scopes scopes = 8;
|
||||||
|
// Custom properties that start with "x-" such as "x-foo" used to describe
|
||||||
|
// extra functionality that is not covered by the standard OpenAPI Specification.
|
||||||
|
// See: https://swagger.io/docs/specification/2-0/swagger-extensions/
|
||||||
|
map<string, google.protobuf.Value> extensions = 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `SecurityRequirement` is a representation of OpenAPI v2 specification's
|
||||||
|
// Security Requirement object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#securityRequirementObject
|
||||||
|
//
|
||||||
|
// Lists the required security schemes to execute this operation. The object can
|
||||||
|
// have multiple security schemes declared in it which are all required (that
|
||||||
|
// is, there is a logical AND between the schemes).
|
||||||
|
//
|
||||||
|
// The name used for each property MUST correspond to a security scheme
|
||||||
|
// declared in the Security Definitions.
|
||||||
|
message SecurityRequirement {
|
||||||
|
// If the security scheme is of type "oauth2", then the value is a list of
|
||||||
|
// scope names required for the execution. For other security scheme types,
|
||||||
|
// the array MUST be empty.
|
||||||
|
message SecurityRequirementValue {
|
||||||
|
repeated string scope = 1;
|
||||||
|
}
|
||||||
|
// Each name must correspond to a security scheme which is declared in
|
||||||
|
// the Security Definitions. If the security scheme is of type "oauth2",
|
||||||
|
// then the value is a list of scope names required for the execution.
|
||||||
|
// For other security scheme types, the array MUST be empty.
|
||||||
|
map<string, SecurityRequirementValue> security_requirement = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Scopes` is a representation of OpenAPI v2 specification's Scopes object.
|
||||||
|
//
|
||||||
|
// See: https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#scopesObject
|
||||||
|
//
|
||||||
|
// Lists the available scopes for an OAuth2 security scheme.
|
||||||
|
message Scopes {
|
||||||
|
// Maps between a name of a scope to a short description of it (as the value
|
||||||
|
// of the property).
|
||||||
|
map<string, string> scope = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.buildkit.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/api/services/control;moby_buildkit_v1";
|
||||||
|
|
||||||
|
// import "github.com/containerd/containerd/api/types/descriptor.proto";
|
||||||
|
import "github.com/moby/buildkit/api/types/worker.proto";
|
||||||
|
import "github.com/moby/buildkit/solver/pb/ops.proto";
|
||||||
|
import "github.com/moby/buildkit/sourcepolicy/pb/policy.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "google/rpc/status.proto";
|
||||||
|
|
||||||
|
service Control {
|
||||||
|
rpc DiskUsage(DiskUsageRequest) returns (DiskUsageResponse);
|
||||||
|
rpc Prune(PruneRequest) returns (stream UsageRecord);
|
||||||
|
rpc Solve(SolveRequest) returns (SolveResponse);
|
||||||
|
rpc Status(StatusRequest) returns (stream StatusResponse);
|
||||||
|
rpc Session(stream BytesMessage) returns (stream BytesMessage);
|
||||||
|
rpc ListWorkers(ListWorkersRequest) returns (ListWorkersResponse);
|
||||||
|
rpc Info(InfoRequest) returns (InfoResponse);
|
||||||
|
|
||||||
|
rpc ListenBuildHistory(BuildHistoryRequest) returns (stream BuildHistoryEvent);
|
||||||
|
rpc UpdateBuildHistory(UpdateBuildHistoryRequest) returns (UpdateBuildHistoryResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message PruneRequest {
|
||||||
|
repeated string filter = 1;
|
||||||
|
bool all = 2;
|
||||||
|
int64 keepDuration = 3;
|
||||||
|
|
||||||
|
int64 reservedSpace = 4;
|
||||||
|
int64 maxUsedSpace = 5;
|
||||||
|
int64 minFreeSpace = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DiskUsageRequest {
|
||||||
|
repeated string filter = 1;
|
||||||
|
int64 ageLimit = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DiskUsageResponse {
|
||||||
|
repeated UsageRecord record = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UsageRecord {
|
||||||
|
string ID = 1;
|
||||||
|
bool Mutable = 2;
|
||||||
|
bool InUse = 3;
|
||||||
|
int64 Size = 4;
|
||||||
|
string Parent = 5 [deprecated=true];
|
||||||
|
google.protobuf.Timestamp CreatedAt = 6;
|
||||||
|
google.protobuf.Timestamp LastUsedAt = 7;
|
||||||
|
int64 UsageCount = 8;
|
||||||
|
string Description = 9;
|
||||||
|
string RecordType = 10;
|
||||||
|
bool Shared = 11;
|
||||||
|
repeated string Parents = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SolveRequest {
|
||||||
|
string Ref = 1;
|
||||||
|
pb.Definition Definition = 2;
|
||||||
|
// ExporterDeprecated and ExporterAttrsDeprecated are deprecated in favor
|
||||||
|
// of the new Exporters. If these fields are set, then they will be
|
||||||
|
// appended to the Exporters field if Exporters was not explicitly set.
|
||||||
|
string ExporterDeprecated = 3;
|
||||||
|
map<string, string> ExporterAttrsDeprecated = 4;
|
||||||
|
string Session = 5;
|
||||||
|
string Frontend = 6;
|
||||||
|
map<string, string> FrontendAttrs = 7;
|
||||||
|
CacheOptions Cache = 8;
|
||||||
|
repeated string Entitlements = 9;
|
||||||
|
map<string, pb.Definition> FrontendInputs = 10;
|
||||||
|
bool Internal = 11; // Internal builds are not recorded in build history
|
||||||
|
moby.buildkit.v1.sourcepolicy.Policy SourcePolicy = 12;
|
||||||
|
repeated Exporter Exporters = 13;
|
||||||
|
bool EnableSessionExporter = 14;
|
||||||
|
string SourcePolicySession = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CacheOptions {
|
||||||
|
// ExportRefDeprecated is deprecated in favor or the new Exports since BuildKit v0.4.0.
|
||||||
|
// When ExportRefDeprecated is set, the solver appends
|
||||||
|
// {.Type = "registry", .Attrs = ExportAttrs.add("ref", ExportRef)}
|
||||||
|
// to Exports for compatibility. (planned to be removed)
|
||||||
|
string ExportRefDeprecated = 1;
|
||||||
|
// ImportRefsDeprecated is deprecated in favor or the new Imports since BuildKit v0.4.0.
|
||||||
|
// When ImportRefsDeprecated is set, the solver appends
|
||||||
|
// {.Type = "registry", .Attrs = {"ref": importRef}}
|
||||||
|
// for each of the ImportRefs entry to Imports for compatibility. (planned to be removed)
|
||||||
|
repeated string ImportRefsDeprecated = 2;
|
||||||
|
// ExportAttrsDeprecated is deprecated since BuildKit v0.4.0.
|
||||||
|
// See the description of ExportRefDeprecated.
|
||||||
|
map<string, string> ExportAttrsDeprecated = 3;
|
||||||
|
// Exports was introduced in BuildKit v0.4.0.
|
||||||
|
repeated CacheOptionsEntry Exports = 4;
|
||||||
|
// Imports was introduced in BuildKit v0.4.0.
|
||||||
|
repeated CacheOptionsEntry Imports = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CacheOptionsEntry {
|
||||||
|
// Type is like "registry" or "local"
|
||||||
|
string Type = 1;
|
||||||
|
// Attrs are like mode=(min,max), ref=example.com:5000/foo/bar .
|
||||||
|
// See cache importer/exporter implementations' documentation.
|
||||||
|
map<string, string> Attrs = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SolveResponse {
|
||||||
|
map<string, string> ExporterResponse = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatusRequest {
|
||||||
|
string Ref = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatusResponse {
|
||||||
|
repeated Vertex vertexes = 1;
|
||||||
|
repeated VertexStatus statuses = 2;
|
||||||
|
repeated VertexLog logs = 3;
|
||||||
|
repeated VertexWarning warnings = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Vertex {
|
||||||
|
string digest = 1;
|
||||||
|
repeated string inputs = 2;
|
||||||
|
string name = 3;
|
||||||
|
bool cached = 4;
|
||||||
|
google.protobuf.Timestamp started = 5;
|
||||||
|
google.protobuf.Timestamp completed = 6;
|
||||||
|
string error = 7; // typed errors?
|
||||||
|
pb.ProgressGroup progressGroup = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message VertexStatus {
|
||||||
|
string ID = 1;
|
||||||
|
string vertex = 2;
|
||||||
|
string name = 3;
|
||||||
|
int64 current = 4;
|
||||||
|
int64 total = 5;
|
||||||
|
google.protobuf.Timestamp timestamp = 6;
|
||||||
|
google.protobuf.Timestamp started = 7;
|
||||||
|
google.protobuf.Timestamp completed = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message VertexLog {
|
||||||
|
string vertex = 1;
|
||||||
|
google.protobuf.Timestamp timestamp = 2;
|
||||||
|
int64 stream = 3;
|
||||||
|
bytes msg = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message VertexWarning {
|
||||||
|
string vertex = 1;
|
||||||
|
int64 level = 2;
|
||||||
|
bytes short = 3;
|
||||||
|
repeated bytes detail = 4;
|
||||||
|
string url = 5;
|
||||||
|
pb.SourceInfo info = 6;
|
||||||
|
repeated pb.Range ranges = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BytesMessage {
|
||||||
|
bytes data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListWorkersRequest {
|
||||||
|
repeated string filter = 1; // containerd style
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListWorkersResponse {
|
||||||
|
repeated moby.buildkit.v1.types.WorkerRecord record = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InfoRequest {}
|
||||||
|
|
||||||
|
message InfoResponse {
|
||||||
|
moby.buildkit.v1.types.BuildkitVersion buildkitVersion = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BuildHistoryRequest {
|
||||||
|
bool ActiveOnly = 1;
|
||||||
|
string Ref = 2;
|
||||||
|
bool EarlyExit = 3;
|
||||||
|
repeated string Filter = 4;
|
||||||
|
int32 Limit = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum BuildHistoryEventType {
|
||||||
|
STARTED = 0;
|
||||||
|
COMPLETE = 1;
|
||||||
|
DELETED = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BuildHistoryEvent {
|
||||||
|
BuildHistoryEventType type = 1;
|
||||||
|
BuildHistoryRecord record = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BuildHistoryRecord {
|
||||||
|
string Ref = 1;
|
||||||
|
string Frontend = 2;
|
||||||
|
map<string, string> FrontendAttrs = 3;
|
||||||
|
repeated Exporter Exporters = 4;
|
||||||
|
google.rpc.Status error = 5;
|
||||||
|
google.protobuf.Timestamp CreatedAt = 6;
|
||||||
|
google.protobuf.Timestamp CompletedAt = 7;
|
||||||
|
Descriptor logs = 8;
|
||||||
|
map<string, string> ExporterResponse = 9;
|
||||||
|
BuildResultInfo Result = 10;
|
||||||
|
map<string, BuildResultInfo> Results = 11;
|
||||||
|
int32 Generation = 12;
|
||||||
|
Descriptor trace = 13;
|
||||||
|
bool pinned = 14;
|
||||||
|
int32 numCachedSteps = 15;
|
||||||
|
int32 numTotalSteps = 16;
|
||||||
|
int32 numCompletedSteps = 17;
|
||||||
|
Descriptor externalError = 18;
|
||||||
|
int32 numWarnings = 19;
|
||||||
|
// TODO: tags
|
||||||
|
// TODO: unclipped logs
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateBuildHistoryRequest {
|
||||||
|
string Ref = 1;
|
||||||
|
bool Pinned = 2;
|
||||||
|
bool Delete = 3;
|
||||||
|
bool Finalize = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateBuildHistoryResponse {}
|
||||||
|
|
||||||
|
message Descriptor {
|
||||||
|
string media_type = 1;
|
||||||
|
string digest = 2;
|
||||||
|
int64 size = 3;
|
||||||
|
map<string, string> annotations = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BuildResultInfo {
|
||||||
|
Descriptor ResultDeprecated = 1;
|
||||||
|
repeated Descriptor Attestations = 2;
|
||||||
|
map<int64, Descriptor> Results = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exporter describes the output exporter
|
||||||
|
message Exporter {
|
||||||
|
// Type identifies the exporter
|
||||||
|
string Type = 1;
|
||||||
|
// Attrs specifies exporter configuration
|
||||||
|
map<string, string> Attrs = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.buildkit.v1.types;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/api/types;moby_buildkit_v1_types";
|
||||||
|
|
||||||
|
import "github.com/moby/buildkit/solver/pb/ops.proto";
|
||||||
|
|
||||||
|
message WorkerRecord {
|
||||||
|
string ID = 1;
|
||||||
|
map<string, string> Labels = 2;
|
||||||
|
repeated pb.Platform platforms = 3;
|
||||||
|
repeated GCPolicy GCPolicy = 4;
|
||||||
|
BuildkitVersion BuildkitVersion = 5;
|
||||||
|
repeated CDIDevice CDIDevices = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GCPolicy {
|
||||||
|
bool all = 1;
|
||||||
|
int64 keepDuration = 2;
|
||||||
|
repeated string filters = 4;
|
||||||
|
|
||||||
|
// reservedSpace was renamed from freeBytes
|
||||||
|
int64 reservedSpace = 3;
|
||||||
|
int64 maxUsedSpace = 5;
|
||||||
|
int64 minFreeSpace = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BuildkitVersion {
|
||||||
|
string package = 1;
|
||||||
|
string version = 2;
|
||||||
|
string revision = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CDIDevice {
|
||||||
|
string Name = 1;
|
||||||
|
bool AutoAllow = 2;
|
||||||
|
map<string, string> Annotations = 3;
|
||||||
|
bool OnDemand = 4;
|
||||||
|
}
|
||||||
27
wfe-buildkit-protos/proto/github.com/moby/buildkit/cache/contenthash/checksum.proto
vendored
Normal file
27
wfe-buildkit-protos/proto/github.com/moby/buildkit/cache/contenthash/checksum.proto
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package contenthash;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/cache/contenthash";
|
||||||
|
|
||||||
|
enum CacheRecordType {
|
||||||
|
FILE = 0;
|
||||||
|
DIR = 1;
|
||||||
|
DIR_HEADER = 2;
|
||||||
|
SYMLINK = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CacheRecord {
|
||||||
|
string digest = 1;
|
||||||
|
CacheRecordType type = 2;
|
||||||
|
string linkname = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CacheRecordWithPath {
|
||||||
|
string path = 1;
|
||||||
|
CacheRecord record = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CacheRecords {
|
||||||
|
repeated CacheRecordWithPath paths = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,407 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.buildkit.v1.frontend;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/frontend/gateway/pb;moby_buildkit_v1_frontend";
|
||||||
|
|
||||||
|
import "github.com/moby/buildkit/api/types/worker.proto";
|
||||||
|
import "github.com/moby/buildkit/solver/pb/ops.proto";
|
||||||
|
import "github.com/moby/buildkit/sourcepolicy/pb/policy.proto";
|
||||||
|
import "github.com/moby/buildkit/util/apicaps/pb/caps.proto";
|
||||||
|
import "github.com/tonistiigi/fsutil/types/stat.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "google/rpc/status.proto";
|
||||||
|
|
||||||
|
service LLBBridge {
|
||||||
|
// apicaps:CapResolveImage
|
||||||
|
rpc ResolveImageConfig(ResolveImageConfigRequest) returns (ResolveImageConfigResponse);
|
||||||
|
// apicaps:CapSourceMetaResolver
|
||||||
|
rpc ResolveSourceMeta(ResolveSourceMetaRequest) returns (ResolveSourceMetaResponse);
|
||||||
|
// apicaps:CapSolveBase
|
||||||
|
rpc Solve(SolveRequest) returns (SolveResponse);
|
||||||
|
// apicaps:CapReadFile
|
||||||
|
rpc ReadFile(ReadFileRequest) returns (ReadFileResponse);
|
||||||
|
// apicaps:CapReadDir
|
||||||
|
rpc ReadDir(ReadDirRequest) returns (ReadDirResponse);
|
||||||
|
// apicaps:CapStatFile
|
||||||
|
rpc StatFile(StatFileRequest) returns (StatFileResponse);
|
||||||
|
// apicaps:CapGatewayEvaluate
|
||||||
|
rpc Evaluate(EvaluateRequest) returns (EvaluateResponse);
|
||||||
|
rpc Ping(PingRequest) returns (PongResponse);
|
||||||
|
rpc Return(ReturnRequest) returns (ReturnResponse);
|
||||||
|
// apicaps:CapFrontendInputs
|
||||||
|
rpc Inputs(InputsRequest) returns (InputsResponse);
|
||||||
|
|
||||||
|
rpc NewContainer(NewContainerRequest) returns (NewContainerResponse);
|
||||||
|
rpc ReleaseContainer(ReleaseContainerRequest) returns (ReleaseContainerResponse);
|
||||||
|
rpc ExecProcess(stream ExecMessage) returns (stream ExecMessage);
|
||||||
|
|
||||||
|
// apicaps:CapGatewayExecFilesystem
|
||||||
|
rpc ReadFileContainer(ReadFileRequest) returns (ReadFileResponse);
|
||||||
|
rpc ReadDirContainer(ReadDirRequest) returns (ReadDirResponse);
|
||||||
|
rpc StatFileContainer(StatFileRequest) returns (StatFileResponse);
|
||||||
|
|
||||||
|
// apicaps:CapGatewayWarnings
|
||||||
|
rpc Warn(WarnRequest) returns (WarnResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Result {
|
||||||
|
oneof result {
|
||||||
|
// Deprecated non-array refs.
|
||||||
|
string refDeprecated = 1;
|
||||||
|
RefMapDeprecated refsDeprecated = 2;
|
||||||
|
|
||||||
|
Ref ref = 3;
|
||||||
|
RefMap refs = 4;
|
||||||
|
}
|
||||||
|
map<string, bytes> metadata = 10;
|
||||||
|
// 11 was used during development and is reserved for old attestation format
|
||||||
|
map<string, Attestations> attestations = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RefMapDeprecated {
|
||||||
|
map<string, string> refs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Ref {
|
||||||
|
string id = 1;
|
||||||
|
pb.Definition def = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RefMap {
|
||||||
|
map<string, Ref> refs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Attestations {
|
||||||
|
repeated Attestation attestation = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Attestation {
|
||||||
|
AttestationKind kind = 1;
|
||||||
|
map<string, bytes> metadata = 2;
|
||||||
|
|
||||||
|
Ref ref = 3;
|
||||||
|
string path = 4;
|
||||||
|
string inTotoPredicateType = 5;
|
||||||
|
repeated InTotoSubject inTotoSubjects = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum AttestationKind {
|
||||||
|
InToto = 0;
|
||||||
|
Bundle = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InTotoSubject {
|
||||||
|
InTotoSubjectKind kind = 1;
|
||||||
|
|
||||||
|
repeated string digest = 2;
|
||||||
|
string name = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum InTotoSubjectKind {
|
||||||
|
Self = 0;
|
||||||
|
Raw = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReturnRequest {
|
||||||
|
Result result = 1;
|
||||||
|
google.rpc.Status error = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReturnResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
message InputsRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
message InputsResponse {
|
||||||
|
map<string, pb.Definition> Definitions = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveImageConfigRequest {
|
||||||
|
string Ref = 1;
|
||||||
|
pb.Platform Platform = 2;
|
||||||
|
string ResolveMode = 3;
|
||||||
|
string LogName = 4;
|
||||||
|
int32 ResolverType = 5;
|
||||||
|
string SessionID = 6;
|
||||||
|
string StoreID = 7;
|
||||||
|
repeated moby.buildkit.v1.sourcepolicy.Policy SourcePolicies = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveImageConfigResponse {
|
||||||
|
string Digest = 1;
|
||||||
|
bytes Config = 2;
|
||||||
|
string Ref = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveSourceMetaRequest {
|
||||||
|
pb.SourceOp Source = 1;
|
||||||
|
pb.Platform Platform = 2;
|
||||||
|
string LogName = 3;
|
||||||
|
string ResolveMode = 4;
|
||||||
|
ResolveSourceGitRequest Git = 5;
|
||||||
|
ResolveSourceImageRequest Image = 6;
|
||||||
|
ResolveSourceHTTPRequest HTTP = 7;
|
||||||
|
repeated moby.buildkit.v1.sourcepolicy.Policy SourcePolicies = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveSourceMetaResponse {
|
||||||
|
pb.SourceOp Source = 1;
|
||||||
|
ResolveSourceImageResponse Image = 2;
|
||||||
|
ResolveSourceGitResponse Git = 3;
|
||||||
|
ResolveSourceHTTPResponse HTTP = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveSourceImageRequest {
|
||||||
|
bool NoConfig = 1;
|
||||||
|
bool AttestationChain = 2;
|
||||||
|
repeated string ResolveAttestations = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AttestationChain {
|
||||||
|
string Root = 1;
|
||||||
|
string ImageManifest = 2;
|
||||||
|
string AttestationManifest = 3;
|
||||||
|
repeated string SignatureManifests = 4;
|
||||||
|
map<string, Blob> Blobs = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveSourceImageResponse {
|
||||||
|
string Digest = 1;
|
||||||
|
bytes Config = 2;
|
||||||
|
AttestationChain AttestationChain = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveSourceGitRequest {
|
||||||
|
// Return full commit and tag object bytes.
|
||||||
|
bool ReturnObject = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveSourceGitResponse {
|
||||||
|
string Checksum = 1;
|
||||||
|
string Ref = 2;
|
||||||
|
string CommitChecksum = 3;
|
||||||
|
bytes CommitObject = 4;
|
||||||
|
bytes TagObject = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveSourceHTTPResponse {
|
||||||
|
string Checksum = 1;
|
||||||
|
string Filename = 2;
|
||||||
|
google.protobuf.Timestamp LastModified = 3;
|
||||||
|
ChecksumResponse ChecksumResponse = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResolveSourceHTTPRequest {
|
||||||
|
ChecksumRequest ChecksumRequest = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ChecksumRequest {
|
||||||
|
enum ChecksumAlgo {
|
||||||
|
CHECKSUM_ALGO_SHA256 = 0;
|
||||||
|
CHECKSUM_ALGO_SHA384 = 1;
|
||||||
|
CHECKSUM_ALGO_SHA512 = 2;
|
||||||
|
}
|
||||||
|
ChecksumAlgo Algo = 1;
|
||||||
|
bytes Suffix = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ChecksumResponse {
|
||||||
|
string Digest = 1;
|
||||||
|
bytes Suffix = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SolveRequest {
|
||||||
|
pb.Definition Definition = 1;
|
||||||
|
string Frontend = 2;
|
||||||
|
map<string, string> FrontendOpt = 3;
|
||||||
|
// 4 was removed in BuildKit v0.11.0.
|
||||||
|
bool allowResultReturn = 5;
|
||||||
|
bool allowResultArrayRef = 6;
|
||||||
|
|
||||||
|
// apicaps.CapSolveInlineReturn deprecated
|
||||||
|
bool Final = 10;
|
||||||
|
bytes ExporterAttr = 11;
|
||||||
|
// CacheImports was added in BuildKit v0.4.0.
|
||||||
|
// apicaps:CapImportCaches
|
||||||
|
repeated CacheOptionsEntry CacheImports = 12;
|
||||||
|
|
||||||
|
// apicaps:CapFrontendInputs
|
||||||
|
map<string, pb.Definition> FrontendInputs = 13;
|
||||||
|
|
||||||
|
bool Evaluate = 14;
|
||||||
|
|
||||||
|
repeated moby.buildkit.v1.sourcepolicy.Policy SourcePolicies = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CacheOptionsEntry corresponds to the control.CacheOptionsEntry
|
||||||
|
message CacheOptionsEntry {
|
||||||
|
string Type = 1;
|
||||||
|
map<string, string> Attrs = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SolveResponse {
|
||||||
|
// deprecated
|
||||||
|
string ref = 1; // can be used by readfile request
|
||||||
|
// deprecated
|
||||||
|
// bytes ExporterAttr = 2;
|
||||||
|
|
||||||
|
// these fields are returned when allowMapReturn was set
|
||||||
|
Result result = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReadFileRequest {
|
||||||
|
string Ref = 1;
|
||||||
|
string FilePath = 2;
|
||||||
|
FileRange Range = 3;
|
||||||
|
int32 MountIndex = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileRange {
|
||||||
|
int64 Offset = 1;
|
||||||
|
int64 Length = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReadFileResponse {
|
||||||
|
bytes Data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReadDirRequest {
|
||||||
|
string Ref = 1;
|
||||||
|
string DirPath = 2;
|
||||||
|
string IncludePattern = 3;
|
||||||
|
int32 MountIndex = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReadDirResponse {
|
||||||
|
repeated fsutil.types.Stat entries = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatFileRequest {
|
||||||
|
string Ref = 1;
|
||||||
|
string Path = 2;
|
||||||
|
int32 MountIndex = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatFileResponse {
|
||||||
|
fsutil.types.Stat stat = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message EvaluateRequest {
|
||||||
|
string Ref = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message EvaluateResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
message PingRequest{
|
||||||
|
}
|
||||||
|
message PongResponse{
|
||||||
|
repeated moby.buildkit.v1.apicaps.APICap FrontendAPICaps = 1;
|
||||||
|
repeated moby.buildkit.v1.apicaps.APICap LLBCaps = 2;
|
||||||
|
repeated moby.buildkit.v1.types.WorkerRecord Workers = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WarnRequest {
|
||||||
|
string digest = 1;
|
||||||
|
int64 level = 2;
|
||||||
|
bytes short = 3;
|
||||||
|
repeated bytes detail = 4;
|
||||||
|
string url = 5;
|
||||||
|
pb.SourceInfo info = 6;
|
||||||
|
repeated pb.Range ranges = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WarnResponse{}
|
||||||
|
|
||||||
|
message NewContainerRequest {
|
||||||
|
string ContainerID = 1;
|
||||||
|
// For mount input values we can use random identifiers passed with ref
|
||||||
|
repeated pb.Mount Mounts = 2;
|
||||||
|
pb.NetMode Network = 3;
|
||||||
|
pb.Platform platform = 4;
|
||||||
|
pb.WorkerConstraints constraints = 5;
|
||||||
|
repeated pb.HostIP extraHosts = 6;
|
||||||
|
string hostname = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NewContainerResponse{}
|
||||||
|
|
||||||
|
message ReleaseContainerRequest {
|
||||||
|
string ContainerID = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReleaseContainerResponse{}
|
||||||
|
|
||||||
|
message ExecMessage {
|
||||||
|
string ProcessID = 1;
|
||||||
|
oneof Input {
|
||||||
|
// InitMessage sent from client to server will start a new process in a
|
||||||
|
// container
|
||||||
|
InitMessage Init = 2;
|
||||||
|
// FdMessage used from client to server for input (stdin) and
|
||||||
|
// from server to client for output (stdout, stderr)
|
||||||
|
FdMessage File = 3;
|
||||||
|
// ResizeMessage used from client to server for terminal resize events
|
||||||
|
ResizeMessage Resize = 4;
|
||||||
|
// StartedMessage sent from server to client after InitMessage to
|
||||||
|
// indicate the process has started.
|
||||||
|
StartedMessage Started = 5;
|
||||||
|
// ExitMessage sent from server to client will contain the exit code
|
||||||
|
// when the process ends.
|
||||||
|
ExitMessage Exit = 6;
|
||||||
|
// DoneMessage from server to client will be the last message for any
|
||||||
|
// process. Note that FdMessage might be sent after ExitMessage.
|
||||||
|
DoneMessage Done = 7;
|
||||||
|
// SignalMessage is used from client to server to send signal events
|
||||||
|
SignalMessage Signal = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message InitMessage{
|
||||||
|
string ContainerID = 1;
|
||||||
|
pb.Meta Meta = 2;
|
||||||
|
repeated uint32 Fds = 3;
|
||||||
|
bool Tty = 4;
|
||||||
|
pb.SecurityMode Security = 5;
|
||||||
|
repeated pb.SecretEnv secretenv = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExitMessage {
|
||||||
|
uint32 Code = 1;
|
||||||
|
google.rpc.Status Error = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartedMessage{}
|
||||||
|
|
||||||
|
message DoneMessage{}
|
||||||
|
|
||||||
|
message FdMessage{
|
||||||
|
uint32 Fd = 1; // what fd the data was from
|
||||||
|
bool EOF = 2; // true if eof was reached
|
||||||
|
bytes Data = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResizeMessage{
|
||||||
|
uint32 Rows = 1;
|
||||||
|
uint32 Cols = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SignalMessage {
|
||||||
|
// we only send name (ie HUP, INT) because the int values
|
||||||
|
// are platform dependent.
|
||||||
|
string Name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Blob {
|
||||||
|
Descriptor descriptor = 1;
|
||||||
|
bytes data = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Descriptor {
|
||||||
|
string media_type = 1;
|
||||||
|
string digest = 2;
|
||||||
|
int64 size = 3;
|
||||||
|
map<string, string> annotations = 5;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.filesync.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/session/auth";
|
||||||
|
|
||||||
|
service Auth{
|
||||||
|
rpc Credentials(CredentialsRequest) returns (CredentialsResponse);
|
||||||
|
rpc FetchToken(FetchTokenRequest) returns (FetchTokenResponse);
|
||||||
|
rpc GetTokenAuthority(GetTokenAuthorityRequest) returns (GetTokenAuthorityResponse);
|
||||||
|
rpc VerifyTokenAuthority(VerifyTokenAuthorityRequest) returns (VerifyTokenAuthorityResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message CredentialsRequest {
|
||||||
|
string Host = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CredentialsResponse {
|
||||||
|
string Username = 1;
|
||||||
|
string Secret = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FetchTokenRequest {
|
||||||
|
string ClientID = 1;
|
||||||
|
string Host = 2;
|
||||||
|
string Realm = 3;
|
||||||
|
string Service = 4;
|
||||||
|
repeated string Scopes = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FetchTokenResponse {
|
||||||
|
string Token = 1;
|
||||||
|
int64 ExpiresIn = 2; // seconds
|
||||||
|
int64 IssuedAt = 3; // timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetTokenAuthorityRequest {
|
||||||
|
string Host = 1;
|
||||||
|
bytes Salt = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetTokenAuthorityResponse {
|
||||||
|
bytes PublicKey = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message VerifyTokenAuthorityRequest {
|
||||||
|
string Host = 1;
|
||||||
|
bytes Payload = 2;
|
||||||
|
bytes Salt = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message VerifyTokenAuthorityResponse {
|
||||||
|
bytes Signed = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.exporter.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/session/exporter";
|
||||||
|
|
||||||
|
service Exporter {
|
||||||
|
rpc FindExporters(FindExportersRequest) returns (FindExportersResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message FindExportersRequest{
|
||||||
|
map<string, bytes> metadata = 1;
|
||||||
|
repeated string refs = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FindExportersResponse {
|
||||||
|
repeated ExporterRequest exporters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExporterRequest {
|
||||||
|
string Type = 1;
|
||||||
|
map<string, string> Attrs = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.filesync.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/session/filesync";
|
||||||
|
|
||||||
|
import "github.com/tonistiigi/fsutil/types/wire.proto";
|
||||||
|
|
||||||
|
// FileSync exposes local files from the client to the server.
|
||||||
|
service FileSync{
|
||||||
|
rpc DiffCopy(stream fsutil.types.Packet) returns (stream fsutil.types.Packet);
|
||||||
|
rpc TarStream(stream fsutil.types.Packet) returns (stream fsutil.types.Packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileSend allows sending files from the server back to the client.
|
||||||
|
service FileSend{
|
||||||
|
rpc DiffCopy(stream BytesMessage) returns (stream BytesMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesMessage contains a chunk of byte data
|
||||||
|
message BytesMessage {
|
||||||
|
bytes data = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.buildkit.secrets.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/session/secrets";
|
||||||
|
|
||||||
|
service Secrets{
|
||||||
|
rpc GetSecret(GetSecretRequest) returns (GetSecretResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message GetSecretRequest {
|
||||||
|
string ID = 1;
|
||||||
|
map<string, string> annotations = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetSecretResponse {
|
||||||
|
bytes data = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.sshforward.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/session/sshforward";
|
||||||
|
|
||||||
|
service SSH {
|
||||||
|
rpc CheckAgent(CheckAgentRequest) returns (CheckAgentResponse);
|
||||||
|
rpc ForwardAgent(stream BytesMessage) returns (stream BytesMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesMessage contains a chunk of byte data
|
||||||
|
message BytesMessage{
|
||||||
|
bytes data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckAgentRequest {
|
||||||
|
string ID = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckAgentResponse {
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.upload.v1;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/session/upload";
|
||||||
|
|
||||||
|
service Upload {
|
||||||
|
rpc Pull(stream BytesMessage) returns (stream BytesMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BytesMessage contains a chunk of byte data
|
||||||
|
message BytesMessage{
|
||||||
|
bytes data = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package errdefs;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/solver/errdefs";
|
||||||
|
|
||||||
|
import "github.com/moby/buildkit/solver/pb/ops.proto";
|
||||||
|
|
||||||
|
message Vertex {
|
||||||
|
string digest = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Source {
|
||||||
|
pb.SourceInfo info = 1;
|
||||||
|
repeated pb.Range ranges = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Frontend {
|
||||||
|
string name = 1; // frontend name e.g. dockerfile.v0 or gateway.v0
|
||||||
|
string source = 2; // used by the gateway frontend to identify the source, which corresponds to the image name
|
||||||
|
}
|
||||||
|
|
||||||
|
message FrontendCap {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Subrequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Solve {
|
||||||
|
repeated string inputIDs = 1;
|
||||||
|
repeated string mountIDs = 2;
|
||||||
|
pb.Op op = 3;
|
||||||
|
|
||||||
|
oneof subject {
|
||||||
|
FileAction file = 4;
|
||||||
|
ContentCache cache = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
map<string, string> description = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileAction {
|
||||||
|
// Index of the file action that failed the exec.
|
||||||
|
int64 index = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ContentCache {
|
||||||
|
// Original index of result that failed the slow cache calculation.
|
||||||
|
int64 index = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,446 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
// Package pb provides the protobuf definition of LLB: low-level builder instruction.
|
||||||
|
// LLB is DAG-structured; Op represents a vertex, and Definition represents a graph.
|
||||||
|
package pb;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/solver/pb";
|
||||||
|
|
||||||
|
// Op represents a vertex of the LLB DAG.
|
||||||
|
message Op {
|
||||||
|
// changes to this structure must be represented in json.go.
|
||||||
|
// inputs is a set of input edges.
|
||||||
|
repeated Input inputs = 1;
|
||||||
|
oneof op {
|
||||||
|
ExecOp exec = 2;
|
||||||
|
SourceOp source = 3;
|
||||||
|
FileOp file = 4;
|
||||||
|
BuildOp build = 5;
|
||||||
|
MergeOp merge = 6;
|
||||||
|
DiffOp diff = 7;
|
||||||
|
}
|
||||||
|
Platform platform = 10;
|
||||||
|
WorkerConstraints constraints = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Platform is github.com/opencontainers/image-spec/specs-go/v1.Platform
|
||||||
|
message Platform {
|
||||||
|
string Architecture = 1;
|
||||||
|
string OS = 2;
|
||||||
|
string Variant = 3;
|
||||||
|
string OSVersion = 4;
|
||||||
|
repeated string OSFeatures = 5; // unused
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input represents an input edge for an Op.
|
||||||
|
message Input {
|
||||||
|
// digest of the marshaled input Op
|
||||||
|
string digest = 1;
|
||||||
|
// output index of the input Op
|
||||||
|
int64 index = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecOp executes a command in a container.
|
||||||
|
message ExecOp {
|
||||||
|
Meta meta = 1;
|
||||||
|
repeated Mount mounts = 2;
|
||||||
|
NetMode network = 3;
|
||||||
|
SecurityMode security = 4;
|
||||||
|
repeated SecretEnv secretenv = 5;
|
||||||
|
repeated CDIDevice cdiDevices = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Meta is a set of arguments for ExecOp.
|
||||||
|
// Meta is unrelated to LLB metadata.
|
||||||
|
// FIXME: rename (ExecContext? ExecArgs?)
|
||||||
|
message Meta {
|
||||||
|
repeated string args = 1;
|
||||||
|
repeated string env = 2;
|
||||||
|
string cwd = 3;
|
||||||
|
string user = 4;
|
||||||
|
ProxyEnv proxy_env = 5;
|
||||||
|
repeated HostIP extraHosts = 6;
|
||||||
|
string hostname = 7;
|
||||||
|
repeated Ulimit ulimit = 9;
|
||||||
|
string cgroupParent = 10;
|
||||||
|
bool removeMountStubsRecursive = 11;
|
||||||
|
repeated int32 validExitCodes = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
message HostIP {
|
||||||
|
string Host = 1;
|
||||||
|
string IP = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Ulimit {
|
||||||
|
string Name = 1;
|
||||||
|
int64 Soft = 2;
|
||||||
|
int64 Hard = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NetMode {
|
||||||
|
UNSET = 0; // sandbox
|
||||||
|
HOST = 1;
|
||||||
|
NONE = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SecurityMode {
|
||||||
|
SANDBOX = 0;
|
||||||
|
INSECURE = 1; // privileged mode
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretEnv is an environment variable that is backed by a secret.
|
||||||
|
message SecretEnv {
|
||||||
|
string ID = 1;
|
||||||
|
string name = 2;
|
||||||
|
bool optional = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CDIDevice specifies a CDI device information.
|
||||||
|
message CDIDevice {
|
||||||
|
// Fully qualified CDI device name (e.g., vendor.com/gpu=gpudevice1)
|
||||||
|
// https://github.com/cncf-tags/container-device-interface/blob/main/SPEC.md
|
||||||
|
string name = 1;
|
||||||
|
// Optional defines if CDI device is required.
|
||||||
|
bool optional = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mount specifies how to mount an input Op as a filesystem.
|
||||||
|
message Mount {
|
||||||
|
int64 input = 1;
|
||||||
|
string selector = 2;
|
||||||
|
string dest = 3;
|
||||||
|
int64 output = 4;
|
||||||
|
bool readonly = 5;
|
||||||
|
MountType mountType = 6;
|
||||||
|
TmpfsOpt TmpfsOpt = 19;
|
||||||
|
CacheOpt cacheOpt = 20;
|
||||||
|
SecretOpt secretOpt = 21;
|
||||||
|
SSHOpt SSHOpt = 22;
|
||||||
|
string resultID = 23;
|
||||||
|
MountContentCache contentCache = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MountType defines a type of a mount from a supported set
|
||||||
|
enum MountType {
|
||||||
|
BIND = 0;
|
||||||
|
SECRET = 1;
|
||||||
|
SSH = 2;
|
||||||
|
CACHE = 3;
|
||||||
|
TMPFS = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MountContentCache ...
|
||||||
|
enum MountContentCache {
|
||||||
|
DEFAULT = 0;
|
||||||
|
ON = 1;
|
||||||
|
OFF = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TmpfsOpt defines options describing tpmfs mounts
|
||||||
|
message TmpfsOpt {
|
||||||
|
// Specify an upper limit on the size of the filesystem.
|
||||||
|
int64 size = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CacheOpt defines options specific to cache mounts
|
||||||
|
message CacheOpt {
|
||||||
|
// ID is an optional namespace for the mount
|
||||||
|
string ID = 1;
|
||||||
|
// Sharing is the sharing mode for the mount
|
||||||
|
CacheSharingOpt sharing = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CacheSharingOpt defines different sharing modes for cache mount
|
||||||
|
enum CacheSharingOpt {
|
||||||
|
// SHARED cache mount can be used concurrently by multiple writers
|
||||||
|
SHARED = 0;
|
||||||
|
// PRIVATE creates a new mount if there are multiple writers
|
||||||
|
PRIVATE = 1;
|
||||||
|
// LOCKED pauses second writer until first one releases the mount
|
||||||
|
LOCKED = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretOpt defines options describing secret mounts
|
||||||
|
message SecretOpt {
|
||||||
|
// ID of secret. Used for quering the value.
|
||||||
|
string ID = 1;
|
||||||
|
// UID of secret file
|
||||||
|
uint32 uid = 2;
|
||||||
|
// GID of secret file
|
||||||
|
uint32 gid = 3;
|
||||||
|
// Mode is the filesystem mode of secret file
|
||||||
|
uint32 mode = 4;
|
||||||
|
// Optional defines if secret value is required. Error is produced
|
||||||
|
// if value is not found and optional is false.
|
||||||
|
bool optional = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSHOpt defines options describing ssh mounts
|
||||||
|
message SSHOpt {
|
||||||
|
// ID of exposed ssh rule. Used for quering the value.
|
||||||
|
string ID = 1;
|
||||||
|
// UID of agent socket
|
||||||
|
uint32 uid = 2;
|
||||||
|
// GID of agent socket
|
||||||
|
uint32 gid = 3;
|
||||||
|
// Mode is the filesystem mode of agent socket
|
||||||
|
uint32 mode = 4;
|
||||||
|
// Optional defines if ssh socket is required. Error is produced
|
||||||
|
// if client does not expose ssh.
|
||||||
|
bool optional = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SourceOp specifies a source such as build contexts and images.
|
||||||
|
message SourceOp {
|
||||||
|
// TODO: use source type or any type instead of URL protocol.
|
||||||
|
// identifier e.g. local://, docker-image://, git://, https://...
|
||||||
|
string identifier = 1;
|
||||||
|
// attrs are defined in attr.go
|
||||||
|
map<string, string> attrs = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildOp is used for nested build invocation.
|
||||||
|
// BuildOp is experimental and can break without backwards compatibility
|
||||||
|
message BuildOp {
|
||||||
|
int64 builder = 1;
|
||||||
|
map<string, BuildInput> inputs = 2;
|
||||||
|
Definition def = 3;
|
||||||
|
map<string, string> attrs = 4;
|
||||||
|
// outputs
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildInput is used for BuildOp.
|
||||||
|
message BuildInput {
|
||||||
|
int64 input = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpMetadata is a per-vertex metadata entry, which can be defined for arbitrary Op vertex and overridable on the run time.
|
||||||
|
message OpMetadata {
|
||||||
|
// ignore_cache specifies to ignore the cache for this Op.
|
||||||
|
bool ignore_cache = 1;
|
||||||
|
// Description can be used for keeping any text fields that builder doesn't parse
|
||||||
|
map<string, string> description = 2;
|
||||||
|
// index 3 reserved for WorkerConstraint in previous versions
|
||||||
|
// WorkerConstraint worker_constraint = 3;
|
||||||
|
ExportCache export_cache = 4;
|
||||||
|
|
||||||
|
map<string, bool> caps = 5;
|
||||||
|
|
||||||
|
ProgressGroup progress_group = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source is a source mapping description for a file
|
||||||
|
message Source {
|
||||||
|
map<string, Locations> locations = 1;
|
||||||
|
repeated SourceInfo infos = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locations is a list of ranges with a index to its source map.
|
||||||
|
message Locations {
|
||||||
|
repeated Location locations = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source info contains the shared metadata of a source mapping
|
||||||
|
message SourceInfo {
|
||||||
|
string filename = 1;
|
||||||
|
bytes data = 2;
|
||||||
|
Definition definition = 3;
|
||||||
|
string language = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Location defines list of areas in to source file
|
||||||
|
message Location {
|
||||||
|
int32 sourceIndex = 1;
|
||||||
|
repeated Range ranges = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range is an area in the source file
|
||||||
|
message Range {
|
||||||
|
Position start = 1;
|
||||||
|
Position end = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position is single location in a source file
|
||||||
|
message Position {
|
||||||
|
int32 line = 1;
|
||||||
|
int32 character = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExportCache {
|
||||||
|
bool Value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ProgressGroup {
|
||||||
|
string id = 1;
|
||||||
|
string name = 2;
|
||||||
|
bool weak = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ProxyEnv {
|
||||||
|
string http_proxy = 1;
|
||||||
|
string https_proxy = 2;
|
||||||
|
string ftp_proxy = 3;
|
||||||
|
string no_proxy = 4;
|
||||||
|
string all_proxy = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WorkerConstraints defines conditions for the worker
|
||||||
|
message WorkerConstraints {
|
||||||
|
repeated string filter = 1; // containerd-style filter
|
||||||
|
}
|
||||||
|
|
||||||
|
// Definition is the LLB definition structure with per-vertex metadata entries
|
||||||
|
message Definition {
|
||||||
|
// def is a list of marshaled Op messages
|
||||||
|
repeated bytes def = 1;
|
||||||
|
// metadata contains metadata for the each of the Op messages.
|
||||||
|
// A key must be an LLB op digest string. Currently, empty string is not expected as a key, but it may change in the future.
|
||||||
|
map<string, OpMetadata> metadata = 2;
|
||||||
|
// Source contains the source mapping information for the vertexes in the definition
|
||||||
|
Source Source = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileOp {
|
||||||
|
repeated FileAction actions = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileAction {
|
||||||
|
// changes to this structure must be represented in json.go.
|
||||||
|
int64 input = 1; // could be real input or target (target index + max input index)
|
||||||
|
int64 secondaryInput = 2; // --//--
|
||||||
|
int64 output = 3;
|
||||||
|
oneof action {
|
||||||
|
// FileActionCopy copies files from secondaryInput on top of input
|
||||||
|
FileActionCopy copy = 4;
|
||||||
|
// FileActionMkFile creates a new file
|
||||||
|
FileActionMkFile mkfile = 5;
|
||||||
|
// FileActionMkDir creates a new directory
|
||||||
|
FileActionMkDir mkdir = 6;
|
||||||
|
// FileActionRm removes a file
|
||||||
|
FileActionRm rm = 7;
|
||||||
|
// FileActionSymlink creates a symlink
|
||||||
|
FileActionSymlink symlink = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileActionCopy {
|
||||||
|
// src is the source path
|
||||||
|
string src = 1;
|
||||||
|
// dest path
|
||||||
|
string dest = 2;
|
||||||
|
// optional owner override
|
||||||
|
ChownOpt owner = 3;
|
||||||
|
// optional permission bits override
|
||||||
|
int32 mode = 4;
|
||||||
|
// followSymlink resolves symlinks in src
|
||||||
|
bool followSymlink = 5;
|
||||||
|
// dirCopyContents only copies contents if src is a directory
|
||||||
|
bool dirCopyContents = 6;
|
||||||
|
// attemptUnpackDockerCompatibility detects if src is an archive to unpack it instead
|
||||||
|
bool attemptUnpackDockerCompatibility = 7;
|
||||||
|
// createDestPath creates dest path directories if needed
|
||||||
|
bool createDestPath = 8;
|
||||||
|
// allowWildcard allows filepath.Match wildcards in src path
|
||||||
|
bool allowWildcard = 9;
|
||||||
|
// allowEmptyWildcard doesn't fail the whole copy if wildcard doesn't resolve to files
|
||||||
|
bool allowEmptyWildcard = 10;
|
||||||
|
// optional created time override
|
||||||
|
int64 timestamp = 11;
|
||||||
|
// include only files/dirs matching at least one of these patterns
|
||||||
|
repeated string include_patterns = 12;
|
||||||
|
// exclude files/dir matching any of these patterns (even if they match an include pattern)
|
||||||
|
repeated string exclude_patterns = 13;
|
||||||
|
// alwaysReplaceExistingDestPaths results in an existing dest path that differs in type from the src path being replaced rather than the default of returning an error
|
||||||
|
bool alwaysReplaceExistingDestPaths = 14;
|
||||||
|
// mode in non-octal format
|
||||||
|
string modeStr = 15;
|
||||||
|
// required paths that must be included in the copy. This is only used when
|
||||||
|
// include_patterns has at least one pattern.
|
||||||
|
repeated string required_paths = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileActionMkFile {
|
||||||
|
// path for the new file
|
||||||
|
string path = 1;
|
||||||
|
// permission bits
|
||||||
|
int32 mode = 2;
|
||||||
|
// data is the new file contents
|
||||||
|
bytes data = 3;
|
||||||
|
// optional owner for the new file
|
||||||
|
ChownOpt owner = 4;
|
||||||
|
// optional created time override
|
||||||
|
int64 timestamp = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileActionSymlink {
|
||||||
|
// destination path for the new file representing the link
|
||||||
|
string oldpath = 1;
|
||||||
|
// source path for the link
|
||||||
|
string newpath = 2;
|
||||||
|
// optional owner for the new file
|
||||||
|
ChownOpt owner = 3;
|
||||||
|
// optional created time override
|
||||||
|
int64 timestamp = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileActionMkDir {
|
||||||
|
// path for the new directory
|
||||||
|
string path = 1;
|
||||||
|
// permission bits
|
||||||
|
int32 mode = 2;
|
||||||
|
// makeParents creates parent directories as well if needed
|
||||||
|
bool makeParents = 3;
|
||||||
|
// optional owner for the new directory
|
||||||
|
ChownOpt owner = 4;
|
||||||
|
// optional created time override
|
||||||
|
int64 timestamp = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FileActionRm {
|
||||||
|
// path to remove
|
||||||
|
string path = 1;
|
||||||
|
// allowNotFound doesn't fail the rm if file is not found
|
||||||
|
bool allowNotFound = 2;
|
||||||
|
// allowWildcard allows filepath.Match wildcards in path
|
||||||
|
bool allowWildcard = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ChownOpt {
|
||||||
|
UserOpt user = 1;
|
||||||
|
UserOpt group = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UserOpt {
|
||||||
|
// changes to this structure must be represented in json.go.
|
||||||
|
oneof user {
|
||||||
|
NamedUserOpt byName = 1;
|
||||||
|
uint32 byID = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message NamedUserOpt {
|
||||||
|
string name = 1;
|
||||||
|
int64 input = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MergeInput {
|
||||||
|
int64 input = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MergeOp {
|
||||||
|
repeated MergeInput inputs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message LowerDiffInput {
|
||||||
|
int64 input = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpperDiffInput {
|
||||||
|
int64 input = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DiffOp {
|
||||||
|
LowerDiffInput lower = 1;
|
||||||
|
UpperDiffInput upper = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.buildkit.v1.sourcepolicy;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/sourcepolicy/pb;moby_buildkit_v1_sourcepolicy";
|
||||||
|
|
||||||
|
// Rule defines the action(s) to take when a source is matched
|
||||||
|
message Rule {
|
||||||
|
PolicyAction action = 1;
|
||||||
|
Selector selector = 2;
|
||||||
|
Update updates = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update contains updates to the matched build step after rule is applied
|
||||||
|
message Update {
|
||||||
|
string identifier = 1;
|
||||||
|
map<string, string> attrs = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selector identifies a source to match a policy to
|
||||||
|
message Selector {
|
||||||
|
string identifier = 1;
|
||||||
|
// MatchType is the type of match to perform on the source identifier
|
||||||
|
MatchType match_type = 2;
|
||||||
|
repeated AttrConstraint constraints = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PolicyAction defines the action to take when a source is matched
|
||||||
|
enum PolicyAction {
|
||||||
|
ALLOW = 0;
|
||||||
|
DENY = 1;
|
||||||
|
CONVERT = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AttrConstraint defines a constraint on a source attribute
|
||||||
|
message AttrConstraint {
|
||||||
|
string key = 1;
|
||||||
|
string value = 2;
|
||||||
|
AttrMatch condition = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AttrMatch defines the condition to match a source attribute
|
||||||
|
enum AttrMatch {
|
||||||
|
EQUAL = 0;
|
||||||
|
NOTEQUAL = 1;
|
||||||
|
MATCHES = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Policy is the list of rules the policy engine will perform
|
||||||
|
message Policy {
|
||||||
|
int64 version = 1; // Currently 1
|
||||||
|
repeated Rule rules = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match type is used to determine how a rule source is matched
|
||||||
|
enum MatchType {
|
||||||
|
// WILDCARD is the default matching type.
|
||||||
|
// It may first attempt to due an exact match but will follow up with a wildcard match
|
||||||
|
// For something more powerful, use REGEX
|
||||||
|
WILDCARD = 0;
|
||||||
|
// EXACT treats the source identifier as a litteral string match
|
||||||
|
EXACT = 1;
|
||||||
|
// REGEX treats the source identifier as a regular expression
|
||||||
|
// With regex matching you can also use match groups to replace values in the destination identifier
|
||||||
|
REGEX = 2;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.buildkit.v1.sourcepolicy.policysession;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/sourcepolicy/policysession";
|
||||||
|
|
||||||
|
import "github.com/moby/buildkit/frontend/gateway/pb/gateway.proto";
|
||||||
|
import "github.com/moby/buildkit/solver/pb/ops.proto";
|
||||||
|
import "github.com/moby/buildkit/sourcepolicy/pb/policy.proto";
|
||||||
|
|
||||||
|
service PolicyVerifier {
|
||||||
|
rpc CheckPolicy(CheckPolicyRequest) returns (CheckPolicyResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckPolicyRequest {
|
||||||
|
pb.Platform Platform = 1;
|
||||||
|
moby.buildkit.v1.frontend.ResolveSourceMetaResponse Source = 2;
|
||||||
|
map<string, bool> caps = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckPolicyResponse {
|
||||||
|
oneof result {
|
||||||
|
DecisionResponse decision = 1;
|
||||||
|
moby.buildkit.v1.frontend.ResolveSourceMetaRequest request = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message DecisionResponse {
|
||||||
|
moby.buildkit.v1.sourcepolicy.PolicyAction action = 1;
|
||||||
|
repeated DenyMessage denyMessages = 2;
|
||||||
|
pb.SourceOp update = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DenyMessage {
|
||||||
|
string message = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package moby.buildkit.v1.apicaps;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/util/apicaps/pb;moby_buildkit_v1_apicaps";
|
||||||
|
|
||||||
|
// APICap defines a capability supported by the service
|
||||||
|
message APICap {
|
||||||
|
string ID = 1;
|
||||||
|
bool Enabled = 2;
|
||||||
|
bool Deprecated = 3; // Unused. May be used for warnings in the future
|
||||||
|
string DisabledReason = 4; // Reason key for detection code
|
||||||
|
string DisabledReasonMsg = 5; // Message to the user
|
||||||
|
string DisabledAlternative = 6; // Identifier that updated client could catch.
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package stack;
|
||||||
|
|
||||||
|
option go_package = "github.com/moby/buildkit/util/stack";
|
||||||
|
|
||||||
|
message Stack {
|
||||||
|
repeated Frame frames = 1;
|
||||||
|
repeated string cmdline = 2;
|
||||||
|
int32 pid = 3;
|
||||||
|
string version = 4;
|
||||||
|
string revision = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Frame {
|
||||||
|
string Name = 1;
|
||||||
|
string File = 2;
|
||||||
|
int32 Line = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// Stub for vtprotobuf extensions — not needed for Rust codegen
|
||||||
|
syntax = "proto3";
|
||||||
|
package vtproto;
|
||||||
|
import "google/protobuf/descriptor.proto";
|
||||||
|
extend google.protobuf.MessageOptions {
|
||||||
|
bool mempool = 64101;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package fsutil.types;
|
||||||
|
|
||||||
|
option go_package = "github.com/tonistiigi/fsutil/types";
|
||||||
|
|
||||||
|
import "github.com/planetscale/vtprotobuf/vtproto/ext.proto";
|
||||||
|
|
||||||
|
message Stat {
|
||||||
|
string path = 1;
|
||||||
|
uint32 mode = 2;
|
||||||
|
uint32 uid = 3;
|
||||||
|
uint32 gid = 4;
|
||||||
|
int64 size = 5;
|
||||||
|
int64 modTime = 6;
|
||||||
|
// int32 typeflag = 7;
|
||||||
|
string linkname = 7;
|
||||||
|
int64 devmajor = 8;
|
||||||
|
int64 devminor = 9;
|
||||||
|
map<string, bytes> xattrs = 10;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package fsutil.types;
|
||||||
|
|
||||||
|
option go_package = "github.com/tonistiigi/fsutil/types";
|
||||||
|
|
||||||
|
import "github.com/planetscale/vtprotobuf/vtproto/ext.proto";
|
||||||
|
import "github.com/tonistiigi/fsutil/types/stat.proto";
|
||||||
|
|
||||||
|
message Packet {
|
||||||
|
option (vtproto.mempool) = true;
|
||||||
|
enum PacketType {
|
||||||
|
PACKET_STAT = 0;
|
||||||
|
PACKET_REQ = 1;
|
||||||
|
PACKET_DATA = 2;
|
||||||
|
PACKET_FIN = 3;
|
||||||
|
PACKET_ERR = 4;
|
||||||
|
}
|
||||||
|
PacketType type = 1;
|
||||||
|
Stat stat = 2;
|
||||||
|
uint32 ID = 3;
|
||||||
|
bytes data = 4;
|
||||||
|
}
|
||||||
49
wfe-buildkit-protos/proto/google/rpc/status.proto
Normal file
49
wfe-buildkit-protos/proto/google/rpc/status.proto
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2025 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package google.rpc;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
|
||||||
|
option cc_enable_arenas = true;
|
||||||
|
option go_package = "google.golang.org/genproto/googleapis/rpc/status;status";
|
||||||
|
option java_multiple_files = true;
|
||||||
|
option java_outer_classname = "StatusProto";
|
||||||
|
option java_package = "com.google.rpc";
|
||||||
|
option objc_class_prefix = "RPC";
|
||||||
|
|
||||||
|
// The `Status` type defines a logical error model that is suitable for
|
||||||
|
// different programming environments, including REST APIs and RPC APIs. It is
|
||||||
|
// used by [gRPC](https://github.com/grpc). Each `Status` message contains
|
||||||
|
// three pieces of data: error code, error message, and error details.
|
||||||
|
//
|
||||||
|
// You can find out more about this error model and how to work with it in the
|
||||||
|
// [API Design Guide](https://cloud.google.com/apis/design/errors).
|
||||||
|
message Status {
|
||||||
|
// The status code, which should be an enum value of
|
||||||
|
// [google.rpc.Code][google.rpc.Code].
|
||||||
|
int32 code = 1;
|
||||||
|
|
||||||
|
// A developer-facing error message, which should be in English. Any
|
||||||
|
// user-facing error message should be localized and sent in the
|
||||||
|
// [google.rpc.Status.details][google.rpc.Status.details] field, or localized
|
||||||
|
// by the client.
|
||||||
|
string message = 2;
|
||||||
|
|
||||||
|
// A list of messages that carry the error details. There is a common set of
|
||||||
|
// message types for APIs to use.
|
||||||
|
repeated google.protobuf.Any details = 3;
|
||||||
|
}
|
||||||
19
wfe-buildkit-protos/src/lib.rs
Normal file
19
wfe-buildkit-protos/src/lib.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//! Generated gRPC stubs for the full BuildKit API.
|
||||||
|
//!
|
||||||
|
//! Built from the official BuildKit proto files at
|
||||||
|
//! <https://github.com/moby/buildkit>.
|
||||||
|
//!
|
||||||
|
//! ```rust,ignore
|
||||||
|
//! use wfe_buildkit_protos::moby::buildkit::v1::control_client::ControlClient;
|
||||||
|
//! use wfe_buildkit_protos::moby::buildkit::v1::StatusResponse;
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
#![allow(clippy::all)]
|
||||||
|
#![allow(warnings)]
|
||||||
|
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/mod.rs"));
|
||||||
|
|
||||||
|
/// Re-export tonic and prost for downstream convenience.
|
||||||
|
pub use prost;
|
||||||
|
pub use prost_types;
|
||||||
|
pub use tonic;
|
||||||
30
wfe-buildkit/Cargo.toml
Normal file
30
wfe-buildkit/Cargo.toml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
[package]
|
||||||
|
name = "wfe-buildkit"
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
repository.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
|
description = "BuildKit image builder executor for WFE"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wfe-core = { workspace = true }
|
||||||
|
tokio = { workspace = true }
|
||||||
|
serde = { workspace = true }
|
||||||
|
serde_json = { workspace = true }
|
||||||
|
async-trait = { workspace = true }
|
||||||
|
tracing = { workspace = true }
|
||||||
|
thiserror = { workspace = true }
|
||||||
|
regex = { workspace = true }
|
||||||
|
wfe-buildkit-protos = { version = "1.8.0", path = "../wfe-buildkit-protos", registry = "sunbeam" }
|
||||||
|
tonic = "0.14"
|
||||||
|
tower = { version = "0.4", features = ["util"] }
|
||||||
|
hyper-util = { version = "0.1", features = ["tokio"] }
|
||||||
|
uuid = { version = "1", features = ["v4"] }
|
||||||
|
tokio-stream = "0.1"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
pretty_assertions = { workspace = true }
|
||||||
|
tempfile = { workspace = true }
|
||||||
|
tokio = { workspace = true, features = ["test-util"] }
|
||||||
|
tokio-util = "0.7"
|
||||||
95
wfe-buildkit/README.md
Normal file
95
wfe-buildkit/README.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# wfe-buildkit
|
||||||
|
|
||||||
|
BuildKit image builder executor for WFE.
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
`wfe-buildkit` provides a `BuildkitStep` that implements the `StepBody` trait from `wfe-core`. It shells out to the `buildctl` CLI to build container images using BuildKit, capturing stdout/stderr and parsing image digests from the output.
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
Use it standalone:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use wfe_buildkit::{BuildkitConfig, BuildkitStep};
|
||||||
|
|
||||||
|
let config = BuildkitConfig {
|
||||||
|
dockerfile: "Dockerfile".to_string(),
|
||||||
|
context: ".".to_string(),
|
||||||
|
tags: vec!["myapp:latest".to_string()],
|
||||||
|
push: true,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
|
||||||
|
// Inspect the command that would be executed.
|
||||||
|
let args = step.build_command();
|
||||||
|
println!("{}", args.join(" "));
|
||||||
|
```
|
||||||
|
|
||||||
|
Or use it through `wfe-yaml` with the `buildkit` feature:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
workflow:
|
||||||
|
id: build-image
|
||||||
|
version: 1
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
type: buildkit
|
||||||
|
config:
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
context: .
|
||||||
|
tags:
|
||||||
|
- myapp:latest
|
||||||
|
- myapp:v1.0
|
||||||
|
push: true
|
||||||
|
build_args:
|
||||||
|
RUST_VERSION: "1.78"
|
||||||
|
cache_from:
|
||||||
|
- type=registry,ref=myapp:cache
|
||||||
|
cache_to:
|
||||||
|
- type=registry,ref=myapp:cache,mode=max
|
||||||
|
timeout: 10m
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
| Field | Type | Required | Default | Description |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| `dockerfile` | String | Yes | - | Path to the Dockerfile |
|
||||||
|
| `context` | String | Yes | - | Build context directory |
|
||||||
|
| `target` | String | No | - | Multi-stage build target |
|
||||||
|
| `tags` | Vec\<String\> | No | [] | Image tags |
|
||||||
|
| `build_args` | Map\<String, String\> | No | {} | Build arguments |
|
||||||
|
| `cache_from` | Vec\<String\> | No | [] | Cache import sources |
|
||||||
|
| `cache_to` | Vec\<String\> | No | [] | Cache export destinations |
|
||||||
|
| `push` | bool | No | false | Push image after build |
|
||||||
|
| `output_type` | String | No | "image" | Output type: image, local, tar |
|
||||||
|
| `buildkit_addr` | String | No | unix:///run/buildkit/buildkitd.sock | BuildKit daemon address |
|
||||||
|
| `tls` | TlsConfig | No | - | TLS certificate paths |
|
||||||
|
| `registry_auth` | Map\<String, RegistryAuth\> | No | {} | Registry credentials |
|
||||||
|
| `timeout_ms` | u64 | No | - | Execution timeout in milliseconds |
|
||||||
|
|
||||||
|
## Output data
|
||||||
|
|
||||||
|
After execution, the step writes the following keys into `output_data`:
|
||||||
|
|
||||||
|
| Key | Description |
|
||||||
|
|---|---|
|
||||||
|
| `{step_name}.digest` | Image digest (sha256:...), if found in output |
|
||||||
|
| `{step_name}.tags` | Array of tags applied to the image |
|
||||||
|
| `{step_name}.stdout` | Full stdout from buildctl |
|
||||||
|
| `{step_name}.stderr` | Full stderr from buildctl |
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo test -p wfe-buildkit
|
||||||
|
```
|
||||||
|
|
||||||
|
The `build_command()` method returns the full argument list without executing, making it possible to test command construction without a running BuildKit daemon.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
358
wfe-buildkit/src/config.rs
Normal file
358
wfe-buildkit/src/config.rs
Normal file
@@ -0,0 +1,358 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Configuration for a BuildKit image build step.
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct BuildkitConfig {
|
||||||
|
/// Path to the Dockerfile (or directory containing it).
|
||||||
|
pub dockerfile: String,
|
||||||
|
/// Build context directory.
|
||||||
|
pub context: String,
|
||||||
|
/// Multi-stage build target.
|
||||||
|
pub target: Option<String>,
|
||||||
|
/// Image tags to apply.
|
||||||
|
#[serde(default)]
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
/// Build arguments passed as `--opt build-arg:KEY=VALUE`.
|
||||||
|
#[serde(default)]
|
||||||
|
pub build_args: HashMap<String, String>,
|
||||||
|
/// Cache import sources.
|
||||||
|
#[serde(default)]
|
||||||
|
pub cache_from: Vec<String>,
|
||||||
|
/// Cache export destinations.
|
||||||
|
#[serde(default)]
|
||||||
|
pub cache_to: Vec<String>,
|
||||||
|
/// Whether to push the built image.
|
||||||
|
#[serde(default)]
|
||||||
|
pub push: bool,
|
||||||
|
/// Output type: "image", "local", "tar".
|
||||||
|
pub output_type: Option<String>,
|
||||||
|
/// BuildKit daemon address.
|
||||||
|
#[serde(default = "default_buildkit_addr")]
|
||||||
|
pub buildkit_addr: String,
|
||||||
|
/// TLS configuration for the BuildKit connection.
|
||||||
|
#[serde(default)]
|
||||||
|
pub tls: TlsConfig,
|
||||||
|
/// Registry authentication credentials keyed by registry host.
|
||||||
|
#[serde(default)]
|
||||||
|
pub registry_auth: HashMap<String, RegistryAuth>,
|
||||||
|
/// Execution timeout in milliseconds.
|
||||||
|
pub timeout_ms: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TLS certificate paths for securing the BuildKit connection.
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct TlsConfig {
|
||||||
|
/// Path to the CA certificate.
|
||||||
|
pub ca: Option<String>,
|
||||||
|
/// Path to the client certificate.
|
||||||
|
pub cert: Option<String>,
|
||||||
|
/// Path to the client private key.
|
||||||
|
pub key: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Credentials for authenticating with a container registry.
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct RegistryAuth {
|
||||||
|
pub username: String,
|
||||||
|
pub password: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_buildkit_addr() -> String {
|
||||||
|
"unix:///run/buildkit/buildkitd.sock".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_round_trip_full_config() {
|
||||||
|
let mut build_args = HashMap::new();
|
||||||
|
build_args.insert("RUST_VERSION".to_string(), "1.78".to_string());
|
||||||
|
|
||||||
|
let mut registry_auth = HashMap::new();
|
||||||
|
registry_auth.insert(
|
||||||
|
"ghcr.io".to_string(),
|
||||||
|
RegistryAuth {
|
||||||
|
username: "user".to_string(),
|
||||||
|
password: "pass".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let config = BuildkitConfig {
|
||||||
|
dockerfile: "./Dockerfile".to_string(),
|
||||||
|
context: ".".to_string(),
|
||||||
|
target: Some("runtime".to_string()),
|
||||||
|
tags: vec!["myapp:latest".to_string(), "myapp:v1.0".to_string()],
|
||||||
|
build_args,
|
||||||
|
cache_from: vec!["type=registry,ref=myapp:cache".to_string()],
|
||||||
|
cache_to: vec!["type=registry,ref=myapp:cache,mode=max".to_string()],
|
||||||
|
push: true,
|
||||||
|
output_type: Some("image".to_string()),
|
||||||
|
buildkit_addr: "tcp://buildkitd:1234".to_string(),
|
||||||
|
tls: TlsConfig {
|
||||||
|
ca: Some("/certs/ca.pem".to_string()),
|
||||||
|
cert: Some("/certs/cert.pem".to_string()),
|
||||||
|
key: Some("/certs/key.pem".to_string()),
|
||||||
|
},
|
||||||
|
registry_auth,
|
||||||
|
timeout_ms: Some(300_000),
|
||||||
|
};
|
||||||
|
|
||||||
|
let json = serde_json::to_string(&config).unwrap();
|
||||||
|
let deserialized: BuildkitConfig = serde_json::from_str(&json).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(config.dockerfile, deserialized.dockerfile);
|
||||||
|
assert_eq!(config.context, deserialized.context);
|
||||||
|
assert_eq!(config.target, deserialized.target);
|
||||||
|
assert_eq!(config.tags, deserialized.tags);
|
||||||
|
assert_eq!(config.build_args, deserialized.build_args);
|
||||||
|
assert_eq!(config.cache_from, deserialized.cache_from);
|
||||||
|
assert_eq!(config.cache_to, deserialized.cache_to);
|
||||||
|
assert_eq!(config.push, deserialized.push);
|
||||||
|
assert_eq!(config.output_type, deserialized.output_type);
|
||||||
|
assert_eq!(config.buildkit_addr, deserialized.buildkit_addr);
|
||||||
|
assert_eq!(config.tls.ca, deserialized.tls.ca);
|
||||||
|
assert_eq!(config.tls.cert, deserialized.tls.cert);
|
||||||
|
assert_eq!(config.tls.key, deserialized.tls.key);
|
||||||
|
assert_eq!(config.timeout_ms, deserialized.timeout_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_round_trip_minimal_config() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": "."
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(config.dockerfile, "Dockerfile");
|
||||||
|
assert_eq!(config.context, ".");
|
||||||
|
assert_eq!(config.target, None);
|
||||||
|
assert!(config.tags.is_empty());
|
||||||
|
assert!(config.build_args.is_empty());
|
||||||
|
assert!(config.cache_from.is_empty());
|
||||||
|
assert!(config.cache_to.is_empty());
|
||||||
|
assert!(!config.push);
|
||||||
|
assert_eq!(config.output_type, None);
|
||||||
|
assert_eq!(config.buildkit_addr, "unix:///run/buildkit/buildkitd.sock");
|
||||||
|
assert_eq!(config.timeout_ms, None);
|
||||||
|
|
||||||
|
// Round-trip
|
||||||
|
let serialized = serde_json::to_string(&config).unwrap();
|
||||||
|
let deserialized: BuildkitConfig = serde_json::from_str(&serialized).unwrap();
|
||||||
|
assert_eq!(config.dockerfile, deserialized.dockerfile);
|
||||||
|
assert_eq!(config.context, deserialized.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn default_buildkit_addr_value() {
|
||||||
|
let addr = default_buildkit_addr();
|
||||||
|
assert_eq!(addr, "unix:///run/buildkit/buildkitd.sock");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tls_config_defaults_to_none() {
|
||||||
|
let tls = TlsConfig::default();
|
||||||
|
assert_eq!(tls.ca, None);
|
||||||
|
assert_eq!(tls.cert, None);
|
||||||
|
assert_eq!(tls.key, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn registry_auth_serde() {
|
||||||
|
let auth = RegistryAuth {
|
||||||
|
username: "admin".to_string(),
|
||||||
|
password: "secret123".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let json = serde_json::to_string(&auth).unwrap();
|
||||||
|
let deserialized: RegistryAuth = serde_json::from_str(&json).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(auth.username, deserialized.username);
|
||||||
|
assert_eq!(auth.password, deserialized.password);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_custom_addr() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"buildkit_addr": "tcp://remote:1234"
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.buildkit_addr, "tcp://remote:1234");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_with_timeout() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"timeout_ms": 60000
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.timeout_ms, Some(60000));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_with_tags_and_push() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"tags": ["myapp:latest", "myapp:v1.0"],
|
||||||
|
"push": true
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.tags, vec!["myapp:latest", "myapp:v1.0"]);
|
||||||
|
assert!(config.push);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_with_build_args() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"build_args": {"VERSION": "1.0", "DEBUG": "false"}
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.build_args.len(), 2);
|
||||||
|
assert_eq!(config.build_args["VERSION"], "1.0");
|
||||||
|
assert_eq!(config.build_args["DEBUG"], "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_with_cache_config() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"cache_from": ["type=registry,ref=cache:latest"],
|
||||||
|
"cache_to": ["type=registry,ref=cache:latest,mode=max"]
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.cache_from.len(), 1);
|
||||||
|
assert_eq!(config.cache_to.len(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_with_output_type() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"output_type": "tar"
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.output_type, Some("tar".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_with_registry_auth() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"registry_auth": {
|
||||||
|
"ghcr.io": {"username": "bot", "password": "tok"},
|
||||||
|
"docker.io": {"username": "u", "password": "p"}
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.registry_auth.len(), 2);
|
||||||
|
assert_eq!(config.registry_auth["ghcr.io"].username, "bot");
|
||||||
|
assert_eq!(config.registry_auth["docker.io"].password, "p");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_with_tls() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"tls": {
|
||||||
|
"ca": "/certs/ca.pem",
|
||||||
|
"cert": "/certs/cert.pem",
|
||||||
|
"key": "/certs/key.pem"
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.tls.ca, Some("/certs/ca.pem".to_string()));
|
||||||
|
assert_eq!(config.tls.cert, Some("/certs/cert.pem".to_string()));
|
||||||
|
assert_eq!(config.tls.key, Some("/certs/key.pem".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_partial_tls() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"tls": {"ca": "/certs/ca.pem"}
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.tls.ca, Some("/certs/ca.pem".to_string()));
|
||||||
|
assert_eq!(config.tls.cert, None);
|
||||||
|
assert_eq!(config.tls.key, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_empty_tls_object() {
|
||||||
|
let json = r#"{
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"context": ".",
|
||||||
|
"tls": {}
|
||||||
|
}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
assert_eq!(config.tls.ca, None);
|
||||||
|
assert_eq!(config.tls.cert, None);
|
||||||
|
assert_eq!(config.tls.key, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tls_config_clone() {
|
||||||
|
let tls = TlsConfig {
|
||||||
|
ca: Some("ca".to_string()),
|
||||||
|
cert: Some("cert".to_string()),
|
||||||
|
key: Some("key".to_string()),
|
||||||
|
};
|
||||||
|
let cloned = tls.clone();
|
||||||
|
assert_eq!(tls.ca, cloned.ca);
|
||||||
|
assert_eq!(tls.cert, cloned.cert);
|
||||||
|
assert_eq!(tls.key, cloned.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tls_config_debug() {
|
||||||
|
let tls = TlsConfig::default();
|
||||||
|
let debug = format!("{:?}", tls);
|
||||||
|
assert!(debug.contains("TlsConfig"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn buildkit_config_debug() {
|
||||||
|
let json = r#"{"dockerfile": "Dockerfile", "context": "."}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
let debug = format!("{:?}", config);
|
||||||
|
assert!(debug.contains("BuildkitConfig"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn registry_auth_clone() {
|
||||||
|
let auth = RegistryAuth {
|
||||||
|
username: "u".to_string(),
|
||||||
|
password: "p".to_string(),
|
||||||
|
};
|
||||||
|
let cloned = auth.clone();
|
||||||
|
assert_eq!(auth.username, cloned.username);
|
||||||
|
assert_eq!(auth.password, cloned.password);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn buildkit_config_clone() {
|
||||||
|
let json = r#"{"dockerfile": "Dockerfile", "context": "."}"#;
|
||||||
|
let config: BuildkitConfig = serde_json::from_str(json).unwrap();
|
||||||
|
let cloned = config.clone();
|
||||||
|
assert_eq!(config.dockerfile, cloned.dockerfile);
|
||||||
|
assert_eq!(config.context, cloned.context);
|
||||||
|
assert_eq!(config.buildkit_addr, cloned.buildkit_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
5
wfe-buildkit/src/lib.rs
Normal file
5
wfe-buildkit/src/lib.rs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
pub mod config;
|
||||||
|
pub mod step;
|
||||||
|
|
||||||
|
pub use config::{BuildkitConfig, RegistryAuth, TlsConfig};
|
||||||
|
pub use step::{build_output_data, parse_digest, BuildkitStep};
|
||||||
905
wfe-buildkit/src/step.rs
Normal file
905
wfe-buildkit/src/step.rs
Normal file
@@ -0,0 +1,905 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use regex::Regex;
|
||||||
|
use tokio_stream::StreamExt;
|
||||||
|
use tonic::transport::{Channel, Endpoint, Uri};
|
||||||
|
use wfe_buildkit_protos::moby::buildkit::v1::control_client::ControlClient;
|
||||||
|
use wfe_buildkit_protos::moby::buildkit::v1::{
|
||||||
|
CacheOptions, CacheOptionsEntry, Exporter, SolveRequest, StatusRequest,
|
||||||
|
};
|
||||||
|
use wfe_core::models::ExecutionResult;
|
||||||
|
use wfe_core::traits::step::{StepBody, StepExecutionContext};
|
||||||
|
use wfe_core::WfeError;
|
||||||
|
|
||||||
|
use crate::config::BuildkitConfig;
|
||||||
|
|
||||||
|
/// Result of a BuildKit solve operation.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) struct BuildResult {
|
||||||
|
/// Image digest produced by the build, if any.
|
||||||
|
pub digest: Option<String>,
|
||||||
|
/// Full exporter response metadata from the daemon.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub metadata: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A workflow step that builds container images via the BuildKit gRPC API.
|
||||||
|
pub struct BuildkitStep {
|
||||||
|
config: BuildkitConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildkitStep {
|
||||||
|
/// Create a new BuildKit step from configuration.
|
||||||
|
pub fn new(config: BuildkitConfig) -> Self {
|
||||||
|
Self { config }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Connect to the BuildKit daemon and return a raw `ControlClient`.
|
||||||
|
///
|
||||||
|
/// Supports Unix socket (`unix://`), TCP (`tcp://`), and HTTP (`http://`)
|
||||||
|
/// endpoints.
|
||||||
|
async fn connect(&self) -> Result<ControlClient<Channel>, WfeError> {
|
||||||
|
let addr = &self.config.buildkit_addr;
|
||||||
|
tracing::info!(addr = %addr, "connecting to BuildKit daemon");
|
||||||
|
|
||||||
|
let channel = if addr.starts_with("unix://") {
|
||||||
|
let socket_path = addr
|
||||||
|
.strip_prefix("unix://")
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
// Verify the socket exists before attempting connection.
|
||||||
|
if !Path::new(&socket_path).exists() {
|
||||||
|
return Err(WfeError::StepExecution(format!(
|
||||||
|
"BuildKit socket not found: {socket_path}"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// tonic requires a dummy URI for Unix sockets; the actual path
|
||||||
|
// is provided via the connector.
|
||||||
|
Endpoint::try_from("http://[::]:50051")
|
||||||
|
.map_err(|e| {
|
||||||
|
WfeError::StepExecution(format!("failed to create endpoint: {e}"))
|
||||||
|
})?
|
||||||
|
.connect_with_connector(tower::service_fn(move |_: Uri| {
|
||||||
|
let path = socket_path.clone();
|
||||||
|
async move {
|
||||||
|
tokio::net::UnixStream::connect(path)
|
||||||
|
.await
|
||||||
|
.map(hyper_util::rt::TokioIo::new)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
WfeError::StepExecution(format!(
|
||||||
|
"failed to connect to buildkitd via Unix socket at {addr}: {e}"
|
||||||
|
))
|
||||||
|
})?
|
||||||
|
} else {
|
||||||
|
// TCP or HTTP endpoint.
|
||||||
|
let connect_addr = if addr.starts_with("tcp://") {
|
||||||
|
addr.replacen("tcp://", "http://", 1)
|
||||||
|
} else {
|
||||||
|
addr.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
Endpoint::from_shared(connect_addr.clone())
|
||||||
|
.map_err(|e| {
|
||||||
|
WfeError::StepExecution(format!(
|
||||||
|
"invalid BuildKit endpoint {connect_addr}: {e}"
|
||||||
|
))
|
||||||
|
})?
|
||||||
|
.timeout(std::time::Duration::from_secs(30))
|
||||||
|
.connect()
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
WfeError::StepExecution(format!(
|
||||||
|
"failed to connect to buildkitd at {connect_addr}: {e}"
|
||||||
|
))
|
||||||
|
})?
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(ControlClient::new(channel))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build frontend attributes from the current configuration.
|
||||||
|
///
|
||||||
|
/// These attributes tell the BuildKit dockerfile frontend how to process
|
||||||
|
/// the build: which file to use, which target stage, build arguments, etc.
|
||||||
|
fn build_frontend_attrs(&self) -> HashMap<String, String> {
|
||||||
|
let mut attrs = HashMap::new();
|
||||||
|
|
||||||
|
// Dockerfile filename (relative to context).
|
||||||
|
if self.config.dockerfile != "Dockerfile" {
|
||||||
|
attrs.insert("filename".to_string(), self.config.dockerfile.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Target stage for multi-stage builds.
|
||||||
|
if let Some(ref target) = self.config.target {
|
||||||
|
attrs.insert("target".to_string(), target.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build arguments (sorted for determinism).
|
||||||
|
let mut sorted_args: Vec<_> = self.config.build_args.iter().collect();
|
||||||
|
sorted_args.sort_by_key(|(k, _)| (*k).clone());
|
||||||
|
for (key, value) in &sorted_args {
|
||||||
|
attrs.insert(format!("build-arg:{key}"), value.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
attrs
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build exporter configuration for image output.
|
||||||
|
fn build_exporters(&self) -> Vec<Exporter> {
|
||||||
|
if self.config.tags.is_empty() {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut export_attrs = HashMap::new();
|
||||||
|
export_attrs.insert("name".to_string(), self.config.tags.join(","));
|
||||||
|
if self.config.push {
|
||||||
|
export_attrs.insert("push".to_string(), "true".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
vec![Exporter {
|
||||||
|
r#type: "image".to_string(),
|
||||||
|
attrs: export_attrs,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build cache options from the configuration.
|
||||||
|
fn build_cache_options(&self) -> Option<CacheOptions> {
|
||||||
|
if self.config.cache_from.is_empty() && self.config.cache_to.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let imports = self
|
||||||
|
.config
|
||||||
|
.cache_from
|
||||||
|
.iter()
|
||||||
|
.map(|source| {
|
||||||
|
let mut attrs = HashMap::new();
|
||||||
|
attrs.insert("ref".to_string(), source.clone());
|
||||||
|
CacheOptionsEntry {
|
||||||
|
r#type: "registry".to_string(),
|
||||||
|
attrs,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let exports = self
|
||||||
|
.config
|
||||||
|
.cache_to
|
||||||
|
.iter()
|
||||||
|
.map(|dest| {
|
||||||
|
let mut attrs = HashMap::new();
|
||||||
|
attrs.insert("ref".to_string(), dest.clone());
|
||||||
|
attrs.insert("mode".to_string(), "max".to_string());
|
||||||
|
CacheOptionsEntry {
|
||||||
|
r#type: "registry".to_string(),
|
||||||
|
attrs,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Some(CacheOptions {
|
||||||
|
export_ref_deprecated: String::new(),
|
||||||
|
import_refs_deprecated: vec![],
|
||||||
|
export_attrs_deprecated: HashMap::new(),
|
||||||
|
exports,
|
||||||
|
imports,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Execute the build against a connected BuildKit daemon.
|
||||||
|
///
|
||||||
|
/// Constructs a `SolveRequest` using the dockerfile.v0 frontend and
|
||||||
|
/// sends it via the Control gRPC service. The build context must be
|
||||||
|
/// accessible to the daemon on its local filesystem (shared mount or
|
||||||
|
/// same machine).
|
||||||
|
///
|
||||||
|
/// # Session protocol
|
||||||
|
///
|
||||||
|
/// TODO: For remote daemons where the build context is not on the same
|
||||||
|
/// filesystem, a full session protocol implementation is needed to
|
||||||
|
/// transfer files. Currently we rely on the context directory being
|
||||||
|
/// available to buildkitd (e.g., via a shared mount in Lima/colima).
|
||||||
|
async fn execute_build(
|
||||||
|
&self,
|
||||||
|
control: &mut ControlClient<Channel>,
|
||||||
|
) -> Result<BuildResult, WfeError> {
|
||||||
|
let build_ref = format!("wfe-build-{}", uuid::Uuid::new_v4());
|
||||||
|
let session_id = uuid::Uuid::new_v4().to_string();
|
||||||
|
|
||||||
|
// Resolve the absolute context path.
|
||||||
|
let abs_context = std::fs::canonicalize(&self.config.context).map_err(|e| {
|
||||||
|
WfeError::StepExecution(format!(
|
||||||
|
"failed to resolve context path {}: {e}",
|
||||||
|
self.config.context
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Build frontend attributes with local context references.
|
||||||
|
let mut frontend_attrs = self.build_frontend_attrs();
|
||||||
|
|
||||||
|
// Point the frontend at the daemon-local context directory.
|
||||||
|
// The "context" attr tells the dockerfile frontend where to find
|
||||||
|
// the build context. For local builds we use the local source type
|
||||||
|
// with a shared-key reference.
|
||||||
|
let context_name = "context";
|
||||||
|
let dockerfile_name = "dockerfile";
|
||||||
|
|
||||||
|
frontend_attrs.insert(
|
||||||
|
"context".to_string(),
|
||||||
|
format!("local://{context_name}"),
|
||||||
|
);
|
||||||
|
frontend_attrs.insert(
|
||||||
|
format!("local-sessionid:{context_name}"),
|
||||||
|
session_id.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Also provide the dockerfile source as a local reference.
|
||||||
|
frontend_attrs.insert(
|
||||||
|
"dockerfilekey".to_string(),
|
||||||
|
format!("local://{dockerfile_name}"),
|
||||||
|
);
|
||||||
|
frontend_attrs.insert(
|
||||||
|
format!("local-sessionid:{dockerfile_name}"),
|
||||||
|
session_id.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let request = SolveRequest {
|
||||||
|
r#ref: build_ref.clone(),
|
||||||
|
definition: None,
|
||||||
|
exporter_deprecated: String::new(),
|
||||||
|
exporter_attrs_deprecated: HashMap::new(),
|
||||||
|
session: session_id.clone(),
|
||||||
|
frontend: "dockerfile.v0".to_string(),
|
||||||
|
frontend_attrs,
|
||||||
|
cache: self.build_cache_options(),
|
||||||
|
entitlements: vec![],
|
||||||
|
frontend_inputs: HashMap::new(),
|
||||||
|
internal: false,
|
||||||
|
source_policy: None,
|
||||||
|
exporters: self.build_exporters(),
|
||||||
|
enable_session_exporter: false,
|
||||||
|
source_policy_session: String::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Attach session metadata headers so buildkitd knows which
|
||||||
|
// session provides the local source content.
|
||||||
|
let mut grpc_request = tonic::Request::new(request);
|
||||||
|
let metadata = grpc_request.metadata_mut();
|
||||||
|
|
||||||
|
// The x-docker-expose-session-uuid header tells buildkitd which
|
||||||
|
// session owns the local sources. The x-docker-expose-session-grpc-method
|
||||||
|
// header lists the gRPC methods the session implements.
|
||||||
|
if let Ok(key) =
|
||||||
|
"x-docker-expose-session-uuid"
|
||||||
|
.parse::<tonic::metadata::MetadataKey<tonic::metadata::Ascii>>()
|
||||||
|
&& let Ok(val) = session_id
|
||||||
|
.parse::<tonic::metadata::MetadataValue<tonic::metadata::Ascii>>()
|
||||||
|
{
|
||||||
|
metadata.insert(key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advertise the filesync method so the daemon knows it can request
|
||||||
|
// local file content from our session.
|
||||||
|
if let Ok(key) =
|
||||||
|
"x-docker-expose-session-grpc-method"
|
||||||
|
.parse::<tonic::metadata::MetadataKey<tonic::metadata::Ascii>>()
|
||||||
|
{
|
||||||
|
if let Ok(val) = "/moby.filesync.v1.FileSync/DiffCopy"
|
||||||
|
.parse::<tonic::metadata::MetadataValue<tonic::metadata::Ascii>>()
|
||||||
|
{
|
||||||
|
metadata.append(key.clone(), val);
|
||||||
|
}
|
||||||
|
if let Ok(val) = "/moby.filesync.v1.Auth/Credentials"
|
||||||
|
.parse::<tonic::metadata::MetadataValue<tonic::metadata::Ascii>>()
|
||||||
|
{
|
||||||
|
metadata.append(key, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::info!(
|
||||||
|
context = %abs_context.display(),
|
||||||
|
session_id = %session_id,
|
||||||
|
"sending solve request to BuildKit"
|
||||||
|
);
|
||||||
|
|
||||||
|
let response = control
|
||||||
|
.solve(grpc_request)
|
||||||
|
.await
|
||||||
|
.map_err(|e| WfeError::StepExecution(format!("BuildKit solve failed: {e}")))?;
|
||||||
|
let solve_response = response.into_inner();
|
||||||
|
|
||||||
|
// Monitor progress (non-blocking, best effort).
|
||||||
|
let status_request = StatusRequest {
|
||||||
|
r#ref: build_ref.clone(),
|
||||||
|
};
|
||||||
|
if let Ok(stream_resp) = control.status(status_request).await {
|
||||||
|
let mut stream = stream_resp.into_inner();
|
||||||
|
while let Some(Ok(status)) = stream.next().await {
|
||||||
|
for vertex in &status.vertexes {
|
||||||
|
if !vertex.name.is_empty() {
|
||||||
|
tracing::debug!(vertex = %vertex.name, "build progress");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract digest.
|
||||||
|
let digest = solve_response
|
||||||
|
.exporter_response
|
||||||
|
.get("containerimage.digest")
|
||||||
|
.cloned();
|
||||||
|
|
||||||
|
tracing::info!(digest = ?digest, "build completed");
|
||||||
|
|
||||||
|
Ok(BuildResult {
|
||||||
|
digest,
|
||||||
|
metadata: solve_response.exporter_response,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build environment variables for registry authentication.
|
||||||
|
///
|
||||||
|
/// This is still useful when the BuildKit daemon reads credentials from
|
||||||
|
/// environment variables rather than session-based auth.
|
||||||
|
pub fn build_registry_env(&self) -> HashMap<String, String> {
|
||||||
|
let mut env = HashMap::new();
|
||||||
|
for (host, auth) in &self.config.registry_auth {
|
||||||
|
let sanitized_host = host.replace(['.', '-'], "_").to_uppercase();
|
||||||
|
env.insert(
|
||||||
|
format!("BUILDKIT_HOST_{sanitized_host}_USERNAME"),
|
||||||
|
auth.username.clone(),
|
||||||
|
);
|
||||||
|
env.insert(
|
||||||
|
format!("BUILDKIT_HOST_{sanitized_host}_PASSWORD"),
|
||||||
|
auth.password.clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
env
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse the image digest from buildctl or BuildKit progress output.
|
||||||
|
///
|
||||||
|
/// Looks for patterns like `exporting manifest sha256:<hex>` or
|
||||||
|
/// `digest: sha256:<hex>` or the raw `containerimage.digest` value.
|
||||||
|
pub fn parse_digest(output: &str) -> Option<String> {
|
||||||
|
let re = Regex::new(r"(?:exporting manifest |digest: )sha256:([a-f0-9]{64})").unwrap();
|
||||||
|
re.captures(output)
|
||||||
|
.map(|caps| format!("sha256:{}", &caps[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build the output data JSON object from step execution results.
|
||||||
|
///
|
||||||
|
/// Assembles a `serde_json::Value::Object` containing the step's stdout,
|
||||||
|
/// stderr, digest (if found), and tags (if any).
|
||||||
|
pub fn build_output_data(
|
||||||
|
step_name: &str,
|
||||||
|
stdout: &str,
|
||||||
|
stderr: &str,
|
||||||
|
digest: Option<&str>,
|
||||||
|
tags: &[String],
|
||||||
|
) -> serde_json::Value {
|
||||||
|
let mut outputs = serde_json::Map::new();
|
||||||
|
|
||||||
|
if let Some(digest) = digest {
|
||||||
|
outputs.insert(
|
||||||
|
format!("{step_name}.digest"),
|
||||||
|
serde_json::Value::String(digest.to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tags.is_empty() {
|
||||||
|
outputs.insert(
|
||||||
|
format!("{step_name}.tags"),
|
||||||
|
serde_json::Value::Array(
|
||||||
|
tags.iter()
|
||||||
|
.map(|t| serde_json::Value::String(t.clone()))
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputs.insert(
|
||||||
|
format!("{step_name}.stdout"),
|
||||||
|
serde_json::Value::String(stdout.to_string()),
|
||||||
|
);
|
||||||
|
outputs.insert(
|
||||||
|
format!("{step_name}.stderr"),
|
||||||
|
serde_json::Value::String(stderr.to_string()),
|
||||||
|
);
|
||||||
|
|
||||||
|
serde_json::Value::Object(outputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl StepBody for BuildkitStep {
|
||||||
|
async fn run(
|
||||||
|
&mut self,
|
||||||
|
context: &StepExecutionContext<'_>,
|
||||||
|
) -> wfe_core::Result<ExecutionResult> {
|
||||||
|
let step_name = context.step.name.as_deref().unwrap_or("unknown");
|
||||||
|
|
||||||
|
// Connect to the BuildKit daemon.
|
||||||
|
let mut control = self.connect().await?;
|
||||||
|
|
||||||
|
tracing::info!(step = step_name, "submitting build to BuildKit");
|
||||||
|
|
||||||
|
// Execute the build with optional timeout.
|
||||||
|
let result = if let Some(timeout_ms) = self.config.timeout_ms {
|
||||||
|
let duration = std::time::Duration::from_millis(timeout_ms);
|
||||||
|
match tokio::time::timeout(duration, self.execute_build(&mut control)).await {
|
||||||
|
Ok(Ok(result)) => result,
|
||||||
|
Ok(Err(e)) => return Err(e),
|
||||||
|
Err(_) => {
|
||||||
|
return Err(WfeError::StepExecution(format!(
|
||||||
|
"BuildKit build timed out after {timeout_ms}ms"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.execute_build(&mut control).await?
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extract digest from BuildResult.
|
||||||
|
let digest = result.digest.clone();
|
||||||
|
|
||||||
|
tracing::info!(
|
||||||
|
step = step_name,
|
||||||
|
digest = ?digest,
|
||||||
|
"build completed"
|
||||||
|
);
|
||||||
|
|
||||||
|
let output_data = build_output_data(
|
||||||
|
step_name,
|
||||||
|
"", // gRPC builds don't produce traditional stdout
|
||||||
|
"", // gRPC builds don't produce traditional stderr
|
||||||
|
digest.as_deref(),
|
||||||
|
&self.config.tags,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(ExecutionResult {
|
||||||
|
proceed: true,
|
||||||
|
output_data: Some(output_data),
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::config::{BuildkitConfig, RegistryAuth, TlsConfig};
|
||||||
|
|
||||||
|
fn minimal_config() -> BuildkitConfig {
|
||||||
|
BuildkitConfig {
|
||||||
|
dockerfile: "Dockerfile".to_string(),
|
||||||
|
context: ".".to_string(),
|
||||||
|
target: None,
|
||||||
|
tags: vec![],
|
||||||
|
build_args: HashMap::new(),
|
||||||
|
cache_from: vec![],
|
||||||
|
cache_to: vec![],
|
||||||
|
push: false,
|
||||||
|
output_type: None,
|
||||||
|
buildkit_addr: "unix:///run/buildkit/buildkitd.sock".to_string(),
|
||||||
|
tls: TlsConfig::default(),
|
||||||
|
registry_auth: HashMap::new(),
|
||||||
|
timeout_ms: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// build_registry_env tests
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_registry_env_with_auth() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.registry_auth.insert(
|
||||||
|
"ghcr.io".to_string(),
|
||||||
|
RegistryAuth {
|
||||||
|
username: "user".to_string(),
|
||||||
|
password: "token".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let env = step.build_registry_env();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
env.get("BUILDKIT_HOST_GHCR_IO_USERNAME"),
|
||||||
|
Some(&"user".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
env.get("BUILDKIT_HOST_GHCR_IO_PASSWORD"),
|
||||||
|
Some(&"token".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_registry_env_sanitizes_host() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.registry_auth.insert(
|
||||||
|
"my-registry.example.com".to_string(),
|
||||||
|
RegistryAuth {
|
||||||
|
username: "u".to_string(),
|
||||||
|
password: "p".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let env = step.build_registry_env();
|
||||||
|
|
||||||
|
assert!(env.contains_key("BUILDKIT_HOST_MY_REGISTRY_EXAMPLE_COM_USERNAME"));
|
||||||
|
assert!(env.contains_key("BUILDKIT_HOST_MY_REGISTRY_EXAMPLE_COM_PASSWORD"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_registry_env_empty_when_no_auth() {
|
||||||
|
let step = BuildkitStep::new(minimal_config());
|
||||||
|
let env = step.build_registry_env();
|
||||||
|
assert!(env.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_registry_env_multiple_registries() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.registry_auth.insert(
|
||||||
|
"ghcr.io".to_string(),
|
||||||
|
RegistryAuth {
|
||||||
|
username: "gh_user".to_string(),
|
||||||
|
password: "gh_pass".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
config.registry_auth.insert(
|
||||||
|
"docker.io".to_string(),
|
||||||
|
RegistryAuth {
|
||||||
|
username: "dh_user".to_string(),
|
||||||
|
password: "dh_pass".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let env = step.build_registry_env();
|
||||||
|
|
||||||
|
assert_eq!(env.len(), 4);
|
||||||
|
assert_eq!(env["BUILDKIT_HOST_GHCR_IO_USERNAME"], "gh_user");
|
||||||
|
assert_eq!(env["BUILDKIT_HOST_GHCR_IO_PASSWORD"], "gh_pass");
|
||||||
|
assert_eq!(env["BUILDKIT_HOST_DOCKER_IO_USERNAME"], "dh_user");
|
||||||
|
assert_eq!(env["BUILDKIT_HOST_DOCKER_IO_PASSWORD"], "dh_pass");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// parse_digest tests
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_digest_from_output() {
|
||||||
|
let output = "some build output\nexporting manifest sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789\ndone";
|
||||||
|
let digest = parse_digest(output);
|
||||||
|
assert_eq!(
|
||||||
|
digest,
|
||||||
|
Some(
|
||||||
|
"sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
|
||||||
|
.to_string()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_digest_with_digest_prefix() {
|
||||||
|
let output = "digest: sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\n";
|
||||||
|
let digest = parse_digest(output);
|
||||||
|
assert_eq!(
|
||||||
|
digest,
|
||||||
|
Some(
|
||||||
|
"sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
|
||||||
|
.to_string()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_digest_missing_returns_none() {
|
||||||
|
let output = "building image...\nall done!";
|
||||||
|
let digest = parse_digest(output);
|
||||||
|
assert_eq!(digest, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_digest_partial_hash_returns_none() {
|
||||||
|
let output = "exporting manifest sha256:abcdef";
|
||||||
|
let digest = parse_digest(output);
|
||||||
|
assert_eq!(digest, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_digest_empty_input() {
|
||||||
|
assert_eq!(parse_digest(""), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_digest_wrong_prefix() {
|
||||||
|
let output =
|
||||||
|
"sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789";
|
||||||
|
assert_eq!(parse_digest(output), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_digest_uppercase_hex_returns_none() {
|
||||||
|
let output = "exporting manifest sha256:ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789";
|
||||||
|
assert_eq!(parse_digest(output), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_digest_multiline_with_noise() {
|
||||||
|
let output = r#"
|
||||||
|
[+] Building 12.3s (8/8) FINISHED
|
||||||
|
=> exporting to image
|
||||||
|
=> exporting manifest sha256:aabbccdd0011223344556677aabbccdd0011223344556677aabbccdd00112233
|
||||||
|
=> done
|
||||||
|
"#;
|
||||||
|
assert_eq!(
|
||||||
|
parse_digest(output),
|
||||||
|
Some("sha256:aabbccdd0011223344556677aabbccdd0011223344556677aabbccdd00112233".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_digest_first_match_wins() {
|
||||||
|
let hash1 = "a".repeat(64);
|
||||||
|
let hash2 = "b".repeat(64);
|
||||||
|
let output = format!(
|
||||||
|
"exporting manifest sha256:{hash1}\ndigest: sha256:{hash2}"
|
||||||
|
);
|
||||||
|
let digest = parse_digest(&output).unwrap();
|
||||||
|
assert_eq!(digest, format!("sha256:{hash1}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// build_output_data tests
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_output_data_with_digest_and_tags() {
|
||||||
|
let digest = "sha256:abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789";
|
||||||
|
let tags = vec!["myapp:latest".to_string(), "myapp:v1".to_string()];
|
||||||
|
let result = build_output_data("build", "out", "err", Some(digest), &tags);
|
||||||
|
|
||||||
|
let obj = result.as_object().unwrap();
|
||||||
|
assert_eq!(obj["build.digest"], digest);
|
||||||
|
assert_eq!(
|
||||||
|
obj["build.tags"],
|
||||||
|
serde_json::json!(["myapp:latest", "myapp:v1"])
|
||||||
|
);
|
||||||
|
assert_eq!(obj["build.stdout"], "out");
|
||||||
|
assert_eq!(obj["build.stderr"], "err");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_output_data_without_digest() {
|
||||||
|
let result = build_output_data("step1", "hello", "", None, &[]);
|
||||||
|
|
||||||
|
let obj = result.as_object().unwrap();
|
||||||
|
assert!(!obj.contains_key("step1.digest"));
|
||||||
|
assert!(!obj.contains_key("step1.tags"));
|
||||||
|
assert_eq!(obj["step1.stdout"], "hello");
|
||||||
|
assert_eq!(obj["step1.stderr"], "");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_output_data_with_digest_no_tags() {
|
||||||
|
let digest = "sha256:0000000000000000000000000000000000000000000000000000000000000000";
|
||||||
|
let result = build_output_data("img", "ok", "warn", Some(digest), &[]);
|
||||||
|
|
||||||
|
let obj = result.as_object().unwrap();
|
||||||
|
assert_eq!(obj["img.digest"], digest);
|
||||||
|
assert!(!obj.contains_key("img.tags"));
|
||||||
|
assert_eq!(obj["img.stdout"], "ok");
|
||||||
|
assert_eq!(obj["img.stderr"], "warn");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_output_data_no_digest_with_tags() {
|
||||||
|
let tags = vec!["app:v2".to_string()];
|
||||||
|
let result = build_output_data("s", "", "", None, &tags);
|
||||||
|
|
||||||
|
let obj = result.as_object().unwrap();
|
||||||
|
assert!(!obj.contains_key("s.digest"));
|
||||||
|
assert_eq!(obj["s.tags"], serde_json::json!(["app:v2"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn build_output_data_empty_strings() {
|
||||||
|
let result = build_output_data("x", "", "", None, &[]);
|
||||||
|
let obj = result.as_object().unwrap();
|
||||||
|
assert_eq!(obj["x.stdout"], "");
|
||||||
|
assert_eq!(obj["x.stderr"], "");
|
||||||
|
assert_eq!(obj.len(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// build_frontend_attrs tests
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn frontend_attrs_minimal() {
|
||||||
|
let step = BuildkitStep::new(minimal_config());
|
||||||
|
let attrs = step.build_frontend_attrs();
|
||||||
|
// Default Dockerfile name is not included (only non-default).
|
||||||
|
assert!(!attrs.contains_key("filename"));
|
||||||
|
assert!(!attrs.contains_key("target"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn frontend_attrs_with_target() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.target = Some("runtime".to_string());
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let attrs = step.build_frontend_attrs();
|
||||||
|
assert_eq!(attrs.get("target"), Some(&"runtime".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn frontend_attrs_with_custom_dockerfile() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.dockerfile = "docker/Dockerfile.prod".to_string();
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let attrs = step.build_frontend_attrs();
|
||||||
|
assert_eq!(
|
||||||
|
attrs.get("filename"),
|
||||||
|
Some(&"docker/Dockerfile.prod".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn frontend_attrs_with_build_args() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config
|
||||||
|
.build_args
|
||||||
|
.insert("RUST_VERSION".to_string(), "1.78".to_string());
|
||||||
|
config
|
||||||
|
.build_args
|
||||||
|
.insert("BUILD_MODE".to_string(), "release".to_string());
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let attrs = step.build_frontend_attrs();
|
||||||
|
assert_eq!(
|
||||||
|
attrs.get("build-arg:BUILD_MODE"),
|
||||||
|
Some(&"release".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
attrs.get("build-arg:RUST_VERSION"),
|
||||||
|
Some(&"1.78".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// build_exporters tests
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exporters_empty_when_no_tags() {
|
||||||
|
let step = BuildkitStep::new(minimal_config());
|
||||||
|
assert!(step.build_exporters().is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exporters_with_tags_and_push() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.tags = vec!["myapp:latest".to_string(), "myapp:v1.0".to_string()];
|
||||||
|
config.push = true;
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let exporters = step.build_exporters();
|
||||||
|
assert_eq!(exporters.len(), 1);
|
||||||
|
assert_eq!(exporters[0].r#type, "image");
|
||||||
|
assert_eq!(
|
||||||
|
exporters[0].attrs.get("name"),
|
||||||
|
Some(&"myapp:latest,myapp:v1.0".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
exporters[0].attrs.get("push"),
|
||||||
|
Some(&"true".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exporters_with_tags_no_push() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.tags = vec!["myapp:latest".to_string()];
|
||||||
|
config.push = false;
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let exporters = step.build_exporters();
|
||||||
|
assert_eq!(exporters.len(), 1);
|
||||||
|
assert!(!exporters[0].attrs.contains_key("push"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// build_cache_options tests
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cache_options_none_when_empty() {
|
||||||
|
let step = BuildkitStep::new(minimal_config());
|
||||||
|
assert!(step.build_cache_options().is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cache_options_with_imports_and_exports() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.cache_from = vec!["type=registry,ref=myapp:cache".to_string()];
|
||||||
|
config.cache_to = vec!["type=registry,ref=myapp:cache,mode=max".to_string()];
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let opts = step.build_cache_options().unwrap();
|
||||||
|
assert_eq!(opts.imports.len(), 1);
|
||||||
|
assert_eq!(opts.exports.len(), 1);
|
||||||
|
assert_eq!(opts.imports[0].r#type, "registry");
|
||||||
|
assert_eq!(opts.exports[0].r#type, "registry");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// connect helper tests
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tcp_addr_converted_to_http() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.buildkit_addr = "tcp://buildkitd:1234".to_string();
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
assert_eq!(step.config.buildkit_addr, "tcp://buildkitd:1234");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unix_addr_preserved() {
|
||||||
|
let config = minimal_config();
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
assert!(step.config.buildkit_addr.starts_with("unix://"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn connect_to_missing_unix_socket_returns_error() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.buildkit_addr = "unix:///tmp/nonexistent-wfe-test.sock".to_string();
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let err = step.connect().await.unwrap_err();
|
||||||
|
let msg = format!("{err}");
|
||||||
|
assert!(
|
||||||
|
msg.contains("socket not found"),
|
||||||
|
"expected 'socket not found' error, got: {msg}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn connect_to_invalid_tcp_returns_error() {
|
||||||
|
let mut config = minimal_config();
|
||||||
|
config.buildkit_addr = "tcp://127.0.0.1:1".to_string();
|
||||||
|
let step = BuildkitStep::new(config);
|
||||||
|
let err = step.connect().await.unwrap_err();
|
||||||
|
let msg = format!("{err}");
|
||||||
|
assert!(
|
||||||
|
msg.contains("failed to connect"),
|
||||||
|
"expected connection error, got: {msg}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// BuildkitStep construction tests
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn new_step_stores_config() {
|
||||||
|
let config = minimal_config();
|
||||||
|
let step = BuildkitStep::new(config.clone());
|
||||||
|
assert_eq!(step.config.dockerfile, "Dockerfile");
|
||||||
|
assert_eq!(step.config.context, ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
237
wfe-buildkit/tests/integration_test.rs
Normal file
237
wfe-buildkit/tests/integration_test.rs
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
//! Integration tests for wfe-buildkit using a real BuildKit daemon.
|
||||||
|
//!
|
||||||
|
//! These tests require a running BuildKit daemon. The socket path is read
|
||||||
|
//! from `WFE_BUILDKIT_ADDR`, falling back to
|
||||||
|
//! `unix:///Users/sienna/.lima/wfe-test/sock/buildkitd.sock`.
|
||||||
|
//!
|
||||||
|
//! If the daemon is not available, the tests are skipped gracefully.
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use wfe_buildkit::config::{BuildkitConfig, TlsConfig};
|
||||||
|
use wfe_buildkit::BuildkitStep;
|
||||||
|
|
||||||
|
use wfe_core::models::{ExecutionPointer, WorkflowInstance, WorkflowStep};
|
||||||
|
use wfe_core::traits::step::{StepBody, StepExecutionContext};
|
||||||
|
|
||||||
|
/// Get the BuildKit daemon address from the environment or use the default.
|
||||||
|
fn buildkit_addr() -> String {
|
||||||
|
std::env::var("WFE_BUILDKIT_ADDR").unwrap_or_else(|_| {
|
||||||
|
"unix:///Users/sienna/.lima/wfe-test/sock/buildkitd.sock".to_string()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check whether the BuildKit daemon socket is reachable.
|
||||||
|
fn buildkitd_available() -> bool {
|
||||||
|
let addr = buildkit_addr();
|
||||||
|
if let Some(path) = addr.strip_prefix("unix://") {
|
||||||
|
Path::new(path).exists()
|
||||||
|
} else {
|
||||||
|
// For TCP endpoints, optimistically assume available.
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_test_context(
|
||||||
|
step_name: &str,
|
||||||
|
) -> (
|
||||||
|
WorkflowStep,
|
||||||
|
ExecutionPointer,
|
||||||
|
WorkflowInstance,
|
||||||
|
) {
|
||||||
|
let mut step = WorkflowStep::new(0, "buildkit");
|
||||||
|
step.name = Some(step_name.to_string());
|
||||||
|
let pointer = ExecutionPointer::new(0);
|
||||||
|
let instance = WorkflowInstance::new("test-wf", 1, serde_json::json!({}));
|
||||||
|
(step, pointer, instance)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn build_simple_dockerfile_via_grpc() {
|
||||||
|
if !buildkitd_available() {
|
||||||
|
eprintln!(
|
||||||
|
"SKIP: BuildKit daemon not available at {}",
|
||||||
|
buildkit_addr()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a temp directory with a trivial Dockerfile.
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let dockerfile = tmp.path().join("Dockerfile");
|
||||||
|
std::fs::write(
|
||||||
|
&dockerfile,
|
||||||
|
"FROM alpine:latest\nRUN echo built\n",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let config = BuildkitConfig {
|
||||||
|
dockerfile: "Dockerfile".to_string(),
|
||||||
|
context: tmp.path().to_string_lossy().to_string(),
|
||||||
|
target: None,
|
||||||
|
tags: vec![],
|
||||||
|
build_args: HashMap::new(),
|
||||||
|
cache_from: vec![],
|
||||||
|
cache_to: vec![],
|
||||||
|
push: false,
|
||||||
|
output_type: None,
|
||||||
|
buildkit_addr: buildkit_addr(),
|
||||||
|
tls: TlsConfig::default(),
|
||||||
|
registry_auth: HashMap::new(),
|
||||||
|
timeout_ms: Some(120_000), // 2 minutes
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut step = BuildkitStep::new(config);
|
||||||
|
|
||||||
|
let (ws, pointer, instance) = make_test_context("integration-build");
|
||||||
|
let cancel = tokio_util::sync::CancellationToken::new();
|
||||||
|
let ctx = StepExecutionContext {
|
||||||
|
item: None,
|
||||||
|
execution_pointer: &pointer,
|
||||||
|
persistence_data: None,
|
||||||
|
step: &ws,
|
||||||
|
workflow: &instance,
|
||||||
|
cancellation_token: cancel,
|
||||||
|
host_context: None,
|
||||||
|
log_sink: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = step.run(&ctx).await.expect("build should succeed");
|
||||||
|
|
||||||
|
assert!(result.proceed);
|
||||||
|
|
||||||
|
let data = result.output_data.expect("should have output_data");
|
||||||
|
let obj = data.as_object().expect("output_data should be an object");
|
||||||
|
|
||||||
|
// Without tags/push, BuildKit does not produce a digest in the exporter
|
||||||
|
// response. The build succeeds but the digest is absent.
|
||||||
|
assert!(
|
||||||
|
obj.contains_key("integration-build.stdout"),
|
||||||
|
"expected stdout key, got: {:?}",
|
||||||
|
obj.keys().collect::<Vec<_>>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
obj.contains_key("integration-build.stderr"),
|
||||||
|
"expected stderr key, got: {:?}",
|
||||||
|
obj.keys().collect::<Vec<_>>()
|
||||||
|
);
|
||||||
|
|
||||||
|
// If a digest IS present (e.g., newer buildkitd versions), validate its format.
|
||||||
|
if let Some(digest_val) = obj.get("integration-build.digest") {
|
||||||
|
let digest = digest_val.as_str().unwrap();
|
||||||
|
assert!(
|
||||||
|
digest.starts_with("sha256:"),
|
||||||
|
"digest should start with sha256:, got: {digest}"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
digest.len(),
|
||||||
|
7 + 64,
|
||||||
|
"digest should be sha256:<64hex>, got: {digest}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn build_with_build_args() {
|
||||||
|
if !buildkitd_available() {
|
||||||
|
eprintln!(
|
||||||
|
"SKIP: BuildKit daemon not available at {}",
|
||||||
|
buildkit_addr()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let dockerfile = tmp.path().join("Dockerfile");
|
||||||
|
std::fs::write(
|
||||||
|
&dockerfile,
|
||||||
|
"FROM alpine:latest\nARG MY_VAR=default\nRUN echo \"value=$MY_VAR\"\n",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut build_args = HashMap::new();
|
||||||
|
build_args.insert("MY_VAR".to_string(), "custom_value".to_string());
|
||||||
|
|
||||||
|
let config = BuildkitConfig {
|
||||||
|
dockerfile: "Dockerfile".to_string(),
|
||||||
|
context: tmp.path().to_string_lossy().to_string(),
|
||||||
|
target: None,
|
||||||
|
tags: vec![],
|
||||||
|
build_args,
|
||||||
|
cache_from: vec![],
|
||||||
|
cache_to: vec![],
|
||||||
|
push: false,
|
||||||
|
output_type: None,
|
||||||
|
buildkit_addr: buildkit_addr(),
|
||||||
|
tls: TlsConfig::default(),
|
||||||
|
registry_auth: HashMap::new(),
|
||||||
|
timeout_ms: Some(120_000),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut step = BuildkitStep::new(config);
|
||||||
|
|
||||||
|
let (ws, pointer, instance) = make_test_context("build-args-test");
|
||||||
|
let cancel = tokio_util::sync::CancellationToken::new();
|
||||||
|
let ctx = StepExecutionContext {
|
||||||
|
item: None,
|
||||||
|
execution_pointer: &pointer,
|
||||||
|
persistence_data: None,
|
||||||
|
step: &ws,
|
||||||
|
workflow: &instance,
|
||||||
|
cancellation_token: cancel,
|
||||||
|
host_context: None,
|
||||||
|
log_sink: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = step.run(&ctx).await.expect("build with args should succeed");
|
||||||
|
assert!(result.proceed);
|
||||||
|
|
||||||
|
let data = result.output_data.expect("should have output_data");
|
||||||
|
let obj = data.as_object().unwrap();
|
||||||
|
|
||||||
|
// Build should complete and produce output data entries.
|
||||||
|
assert!(
|
||||||
|
obj.contains_key("build-args-test.stdout"),
|
||||||
|
"expected stdout key, got: {:?}",
|
||||||
|
obj.keys().collect::<Vec<_>>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn connect_to_unavailable_daemon_returns_error() {
|
||||||
|
// Use a deliberately wrong address to test error handling.
|
||||||
|
let config = BuildkitConfig {
|
||||||
|
dockerfile: "Dockerfile".to_string(),
|
||||||
|
context: ".".to_string(),
|
||||||
|
target: None,
|
||||||
|
tags: vec![],
|
||||||
|
build_args: HashMap::new(),
|
||||||
|
cache_from: vec![],
|
||||||
|
cache_to: vec![],
|
||||||
|
push: false,
|
||||||
|
output_type: None,
|
||||||
|
buildkit_addr: "unix:///tmp/nonexistent-buildkitd.sock".to_string(),
|
||||||
|
tls: TlsConfig::default(),
|
||||||
|
registry_auth: HashMap::new(),
|
||||||
|
timeout_ms: Some(5_000),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut step = BuildkitStep::new(config);
|
||||||
|
|
||||||
|
let (ws, pointer, instance) = make_test_context("error-test");
|
||||||
|
let cancel = tokio_util::sync::CancellationToken::new();
|
||||||
|
let ctx = StepExecutionContext {
|
||||||
|
item: None,
|
||||||
|
execution_pointer: &pointer,
|
||||||
|
persistence_data: None,
|
||||||
|
step: &ws,
|
||||||
|
workflow: &instance,
|
||||||
|
cancellation_token: cancel,
|
||||||
|
host_context: None,
|
||||||
|
log_sink: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let err = step.run(&ctx).await;
|
||||||
|
assert!(err.is_err(), "should fail when daemon is unavailable");
|
||||||
|
}
|
||||||
19
wfe-containerd-protos/Cargo.toml
Normal file
19
wfe-containerd-protos/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
name = "wfe-containerd-protos"
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
repository.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
|
description = "Generated gRPC stubs for the full containerd API"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tonic = "0.14"
|
||||||
|
tonic-prost = "0.14"
|
||||||
|
prost = "0.14"
|
||||||
|
prost-types = "0.14"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tonic-build = "0.14"
|
||||||
|
tonic-prost-build = "0.14"
|
||||||
|
prost-build = "0.14"
|
||||||
50
wfe-containerd-protos/build.rs
Normal file
50
wfe-containerd-protos/build.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let api_dir = PathBuf::from("proto/api");
|
||||||
|
|
||||||
|
// Collect all .proto files, excluding internal runtime shim protos
|
||||||
|
let proto_files: Vec<PathBuf> = walkdir(&api_dir)?
|
||||||
|
.into_iter()
|
||||||
|
.filter(|p| {
|
||||||
|
let s = p.to_string_lossy();
|
||||||
|
!s.contains("/runtime/task/") && !s.contains("/runtime/sandbox/")
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"cargo:warning=Compiling {} containerd proto files",
|
||||||
|
proto_files.len()
|
||||||
|
);
|
||||||
|
|
||||||
|
let _out_dir = PathBuf::from(std::env::var("OUT_DIR")?);
|
||||||
|
|
||||||
|
// Use tonic-prost-build (the tonic 0.14 way)
|
||||||
|
let mut prost_config = prost_build::Config::new();
|
||||||
|
prost_config.include_file("mod.rs");
|
||||||
|
|
||||||
|
tonic_prost_build::configure()
|
||||||
|
.build_server(false)
|
||||||
|
.compile_with_config(
|
||||||
|
prost_config,
|
||||||
|
&proto_files,
|
||||||
|
&[api_dir, PathBuf::from("proto")],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Recursively collect all .proto files under a directory.
|
||||||
|
fn walkdir(dir: &PathBuf) -> Result<Vec<PathBuf>, Box<dyn std::error::Error>> {
|
||||||
|
let mut protos = Vec::new();
|
||||||
|
for entry in std::fs::read_dir(dir)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let path = entry.path();
|
||||||
|
if path.is_dir() {
|
||||||
|
protos.extend(walkdir(&path)?);
|
||||||
|
} else if path.extension().is_some_and(|ext| ext == "proto") {
|
||||||
|
protos.push(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(protos)
|
||||||
|
}
|
||||||
46
wfe-containerd-protos/proto/api/events/container.proto
Normal file
46
wfe-containerd-protos/proto/api/events/container.proto
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message ContainerCreate {
|
||||||
|
string id = 1;
|
||||||
|
string image = 2;
|
||||||
|
message Runtime {
|
||||||
|
string name = 1;
|
||||||
|
google.protobuf.Any options = 2;
|
||||||
|
}
|
||||||
|
Runtime runtime = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ContainerUpdate {
|
||||||
|
string id = 1;
|
||||||
|
string image = 2;
|
||||||
|
map<string, string> labels = 3;
|
||||||
|
string snapshot_key = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ContainerDelete {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
33
wfe-containerd-protos/proto/api/events/content.proto
Normal file
33
wfe-containerd-protos/proto/api/events/content.proto
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message ContentCreate {
|
||||||
|
string digest = 1;
|
||||||
|
int64 size = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ContentDelete {
|
||||||
|
string digest = 1;
|
||||||
|
}
|
||||||
38
wfe-containerd-protos/proto/api/events/image.proto
Normal file
38
wfe-containerd-protos/proto/api/events/image.proto
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.images.v1;
|
||||||
|
|
||||||
|
import "types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message ImageCreate {
|
||||||
|
string name = 1;
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ImageUpdate {
|
||||||
|
string name = 1;
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ImageDelete {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
38
wfe-containerd-protos/proto/api/events/namespace.proto
Normal file
38
wfe-containerd-protos/proto/api/events/namespace.proto
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message NamespaceCreate {
|
||||||
|
string name = 1;
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NamespaceUpdate {
|
||||||
|
string name = 1;
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NamespaceDelete {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
37
wfe-containerd-protos/proto/api/events/sandbox.proto
Normal file
37
wfe-containerd-protos/proto/api/events/sandbox.proto
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
|
||||||
|
message SandboxCreate {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SandboxStart {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SandboxExit {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
uint32 exit_status = 2;
|
||||||
|
google.protobuf.Timestamp exited_at = 3;
|
||||||
|
}
|
||||||
41
wfe-containerd-protos/proto/api/events/snapshot.proto
Normal file
41
wfe-containerd-protos/proto/api/events/snapshot.proto
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "types/fieldpath.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message SnapshotPrepare {
|
||||||
|
string key = 1;
|
||||||
|
string parent = 2;
|
||||||
|
string snapshotter = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SnapshotCommit {
|
||||||
|
string key = 1;
|
||||||
|
string name = 2;
|
||||||
|
string snapshotter = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SnapshotRemove {
|
||||||
|
string key = 1;
|
||||||
|
string snapshotter = 5;
|
||||||
|
}
|
||||||
93
wfe-containerd-protos/proto/api/events/task.proto
Normal file
93
wfe-containerd-protos/proto/api/events/task.proto
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.events;
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "types/fieldpath.proto";
|
||||||
|
import "types/mount.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/events;events";
|
||||||
|
option (containerd.types.fieldpath_all) = true;
|
||||||
|
|
||||||
|
message TaskCreate {
|
||||||
|
string container_id = 1;
|
||||||
|
string bundle = 2;
|
||||||
|
repeated containerd.types.Mount rootfs = 3;
|
||||||
|
TaskIO io = 4;
|
||||||
|
string checkpoint = 5;
|
||||||
|
uint32 pid = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskStart {
|
||||||
|
string container_id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskDelete {
|
||||||
|
string container_id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
uint32 exit_status = 3;
|
||||||
|
google.protobuf.Timestamp exited_at = 4;
|
||||||
|
// id is the specific exec. By default if omitted will be `""` thus matches
|
||||||
|
// the init exec of the task matching `container_id`.
|
||||||
|
string id = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskIO {
|
||||||
|
string stdin = 1;
|
||||||
|
string stdout = 2;
|
||||||
|
string stderr = 3;
|
||||||
|
bool terminal = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskExit {
|
||||||
|
string container_id = 1;
|
||||||
|
string id = 2;
|
||||||
|
uint32 pid = 3;
|
||||||
|
uint32 exit_status = 4;
|
||||||
|
google.protobuf.Timestamp exited_at = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskOOM {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskExecAdded {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskExecStarted {
|
||||||
|
string container_id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
uint32 pid = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskPaused {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskResumed {
|
||||||
|
string container_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message TaskCheckpointed {
|
||||||
|
string container_id = 1;
|
||||||
|
string checkpoint = 2;
|
||||||
|
}
|
||||||
149
wfe-containerd-protos/proto/api/runtime/sandbox/v1/sandbox.proto
Normal file
149
wfe-containerd-protos/proto/api/runtime/sandbox/v1/sandbox.proto
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.runtime.sandbox.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "types/metrics.proto";
|
||||||
|
import "types/mount.proto";
|
||||||
|
import "types/platform.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/runtime/sandbox/v1;sandbox";
|
||||||
|
|
||||||
|
// Sandbox is an optional interface that shim may implement to support sandboxes environments.
|
||||||
|
// A typical example of sandbox is microVM or pause container - an entity that groups containers and/or
|
||||||
|
// holds resources relevant for this group.
|
||||||
|
service Sandbox {
|
||||||
|
// CreateSandbox will be called right after sandbox shim instance launched.
|
||||||
|
// It is a good place to initialize sandbox environment.
|
||||||
|
rpc CreateSandbox(CreateSandboxRequest) returns (CreateSandboxResponse);
|
||||||
|
|
||||||
|
// StartSandbox will start a previously created sandbox.
|
||||||
|
rpc StartSandbox(StartSandboxRequest) returns (StartSandboxResponse);
|
||||||
|
|
||||||
|
// Platform queries the platform the sandbox is going to run containers on.
|
||||||
|
// containerd will use this to generate a proper OCI spec.
|
||||||
|
rpc Platform(PlatformRequest) returns (PlatformResponse);
|
||||||
|
|
||||||
|
// StopSandbox will stop existing sandbox instance
|
||||||
|
rpc StopSandbox(StopSandboxRequest) returns (StopSandboxResponse);
|
||||||
|
|
||||||
|
// WaitSandbox blocks until sandbox exits.
|
||||||
|
rpc WaitSandbox(WaitSandboxRequest) returns (WaitSandboxResponse);
|
||||||
|
|
||||||
|
// SandboxStatus will return current status of the running sandbox instance
|
||||||
|
rpc SandboxStatus(SandboxStatusRequest) returns (SandboxStatusResponse);
|
||||||
|
|
||||||
|
// PingSandbox is a lightweight API call to check whether sandbox alive.
|
||||||
|
rpc PingSandbox(PingRequest) returns (PingResponse);
|
||||||
|
|
||||||
|
// ShutdownSandbox must shutdown shim instance.
|
||||||
|
rpc ShutdownSandbox(ShutdownSandboxRequest) returns (ShutdownSandboxResponse);
|
||||||
|
|
||||||
|
// SandboxMetrics retrieves metrics about a sandbox instance.
|
||||||
|
rpc SandboxMetrics(SandboxMetricsRequest) returns (SandboxMetricsResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
string bundle_path = 2;
|
||||||
|
repeated containerd.types.Mount rootfs = 3;
|
||||||
|
google.protobuf.Any options = 4;
|
||||||
|
string netns_path = 5;
|
||||||
|
map<string, string> annotations = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateSandboxResponse {}
|
||||||
|
|
||||||
|
message StartSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartSandboxResponse {
|
||||||
|
uint32 pid = 1;
|
||||||
|
google.protobuf.Timestamp created_at = 2;
|
||||||
|
google.protobuf.Any spec = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PlatformRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PlatformResponse {
|
||||||
|
containerd.types.Platform platform = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StopSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
uint32 timeout_secs = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StopSandboxResponse {}
|
||||||
|
|
||||||
|
message UpdateSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
google.protobuf.Any resources = 2;
|
||||||
|
map<string, string> annotations = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitSandboxResponse {
|
||||||
|
uint32 exit_status = 1;
|
||||||
|
google.protobuf.Timestamp exited_at = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateSandboxResponse {}
|
||||||
|
|
||||||
|
message SandboxStatusRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
bool verbose = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SandboxStatusResponse {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
uint32 pid = 2;
|
||||||
|
string state = 3;
|
||||||
|
map<string, string> info = 4;
|
||||||
|
google.protobuf.Timestamp created_at = 5;
|
||||||
|
google.protobuf.Timestamp exited_at = 6;
|
||||||
|
google.protobuf.Any extra = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PingRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PingResponse {}
|
||||||
|
|
||||||
|
message ShutdownSandboxRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShutdownSandboxResponse {}
|
||||||
|
|
||||||
|
message SandboxMetricsRequest {
|
||||||
|
string sandbox_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SandboxMetricsResponse {
|
||||||
|
containerd.types.Metric metrics = 1;
|
||||||
|
}
|
||||||
200
wfe-containerd-protos/proto/api/runtime/task/v2/shim.proto
Normal file
200
wfe-containerd-protos/proto/api/runtime/task/v2/shim.proto
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.task.v2;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "types/mount.proto";
|
||||||
|
import "types/task/task.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/runtime/task/v2;task";
|
||||||
|
|
||||||
|
// Shim service is launched for each container and is responsible for owning the IO
|
||||||
|
// for the container and its additional processes. The shim is also the parent of
|
||||||
|
// each container and allows reattaching to the IO and receiving the exit status
|
||||||
|
// for the container processes.
|
||||||
|
service Task {
|
||||||
|
rpc State(StateRequest) returns (StateResponse);
|
||||||
|
rpc Create(CreateTaskRequest) returns (CreateTaskResponse);
|
||||||
|
rpc Start(StartRequest) returns (StartResponse);
|
||||||
|
rpc Delete(DeleteRequest) returns (DeleteResponse);
|
||||||
|
rpc Pids(PidsRequest) returns (PidsResponse);
|
||||||
|
rpc Pause(PauseRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Resume(ResumeRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Checkpoint(CheckpointTaskRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Kill(KillRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Exec(ExecProcessRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc ResizePty(ResizePtyRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc CloseIO(CloseIORequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Update(UpdateTaskRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Wait(WaitRequest) returns (WaitResponse);
|
||||||
|
rpc Stats(StatsRequest) returns (StatsResponse);
|
||||||
|
rpc Connect(ConnectRequest) returns (ConnectResponse);
|
||||||
|
rpc Shutdown(ShutdownRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateTaskRequest {
|
||||||
|
string id = 1;
|
||||||
|
string bundle = 2;
|
||||||
|
repeated containerd.types.Mount rootfs = 3;
|
||||||
|
bool terminal = 4;
|
||||||
|
string stdin = 5;
|
||||||
|
string stdout = 6;
|
||||||
|
string stderr = 7;
|
||||||
|
string checkpoint = 8;
|
||||||
|
string parent_checkpoint = 9;
|
||||||
|
google.protobuf.Any options = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateTaskResponse {
|
||||||
|
uint32 pid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteResponse {
|
||||||
|
uint32 pid = 1;
|
||||||
|
uint32 exit_status = 2;
|
||||||
|
google.protobuf.Timestamp exited_at = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExecProcessRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
bool terminal = 3;
|
||||||
|
string stdin = 4;
|
||||||
|
string stdout = 5;
|
||||||
|
string stderr = 6;
|
||||||
|
google.protobuf.Any spec = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExecProcessResponse {}
|
||||||
|
|
||||||
|
message ResizePtyRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
uint32 width = 3;
|
||||||
|
uint32 height = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StateRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StateResponse {
|
||||||
|
string id = 1;
|
||||||
|
string bundle = 2;
|
||||||
|
uint32 pid = 3;
|
||||||
|
containerd.v1.types.Status status = 4;
|
||||||
|
string stdin = 5;
|
||||||
|
string stdout = 6;
|
||||||
|
string stderr = 7;
|
||||||
|
bool terminal = 8;
|
||||||
|
uint32 exit_status = 9;
|
||||||
|
google.protobuf.Timestamp exited_at = 10;
|
||||||
|
string exec_id = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message KillRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
uint32 signal = 3;
|
||||||
|
bool all = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CloseIORequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
bool stdin = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PidsRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PidsResponse {
|
||||||
|
repeated containerd.v1.types.ProcessInfo processes = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckpointTaskRequest {
|
||||||
|
string id = 1;
|
||||||
|
string path = 2;
|
||||||
|
google.protobuf.Any options = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateTaskRequest {
|
||||||
|
string id = 1;
|
||||||
|
google.protobuf.Any resources = 2;
|
||||||
|
map<string, string> annotations = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartResponse {
|
||||||
|
uint32 pid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitResponse {
|
||||||
|
uint32 exit_status = 1;
|
||||||
|
google.protobuf.Timestamp exited_at = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatsRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatsResponse {
|
||||||
|
google.protobuf.Any stats = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ConnectRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ConnectResponse {
|
||||||
|
uint32 shim_pid = 1;
|
||||||
|
uint32 task_pid = 2;
|
||||||
|
string version = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShutdownRequest {
|
||||||
|
string id = 1;
|
||||||
|
bool now = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PauseRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResumeRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
200
wfe-containerd-protos/proto/api/runtime/task/v3/shim.proto
Normal file
200
wfe-containerd-protos/proto/api/runtime/task/v3/shim.proto
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.task.v3;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "types/mount.proto";
|
||||||
|
import "types/task/task.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/runtime/task/v3;task";
|
||||||
|
|
||||||
|
// Shim service is launched for each container and is responsible for owning the IO
|
||||||
|
// for the container and its additional processes. The shim is also the parent of
|
||||||
|
// each container and allows reattaching to the IO and receiving the exit status
|
||||||
|
// for the container processes.
|
||||||
|
service Task {
|
||||||
|
rpc State(StateRequest) returns (StateResponse);
|
||||||
|
rpc Create(CreateTaskRequest) returns (CreateTaskResponse);
|
||||||
|
rpc Start(StartRequest) returns (StartResponse);
|
||||||
|
rpc Delete(DeleteRequest) returns (DeleteResponse);
|
||||||
|
rpc Pids(PidsRequest) returns (PidsResponse);
|
||||||
|
rpc Pause(PauseRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Resume(ResumeRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Checkpoint(CheckpointTaskRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Kill(KillRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Exec(ExecProcessRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc ResizePty(ResizePtyRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc CloseIO(CloseIORequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Update(UpdateTaskRequest) returns (google.protobuf.Empty);
|
||||||
|
rpc Wait(WaitRequest) returns (WaitResponse);
|
||||||
|
rpc Stats(StatsRequest) returns (StatsResponse);
|
||||||
|
rpc Connect(ConnectRequest) returns (ConnectResponse);
|
||||||
|
rpc Shutdown(ShutdownRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateTaskRequest {
|
||||||
|
string id = 1;
|
||||||
|
string bundle = 2;
|
||||||
|
repeated containerd.types.Mount rootfs = 3;
|
||||||
|
bool terminal = 4;
|
||||||
|
string stdin = 5;
|
||||||
|
string stdout = 6;
|
||||||
|
string stderr = 7;
|
||||||
|
string checkpoint = 8;
|
||||||
|
string parent_checkpoint = 9;
|
||||||
|
google.protobuf.Any options = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateTaskResponse {
|
||||||
|
uint32 pid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteResponse {
|
||||||
|
uint32 pid = 1;
|
||||||
|
uint32 exit_status = 2;
|
||||||
|
google.protobuf.Timestamp exited_at = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExecProcessRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
bool terminal = 3;
|
||||||
|
string stdin = 4;
|
||||||
|
string stdout = 5;
|
||||||
|
string stderr = 6;
|
||||||
|
google.protobuf.Any spec = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ExecProcessResponse {}
|
||||||
|
|
||||||
|
message ResizePtyRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
uint32 width = 3;
|
||||||
|
uint32 height = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StateRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StateResponse {
|
||||||
|
string id = 1;
|
||||||
|
string bundle = 2;
|
||||||
|
uint32 pid = 3;
|
||||||
|
containerd.v1.types.Status status = 4;
|
||||||
|
string stdin = 5;
|
||||||
|
string stdout = 6;
|
||||||
|
string stderr = 7;
|
||||||
|
bool terminal = 8;
|
||||||
|
uint32 exit_status = 9;
|
||||||
|
google.protobuf.Timestamp exited_at = 10;
|
||||||
|
string exec_id = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message KillRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
uint32 signal = 3;
|
||||||
|
bool all = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CloseIORequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
bool stdin = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PidsRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PidsResponse {
|
||||||
|
repeated containerd.v1.types.ProcessInfo processes = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CheckpointTaskRequest {
|
||||||
|
string id = 1;
|
||||||
|
string path = 2;
|
||||||
|
google.protobuf.Any options = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateTaskRequest {
|
||||||
|
string id = 1;
|
||||||
|
google.protobuf.Any resources = 2;
|
||||||
|
map<string, string> annotations = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StartResponse {
|
||||||
|
uint32 pid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitRequest {
|
||||||
|
string id = 1;
|
||||||
|
string exec_id = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message WaitResponse {
|
||||||
|
uint32 exit_status = 1;
|
||||||
|
google.protobuf.Timestamp exited_at = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatsRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatsResponse {
|
||||||
|
google.protobuf.Any stats = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ConnectRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ConnectResponse {
|
||||||
|
uint32 shim_pid = 1;
|
||||||
|
uint32 task_pid = 2;
|
||||||
|
string version = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShutdownRequest {
|
||||||
|
string id = 1;
|
||||||
|
bool now = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PauseRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ResumeRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.containers.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/containers/v1;containers";
|
||||||
|
|
||||||
|
// Containers provides metadata storage for containers used in the execution
|
||||||
|
// service.
|
||||||
|
//
|
||||||
|
// The objects here provide an state-independent view of containers for use in
|
||||||
|
// management and resource pinning. From that perspective, containers do not
|
||||||
|
// have a "state" but rather this is the set of resources that will be
|
||||||
|
// considered in use by the container.
|
||||||
|
//
|
||||||
|
// From the perspective of the execution service, these objects represent the
|
||||||
|
// base parameters for creating a container process.
|
||||||
|
//
|
||||||
|
// In general, when looking to add fields for this type, first ask yourself
|
||||||
|
// whether or not the function of the field has to do with runtime execution or
|
||||||
|
// is invariant of the runtime state of the container. If it has to do with
|
||||||
|
// runtime, or changes as the "container" is started and stops, it probably
|
||||||
|
// doesn't belong on this object.
|
||||||
|
service Containers {
|
||||||
|
rpc Get(GetContainerRequest) returns (GetContainerResponse);
|
||||||
|
rpc List(ListContainersRequest) returns (ListContainersResponse);
|
||||||
|
rpc ListStream(ListContainersRequest) returns (stream ListContainerMessage);
|
||||||
|
rpc Create(CreateContainerRequest) returns (CreateContainerResponse);
|
||||||
|
rpc Update(UpdateContainerRequest) returns (UpdateContainerResponse);
|
||||||
|
rpc Delete(DeleteContainerRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Container {
|
||||||
|
// ID is the user-specified identifier.
|
||||||
|
//
|
||||||
|
// This field may not be updated.
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
// Labels provides an area to include arbitrary data on containers.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
//
|
||||||
|
// Note that to add a new value to this field, read the existing set and
|
||||||
|
// include the entire result in the update call.
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
|
||||||
|
// Image contains the reference of the image used to build the
|
||||||
|
// specification and snapshots for running this container.
|
||||||
|
//
|
||||||
|
// If this field is updated, the spec and rootfs needed to updated, as well.
|
||||||
|
string image = 3;
|
||||||
|
|
||||||
|
message Runtime {
|
||||||
|
// Name is the name of the runtime.
|
||||||
|
string name = 1;
|
||||||
|
// Options specify additional runtime initialization options.
|
||||||
|
google.protobuf.Any options = 2;
|
||||||
|
}
|
||||||
|
// Runtime specifies which runtime to use for executing this container.
|
||||||
|
Runtime runtime = 4;
|
||||||
|
|
||||||
|
// Spec to be used when creating the container. This is runtime specific.
|
||||||
|
google.protobuf.Any spec = 5;
|
||||||
|
|
||||||
|
// Snapshotter specifies the snapshotter name used for rootfs
|
||||||
|
string snapshotter = 6;
|
||||||
|
|
||||||
|
// SnapshotKey specifies the snapshot key to use for the container's root
|
||||||
|
// filesystem. When starting a task from this container, a caller should
|
||||||
|
// look up the mounts from the snapshot service and include those on the
|
||||||
|
// task create request.
|
||||||
|
//
|
||||||
|
// Snapshots referenced in this field will not be garbage collected.
|
||||||
|
//
|
||||||
|
// This field is set to empty when the rootfs is not a snapshot.
|
||||||
|
//
|
||||||
|
// This field may be updated.
|
||||||
|
string snapshot_key = 7;
|
||||||
|
|
||||||
|
// CreatedAt is the time the container was first created.
|
||||||
|
google.protobuf.Timestamp created_at = 8;
|
||||||
|
|
||||||
|
// UpdatedAt is the last time the container was mutated.
|
||||||
|
google.protobuf.Timestamp updated_at = 9;
|
||||||
|
|
||||||
|
// Extensions allow clients to provide zero or more blobs that are directly
|
||||||
|
// associated with the container. One may provide protobuf, json, or other
|
||||||
|
// encoding formats. The primary use of this is to further decorate the
|
||||||
|
// container object with fields that may be specific to a client integration.
|
||||||
|
//
|
||||||
|
// The key portion of this map should identify a "name" for the extension
|
||||||
|
// that should be unique against other extensions. When updating extension
|
||||||
|
// data, one should only update the specified extension using field paths
|
||||||
|
// to select a specific map key.
|
||||||
|
map<string, google.protobuf.Any> extensions = 10;
|
||||||
|
|
||||||
|
// Sandbox ID this container belongs to.
|
||||||
|
string sandbox = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetContainerRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetContainerResponse {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContainersRequest {
|
||||||
|
// Filters contains one or more filters using the syntax defined in the
|
||||||
|
// containerd filter package.
|
||||||
|
//
|
||||||
|
// The returned result will be those that match any of the provided
|
||||||
|
// filters. Expanded, containers that match the following will be
|
||||||
|
// returned:
|
||||||
|
//
|
||||||
|
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||||
|
//
|
||||||
|
// If filters is zero-length or nil, all items will be returned.
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContainersResponse {
|
||||||
|
repeated Container containers = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateContainerRequest {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateContainerResponse {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateContainerRequest updates the metadata on one or more container.
|
||||||
|
//
|
||||||
|
// The operation should follow semantics described in
|
||||||
|
// https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/field-mask,
|
||||||
|
// unless otherwise qualified.
|
||||||
|
message UpdateContainerRequest {
|
||||||
|
// Container provides the target values, as declared by the mask, for the update.
|
||||||
|
//
|
||||||
|
// The ID field must be set.
|
||||||
|
Container container = 1;
|
||||||
|
|
||||||
|
// UpdateMask specifies which fields to perform the update on. If empty,
|
||||||
|
// the operation applies to all fields.
|
||||||
|
google.protobuf.FieldMask update_mask = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateContainerResponse {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteContainerRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContainerMessage {
|
||||||
|
Container container = 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,329 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.content.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/content/v1;content";
|
||||||
|
|
||||||
|
// Content provides access to a content addressable storage system.
|
||||||
|
service Content {
|
||||||
|
// Info returns information about a committed object.
|
||||||
|
//
|
||||||
|
// This call can be used for getting the size of content and checking for
|
||||||
|
// existence.
|
||||||
|
rpc Info(InfoRequest) returns (InfoResponse);
|
||||||
|
|
||||||
|
// Update updates content metadata.
|
||||||
|
//
|
||||||
|
// This call can be used to manage the mutable content labels. The
|
||||||
|
// immutable metadata such as digest, size, and committed at cannot
|
||||||
|
// be updated.
|
||||||
|
rpc Update(UpdateRequest) returns (UpdateResponse);
|
||||||
|
|
||||||
|
// List streams the entire set of content as Info objects and closes the
|
||||||
|
// stream.
|
||||||
|
//
|
||||||
|
// Typically, this will yield a large response, chunked into messages.
|
||||||
|
// Clients should make provisions to ensure they can handle the entire data
|
||||||
|
// set.
|
||||||
|
rpc List(ListContentRequest) returns (stream ListContentResponse);
|
||||||
|
|
||||||
|
// Delete will delete the referenced object.
|
||||||
|
rpc Delete(DeleteContentRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// Read allows one to read an object based on the offset into the content.
|
||||||
|
//
|
||||||
|
// The requested data may be returned in one or more messages.
|
||||||
|
rpc Read(ReadContentRequest) returns (stream ReadContentResponse);
|
||||||
|
|
||||||
|
// Status returns the status for a single reference.
|
||||||
|
rpc Status(StatusRequest) returns (StatusResponse);
|
||||||
|
|
||||||
|
// ListStatuses returns the status of ongoing object ingestions, started via
|
||||||
|
// Write.
|
||||||
|
//
|
||||||
|
// Only those matching the regular expression will be provided in the
|
||||||
|
// response. If the provided regular expression is empty, all ingestions
|
||||||
|
// will be provided.
|
||||||
|
rpc ListStatuses(ListStatusesRequest) returns (ListStatusesResponse);
|
||||||
|
|
||||||
|
// Write begins or resumes writes to a resource identified by a unique ref.
|
||||||
|
// Only one active stream may exist at a time for each ref.
|
||||||
|
//
|
||||||
|
// Once a write stream has started, it may only write to a single ref, thus
|
||||||
|
// once a stream is started, the ref may be omitted on subsequent writes.
|
||||||
|
//
|
||||||
|
// For any write transaction represented by a ref, only a single write may
|
||||||
|
// be made to a given offset. If overlapping writes occur, it is an error.
|
||||||
|
// Writes should be sequential and implementations may throw an error if
|
||||||
|
// this is required.
|
||||||
|
//
|
||||||
|
// If expected_digest is set and already part of the content store, the
|
||||||
|
// write will fail.
|
||||||
|
//
|
||||||
|
// When completed, the commit flag should be set to true. If expected size
|
||||||
|
// or digest is set, the content will be validated against those values.
|
||||||
|
rpc Write(stream WriteContentRequest) returns (stream WriteContentResponse);
|
||||||
|
|
||||||
|
// Abort cancels the ongoing write named in the request. Any resources
|
||||||
|
// associated with the write will be collected.
|
||||||
|
rpc Abort(AbortRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Info {
|
||||||
|
// Digest is the hash identity of the blob.
|
||||||
|
string digest = 1;
|
||||||
|
|
||||||
|
// Size is the total number of bytes in the blob.
|
||||||
|
int64 size = 2;
|
||||||
|
|
||||||
|
// CreatedAt provides the time at which the blob was committed.
|
||||||
|
google.protobuf.Timestamp created_at = 3;
|
||||||
|
|
||||||
|
// UpdatedAt provides the time the info was last updated.
|
||||||
|
google.protobuf.Timestamp updated_at = 4;
|
||||||
|
|
||||||
|
// Labels are arbitrary data on snapshots.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InfoRequest {
|
||||||
|
string digest = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message InfoResponse {
|
||||||
|
Info info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateRequest {
|
||||||
|
Info info = 1;
|
||||||
|
|
||||||
|
// UpdateMask specifies which fields to perform the update on. If empty,
|
||||||
|
// the operation applies to all fields.
|
||||||
|
//
|
||||||
|
// In info, Digest, Size, and CreatedAt are immutable,
|
||||||
|
// other field may be updated using this mask.
|
||||||
|
// If no mask is provided, all mutable field are updated.
|
||||||
|
google.protobuf.FieldMask update_mask = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateResponse {
|
||||||
|
Info info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContentRequest {
|
||||||
|
// Filters contains one or more filters using the syntax defined in the
|
||||||
|
// containerd filter package.
|
||||||
|
//
|
||||||
|
// The returned result will be those that match any of the provided
|
||||||
|
// filters. Expanded, containers that match the following will be
|
||||||
|
// returned:
|
||||||
|
//
|
||||||
|
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||||
|
//
|
||||||
|
// If filters is zero-length or nil, all items will be returned.
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListContentResponse {
|
||||||
|
repeated Info info = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteContentRequest {
|
||||||
|
// Digest specifies which content to delete.
|
||||||
|
string digest = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadContentRequest defines the fields that make up a request to read a portion of
|
||||||
|
// data from a stored object.
|
||||||
|
message ReadContentRequest {
|
||||||
|
// Digest is the hash identity to read.
|
||||||
|
string digest = 1;
|
||||||
|
|
||||||
|
// Offset specifies the number of bytes from the start at which to begin
|
||||||
|
// the read. If zero or less, the read will be from the start. This uses
|
||||||
|
// standard zero-indexed semantics.
|
||||||
|
int64 offset = 2;
|
||||||
|
|
||||||
|
// size is the total size of the read. If zero, the entire blob will be
|
||||||
|
// returned by the service.
|
||||||
|
int64 size = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadContentResponse carries byte data for a read request.
|
||||||
|
message ReadContentResponse {
|
||||||
|
int64 offset = 1; // offset of the returned data
|
||||||
|
bytes data = 2; // actual data
|
||||||
|
}
|
||||||
|
|
||||||
|
message Status {
|
||||||
|
google.protobuf.Timestamp started_at = 1;
|
||||||
|
google.protobuf.Timestamp updated_at = 2;
|
||||||
|
string ref = 3;
|
||||||
|
int64 offset = 4;
|
||||||
|
int64 total = 5;
|
||||||
|
string expected = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatusRequest {
|
||||||
|
string ref = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatusResponse {
|
||||||
|
Status status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListStatusesRequest {
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListStatusesResponse {
|
||||||
|
repeated Status statuses = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteAction defines the behavior of a WriteRequest.
|
||||||
|
enum WriteAction {
|
||||||
|
// WriteActionStat instructs the writer to return the current status while
|
||||||
|
// holding the lock on the write.
|
||||||
|
STAT = 0;
|
||||||
|
|
||||||
|
// WriteActionWrite sets the action for the write request to write data.
|
||||||
|
//
|
||||||
|
// Any data included will be written at the provided offset. The
|
||||||
|
// transaction will be left open for further writes.
|
||||||
|
//
|
||||||
|
// This is the default.
|
||||||
|
WRITE = 1;
|
||||||
|
|
||||||
|
// WriteActionCommit will write any outstanding data in the message and
|
||||||
|
// commit the write, storing it under the digest.
|
||||||
|
//
|
||||||
|
// This can be used in a single message to send the data, verify it and
|
||||||
|
// commit it.
|
||||||
|
//
|
||||||
|
// This action will always terminate the write.
|
||||||
|
COMMIT = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteContentRequest writes data to the request ref at offset.
|
||||||
|
message WriteContentRequest {
|
||||||
|
// Action sets the behavior of the write.
|
||||||
|
//
|
||||||
|
// When this is a write and the ref is not yet allocated, the ref will be
|
||||||
|
// allocated and the data will be written at offset.
|
||||||
|
//
|
||||||
|
// If the action is write and the ref is allocated, it will accept data to
|
||||||
|
// an offset that has not yet been written.
|
||||||
|
//
|
||||||
|
// If the action is write and there is no data, the current write status
|
||||||
|
// will be returned. This works differently from status because the stream
|
||||||
|
// holds a lock.
|
||||||
|
WriteAction action = 1;
|
||||||
|
|
||||||
|
// Ref identifies the pre-commit object to write to.
|
||||||
|
string ref = 2;
|
||||||
|
|
||||||
|
// Total can be set to have the service validate the total size of the
|
||||||
|
// committed content.
|
||||||
|
//
|
||||||
|
// The latest value before or with the commit action message will be use to
|
||||||
|
// validate the content. If the offset overflows total, the service may
|
||||||
|
// report an error. It is only required on one message for the write.
|
||||||
|
//
|
||||||
|
// If the value is zero or less, no validation of the final content will be
|
||||||
|
// performed.
|
||||||
|
int64 total = 3;
|
||||||
|
|
||||||
|
// Expected can be set to have the service validate the final content against
|
||||||
|
// the provided digest.
|
||||||
|
//
|
||||||
|
// If the digest is already present in the object store, an AlreadyExists
|
||||||
|
// error will be returned.
|
||||||
|
//
|
||||||
|
// Only the latest version will be used to check the content against the
|
||||||
|
// digest. It is only required to include it on a single message, before or
|
||||||
|
// with the commit action message.
|
||||||
|
string expected = 4;
|
||||||
|
|
||||||
|
// Offset specifies the number of bytes from the start at which to begin
|
||||||
|
// the write. For most implementations, this means from the start of the
|
||||||
|
// file. This uses standard, zero-indexed semantics.
|
||||||
|
//
|
||||||
|
// If the action is write, the remote may remove all previously written
|
||||||
|
// data after the offset. Implementations may support arbitrary offsets but
|
||||||
|
// MUST support reseting this value to zero with a write. If an
|
||||||
|
// implementation does not support a write at a particular offset, an
|
||||||
|
// OutOfRange error must be returned.
|
||||||
|
int64 offset = 5;
|
||||||
|
|
||||||
|
// Data is the actual bytes to be written.
|
||||||
|
//
|
||||||
|
// If this is empty and the message is not a commit, a response will be
|
||||||
|
// returned with the current write state.
|
||||||
|
bytes data = 6;
|
||||||
|
|
||||||
|
// Labels are arbitrary data on snapshots.
|
||||||
|
//
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteContentResponse is returned on the culmination of a write call.
|
||||||
|
message WriteContentResponse {
|
||||||
|
// Action contains the action for the final message of the stream. A writer
|
||||||
|
// should confirm that they match the intended result.
|
||||||
|
WriteAction action = 1;
|
||||||
|
|
||||||
|
// StartedAt provides the time at which the write began.
|
||||||
|
//
|
||||||
|
// This must be set for stat and commit write actions. All other write
|
||||||
|
// actions may omit this.
|
||||||
|
google.protobuf.Timestamp started_at = 2;
|
||||||
|
|
||||||
|
// UpdatedAt provides the last time of a successful write.
|
||||||
|
//
|
||||||
|
// This must be set for stat and commit write actions. All other write
|
||||||
|
// actions may omit this.
|
||||||
|
google.protobuf.Timestamp updated_at = 3;
|
||||||
|
|
||||||
|
// Offset is the current committed size for the write.
|
||||||
|
int64 offset = 4;
|
||||||
|
|
||||||
|
// Total provides the current, expected total size of the write.
|
||||||
|
//
|
||||||
|
// We include this to provide consistency with the Status structure on the
|
||||||
|
// client writer.
|
||||||
|
//
|
||||||
|
// This is only valid on the Stat and Commit response.
|
||||||
|
int64 total = 5;
|
||||||
|
|
||||||
|
// Digest, if present, includes the digest up to the currently committed
|
||||||
|
// bytes. If action is commit, this field will be set. It is implementation
|
||||||
|
// defined if this is set for other actions.
|
||||||
|
string digest = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AbortRequest {
|
||||||
|
string ref = 1;
|
||||||
|
}
|
||||||
90
wfe-containerd-protos/proto/api/services/diff/v1/diff.proto
Normal file
90
wfe-containerd-protos/proto/api/services/diff/v1/diff.proto
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.diff.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "types/descriptor.proto";
|
||||||
|
import "types/mount.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/diff/v1;diff";
|
||||||
|
|
||||||
|
// Diff service creates and applies diffs
|
||||||
|
service Diff {
|
||||||
|
// Apply applies the content associated with the provided digests onto
|
||||||
|
// the provided mounts. Archive content will be extracted and
|
||||||
|
// decompressed if necessary.
|
||||||
|
rpc Apply(ApplyRequest) returns (ApplyResponse);
|
||||||
|
|
||||||
|
// Diff creates a diff between the given mounts and uploads the result
|
||||||
|
// to the content store.
|
||||||
|
rpc Diff(DiffRequest) returns (DiffResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
message ApplyRequest {
|
||||||
|
// Diff is the descriptor of the diff to be extracted
|
||||||
|
containerd.types.Descriptor diff = 1;
|
||||||
|
|
||||||
|
repeated containerd.types.Mount mounts = 2;
|
||||||
|
|
||||||
|
map<string, google.protobuf.Any> payloads = 3;
|
||||||
|
// SyncFs is to synchronize the underlying filesystem containing files.
|
||||||
|
bool sync_fs = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ApplyResponse {
|
||||||
|
// Applied is the descriptor for the object which was applied.
|
||||||
|
// If the input was a compressed blob then the result will be
|
||||||
|
// the descriptor for the uncompressed blob.
|
||||||
|
containerd.types.Descriptor applied = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DiffRequest {
|
||||||
|
// Left are the mounts which represent the older copy
|
||||||
|
// in which is the base of the computed changes.
|
||||||
|
repeated containerd.types.Mount left = 1;
|
||||||
|
|
||||||
|
// Right are the mounts which represents the newer copy
|
||||||
|
// in which changes from the left were made into.
|
||||||
|
repeated containerd.types.Mount right = 2;
|
||||||
|
|
||||||
|
// MediaType is the media type descriptor for the created diff
|
||||||
|
// object
|
||||||
|
string media_type = 3;
|
||||||
|
|
||||||
|
// Ref identifies the pre-commit content store object. This
|
||||||
|
// reference can be used to get the status from the content store.
|
||||||
|
string ref = 4;
|
||||||
|
|
||||||
|
// Labels are the labels to apply to the generated content
|
||||||
|
// on content store commit.
|
||||||
|
map<string, string> labels = 5;
|
||||||
|
|
||||||
|
// SourceDateEpoch specifies the timestamp used to provide control for reproducibility.
|
||||||
|
// See also https://reproducible-builds.org/docs/source-date-epoch/ .
|
||||||
|
//
|
||||||
|
// Since containerd v2.0, the whiteout timestamps are set to zero (1970-01-01),
|
||||||
|
// not to the source date epoch.
|
||||||
|
google.protobuf.Timestamp source_date_epoch = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DiffResponse {
|
||||||
|
// Diff is the descriptor of the diff which can be applied
|
||||||
|
containerd.types.Descriptor diff = 3;
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.events.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "types/event.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/events/v1;events";
|
||||||
|
|
||||||
|
service Events {
|
||||||
|
// Publish an event to a topic.
|
||||||
|
//
|
||||||
|
// The event will be packed into a timestamp envelope with the namespace
|
||||||
|
// introspected from the context. The envelope will then be dispatched.
|
||||||
|
rpc Publish(PublishRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// Forward sends an event that has already been packaged into an envelope
|
||||||
|
// with a timestamp and namespace.
|
||||||
|
//
|
||||||
|
// This is useful if earlier timestamping is required or when forwarding on
|
||||||
|
// behalf of another component, namespace or publisher.
|
||||||
|
rpc Forward(ForwardRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// Subscribe to a stream of events, possibly returning only that match any
|
||||||
|
// of the provided filters.
|
||||||
|
//
|
||||||
|
// Unlike many other methods in containerd, subscribers will get messages
|
||||||
|
// from all namespaces unless otherwise specified. If this is not desired,
|
||||||
|
// a filter can be provided in the format 'namespace==<namespace>' to
|
||||||
|
// restrict the received events.
|
||||||
|
rpc Subscribe(SubscribeRequest) returns (stream containerd.types.Envelope);
|
||||||
|
}
|
||||||
|
|
||||||
|
message PublishRequest {
|
||||||
|
string topic = 1;
|
||||||
|
google.protobuf.Any event = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ForwardRequest {
|
||||||
|
containerd.types.Envelope envelope = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SubscribeRequest {
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
149
wfe-containerd-protos/proto/api/services/images/v1/images.proto
Normal file
149
wfe-containerd-protos/proto/api/services/images/v1/images.proto
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.services.images.v1;
|
||||||
|
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/field_mask.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "types/descriptor.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/api/services/images/v1;images";
|
||||||
|
|
||||||
|
// Images is a service that allows one to register images with containerd.
|
||||||
|
//
|
||||||
|
// In containerd, an image is merely the mapping of a name to a content root,
|
||||||
|
// described by a descriptor. The behavior and state of image is purely
|
||||||
|
// dictated by the type of the descriptor.
|
||||||
|
//
|
||||||
|
// From the perspective of this service, these references are mostly shallow,
|
||||||
|
// in that the existence of the required content won't be validated until
|
||||||
|
// required by consuming services.
|
||||||
|
//
|
||||||
|
// As such, this can really be considered a "metadata service".
|
||||||
|
service Images {
|
||||||
|
// Get returns an image by name.
|
||||||
|
rpc Get(GetImageRequest) returns (GetImageResponse);
|
||||||
|
|
||||||
|
// List returns a list of all images known to containerd.
|
||||||
|
rpc List(ListImagesRequest) returns (ListImagesResponse);
|
||||||
|
|
||||||
|
// Create an image record in the metadata store.
|
||||||
|
//
|
||||||
|
// The name of the image must be unique.
|
||||||
|
rpc Create(CreateImageRequest) returns (CreateImageResponse);
|
||||||
|
|
||||||
|
// Update assigns the name to a given target image based on the provided
|
||||||
|
// image.
|
||||||
|
rpc Update(UpdateImageRequest) returns (UpdateImageResponse);
|
||||||
|
|
||||||
|
// Delete deletes the image by name.
|
||||||
|
rpc Delete(DeleteImageRequest) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Image {
|
||||||
|
// Name provides a unique name for the image.
|
||||||
|
//
|
||||||
|
// Containerd treats this as the primary identifier.
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
// Labels provides free form labels for the image. These are runtime only
|
||||||
|
// and do not get inherited into the package image in any way.
|
||||||
|
//
|
||||||
|
// Labels may be updated using the field mask.
|
||||||
|
// The combined size of a key/value pair cannot exceed 4096 bytes.
|
||||||
|
map<string, string> labels = 2;
|
||||||
|
|
||||||
|
// Target describes the content entry point of the image.
|
||||||
|
containerd.types.Descriptor target = 3;
|
||||||
|
|
||||||
|
// CreatedAt is the time the image was first created.
|
||||||
|
google.protobuf.Timestamp created_at = 7;
|
||||||
|
|
||||||
|
// UpdatedAt is the last time the image was mutated.
|
||||||
|
google.protobuf.Timestamp updated_at = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetImageRequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetImageResponse {
|
||||||
|
Image image = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateImageRequest {
|
||||||
|
Image image = 1;
|
||||||
|
|
||||||
|
google.protobuf.Timestamp source_date_epoch = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CreateImageResponse {
|
||||||
|
Image image = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateImageRequest {
|
||||||
|
// Image provides a full or partial image for update.
|
||||||
|
//
|
||||||
|
// The name field must be set or an error will be returned.
|
||||||
|
Image image = 1;
|
||||||
|
|
||||||
|
// UpdateMask specifies which fields to perform the update on. If empty,
|
||||||
|
// the operation applies to all fields.
|
||||||
|
google.protobuf.FieldMask update_mask = 2;
|
||||||
|
|
||||||
|
google.protobuf.Timestamp source_date_epoch = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateImageResponse {
|
||||||
|
Image image = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListImagesRequest {
|
||||||
|
// Filters contains one or more filters using the syntax defined in the
|
||||||
|
// containerd filter package.
|
||||||
|
//
|
||||||
|
// The returned result will be those that match any of the provided
|
||||||
|
// filters. Expanded, images that match the following will be
|
||||||
|
// returned:
|
||||||
|
//
|
||||||
|
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
|
||||||
|
//
|
||||||
|
// If filters is zero-length or nil, all items will be returned.
|
||||||
|
repeated string filters = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListImagesResponse {
|
||||||
|
repeated Image images = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteImageRequest {
|
||||||
|
string name = 1;
|
||||||
|
|
||||||
|
// Sync indicates that the delete and cleanup should be done
|
||||||
|
// synchronously before returning to the caller
|
||||||
|
//
|
||||||
|
// Default is false
|
||||||
|
bool sync = 2;
|
||||||
|
|
||||||
|
// Target value for image to be deleted
|
||||||
|
//
|
||||||
|
// If image descriptor does not match the same digest,
|
||||||
|
// the delete operation will return "not found" error.
|
||||||
|
optional containerd.types.Descriptor target = 3;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user