diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..81bea48 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "wfe-containerd-protos/vendor/containerd"] + path = wfe-containerd-protos/vendor/containerd + url = https://github.com/containerd/containerd.git diff --git a/Cargo.toml b/Cargo.toml index 9c23436..e29f488 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["wfe-core", "wfe-sqlite", "wfe-postgres", "wfe-opensearch", "wfe-valkey", "wfe", "wfe-yaml", "wfe-buildkit", "wfe-containerd"] +members = ["wfe-core", "wfe-sqlite", "wfe-postgres", "wfe-opensearch", "wfe-valkey", "wfe", "wfe-yaml", "wfe-buildkit", "wfe-containerd", "wfe-containerd-protos"] resolver = "2" [workspace.package] diff --git a/wfe-containerd-protos/Cargo.toml b/wfe-containerd-protos/Cargo.toml new file mode 100644 index 0000000..c32722f --- /dev/null +++ b/wfe-containerd-protos/Cargo.toml @@ -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" diff --git a/wfe-containerd-protos/build.rs b/wfe-containerd-protos/build.rs new file mode 100644 index 0000000..a61ab46 --- /dev/null +++ b/wfe-containerd-protos/build.rs @@ -0,0 +1,50 @@ +use std::path::PathBuf; + +fn main() -> Result<(), Box> { + let api_dir = PathBuf::from("vendor/containerd/api"); + + // Collect all .proto files, excluding internal runtime shim protos + let proto_files: Vec = 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, Box> { + 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) +} diff --git a/wfe-containerd-protos/proto/google/rpc/status.proto b/wfe-containerd-protos/proto/google/rpc/status.proto new file mode 100644 index 0000000..dc14c94 --- /dev/null +++ b/wfe-containerd-protos/proto/google/rpc/status.proto @@ -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; +} diff --git a/wfe-containerd-protos/src/lib.rs b/wfe-containerd-protos/src/lib.rs new file mode 100644 index 0000000..0a43ca1 --- /dev/null +++ b/wfe-containerd-protos/src/lib.rs @@ -0,0 +1,27 @@ +//! Generated gRPC stubs for the full containerd API. +//! +//! Built from the official containerd proto files at +//! . +//! +//! The module structure mirrors the protobuf package hierarchy: +//! +//! ```rust,ignore +//! use wfe_containerd_protos::containerd::services::containers::v1::containers_client::ContainersClient; +//! use wfe_containerd_protos::containerd::services::tasks::v1::tasks_client::TasksClient; +//! use wfe_containerd_protos::containerd::services::images::v1::images_client::ImagesClient; +//! use wfe_containerd_protos::containerd::services::version::v1::version_client::VersionClient; +//! use wfe_containerd_protos::containerd::types::Mount; +//! use wfe_containerd_protos::containerd::types::Descriptor; +//! ``` + +#![allow(clippy::all)] +#![allow(warnings)] + +// tonic-build generates a mod.rs that defines the full module tree +// matching the protobuf package structure. +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; diff --git a/wfe-containerd-protos/vendor/containerd b/wfe-containerd-protos/vendor/containerd new file mode 160000 index 0000000..546ce38 --- /dev/null +++ b/wfe-containerd-protos/vendor/containerd @@ -0,0 +1 @@ +Subproject commit 546ce38287edc9fb351747f8fd0866f9f1f22b03