<commit_before>/*
Copyright 2018 The Kubernetes 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.
*/

// To regenerate api.pb.go run hack/update-generated-runtime.sh
syntax = 'proto3';

package runtime.v1alpha2;
option go_package = "v1alpha2";

import "github.com/gogo/protobuf/gogoproto/gogo.proto";

option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) =  true;
option (gogoproto.goproto_getters_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
option (gogoproto.goproto_unrecognized_all) = false;

// Runtime service defines the public APIs for remote container runtimes
service RuntimeService {
    // Version returns the runtime name, runtime version, and runtime API version.
    rpc Version(VersionRequest) returns (VersionResponse) {}

    // RunPodSandbox creates and starts a pod-level sandbox. Runtimes must ensure
    // the sandbox is in the ready state on success.
    rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
    // StopPodSandbox stops any running process that is part of the sandbox and
    // reclaims network resources (e.g., IP addresses) allocated to the sandbox.
    // If there are any running containers in the sandbox, they must be forcibly
    // terminated.
    // This call is idempotent, and must not return an error if all relevant
    // resources have already been reclaimed. kubelet will call StopPodSandbox
    // at least once before calling RemovePodSandbox. It will also attempt to
    // reclaim resources eagerly, as soon as a sandbox is not needed. Hence,
    // multiple StopPodSandbox calls are expected.
    rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}
    // RemovePodSandbox removes the sandbox. If there are any running containers
    // in the sandbox, they must be forcibly terminated and removed.
    // This call is idempotent, and must not return an error if the sandbox has
    // already been removed.
    rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}
    // PodSandboxStatus returns the status of the PodSandbox. If the PodSandbox is not
    // present, returns an error.
    rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {}
    // ListPodSandbox returns a list of PodSandboxes.
    rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}

    // CreateContainer creates a new container in specified PodSandbox
    rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
    // StartContainer starts the container.
    rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}
    // StopContainer stops a running container with a grace period (i.e., timeout).
    // This call is idempotent, and must not return an error if the container has
    // already been stopped.
    // TODO: what must the runtime do after the grace period is reached?
    rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}
    // RemoveContainer removes the container. If the container is running, the
    // container must be forcibly removed.
    // This call is idempotent, and must not return an error if the container has
    // already been removed.
    rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {}
    // ListContainers lists all containers by filters.
    rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
    // ContainerStatus returns status of the container. If the container is not
    // present, returns an error.
    rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}
    // UpdateContainerResources updates ContainerConfig of the container.
    rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}
    // ReopenContainerLog asks runtime to reopen the stdout/stderr log file
    // for the container. This is often called after the log file has been
    // rotated. If the container is not running, container runtime can choose
    // to either create a new log file and return nil, or return an error.
    // Once it returns error, new container log file MUST NOT be created.
    rpc ReopenContainerLog(ReopenContainerLogRequest) returns (ReopenContainerLogResponse) {}

    // ExecSync runs a command in a container synchronously.
    rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}
    // Exec prepares a streaming endpoint to execute a command in the container.
    rpc Exec(ExecRequest) returns (ExecResponse) {}
    // Attach prepares a streaming endpoint to attach to a running container.
    rpc Attach(AttachRequest) returns (AttachResponse) {}
    // PortForward prepares a streaming endpoint to forward ports from a PodSandbox.
    rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}

    // ContainerStats returns stats of the container. If the container does not
    // exist, the call returns an error.
    rpc ContainerStats(ContainerStatsRequest) returns (ContainerStatsResponse) {}
    // ListContainerStats returns stats of all running containers.
    rpc ListContainerStats(ListContainerStatsRequest) returns (ListContainerStatsResponse) {}

    // UpdateRuntimeConfig updates the runtime configuration based on the given request.
    rpc UpdateRuntimeConfig(UpdateRuntimeConfigRequest) returns (UpdateRuntimeConfigResponse) {}

    // Status returns the status of the runtime.
    rpc Status(StatusRequest) returns (StatusResponse) {}
}

// ImageService defines the public APIs for managing images.
service ImageService {
    // ListImages lists existing images.
    rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {}
    // ImageStatus returns the status of the image. If the image is not
    // present, returns a response with ImageStatusResponse.Image set to
    // nil.
    rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {}
    // PullImage pulls an image with authentication config.
    rpc PullImage(PullImageRequest) returns (PullImageResponse) {}
    // RemoveImage removes the image.
    // This call is idempotent, and must not return an error if the image has
    // already been removed.
    rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {}
    // ImageFSInfo returns information of the filesystem that is used to store images.
    rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {}
}

message VersionRequest {
    // Version of the kubelet runtime API.
    string version = 1;
}

message VersionResponse {
    // Version of the kubelet runtime API.
    string version = 1;
    // Name of the container runtime.
    string runtime_name = 2;
    // Version of the container runtime. The string must be
    // semver-compatible.
    string runtime_version = 3;
    // API version of the container runtime. The string must be
    // semver-compatible.
    string runtime_api_version = 4;
}

// DNSConfig specifies the DNS servers and search domains of a sandbox.
message DNSConfig {
    // List of DNS servers of the cluster.
    repeated string servers = 1;
    // List of DNS search domains of the cluster.
    repeated string searches = 2;
    // List of DNS options. See https://linux.die.net/man/5/resolv.conf
    // for all available options.
    repeated string options = 3;
}

enum Protocol {
    TCP = 0;
    UDP = 1;
    SCTP = 2;
}

// PortMapping specifies the port mapping configurations of a sandbox.
message PortMapping {
    // Protocol of the port mapping.
    Protocol protocol = 1;
    // Port number within the container. Default: 0 (not specified).
    int32 container_port = 2;
    // Port number on the host. Default: 0 (not specified).
    int32 host_port = 3;
    // Host IP.
    string host_ip = 4;
}

enum MountPropagation {
    // No mount propagation ("private" in Linux terminology).
    PROPAGATION_PRIVATE = 0;
    // Mounts get propagated from the host to the container ("rslave" in Linux).
    PROPAGATION_HOST_TO_CONTAINER = 1;
    // Mounts get propagated from the host to the container and from the
    // container to the host ("rshared" in Linux).
    PROPAGATION_BIDIRECTIONAL = 2;
}

// Mount specifies a host volume to mount into a container.
message Mount {
    // Path of the mount within the container.
    string container_path = 1;
    // Path of the mount on the host. If the hostPath doesn't exist, then runtimes
    // should report error. If the hostpath is a symbolic link, runtimes should
    // follow the symlink and mount the real destination to container.
    string host_path = 2;
    // If set, the mount is read-only.
    bool readonly = 3;
    // If set, the mount needs SELinux relabeling.
    bool selinux_relabel = 4;
    // Requested propagation mode.
    MountPropagation propagation = 5;
}

// A NamespaceMode describes the intended namespace configuration for each
// of the namespaces (Network, PID, IPC) in NamespaceOption. Runtimes should
// map these modes as appropriate for the technology underlying the runtime.
enum NamespaceMode {
    // A POD namespace is common to all containers in a pod.
    // For example, a container with a PID namespace of POD expects to view
    // all of the processes in all of the containers in the pod.
    POD       = 0;
    // A CONTAINER namespace is restricted to a single container.
    // For example, a container with a PID namespace of CONTAINER expects to
    // view only the processes in that container.
    CONTAINER = 1;
    // A NODE namespace is the namespace of the Kubernetes node.
    // For example, a container with a PID namespace of NODE expects to view
    // all of the processes on the host running the kubelet.
    NODE      = 2;
}

// NamespaceOption provides options for Linux namespaces.
message NamespaceOption {
    // Network namespace for this container/sandbox.
    // Note: There is currently no way to set CONTAINER scoped network in the Kubernetes API.
    // Namespaces currently set by the kubelet: POD, NODE
    NamespaceMode network = 1;
    // PID namespace for this container/sandbox.
    // Note: The CRI default is POD, but the v1.PodSpec default is CONTAINER.
    // The kubelet's runtime manager will set this to CONTAINER explicitly for v1 pods.
    // Namespaces currently set by the kubelet: POD, CONTAINER, NODE
    NamespaceMode pid = 2;
    // IPC namespace for this container/sandbox.
    // Note: There is currently no way to set CONTAINER scoped IPC in the Kubernetes API.
    // Namespaces currently set by the kubelet: POD, NODE
    NamespaceMode ipc = 3;
}

// Int64Value is the wrapper of int64.
message Int64Value {
    // The value.
    int64 value = 1;
}

// LinuxSandboxSecurityContext holds linux security configuration that will be
// applied to a sandbox. Note that:
// 1) It does not apply to containers in the pods.
// 2) It may not be applicable to a PodSandbox which does not contain any running
//    process.
message LinuxSandboxSecurityContext {
    // Configurations for the sandbox's namespaces.
    // This will be used only if the PodSandbox uses namespace for isolation.
    NamespaceOption namespace_options = 1;
    // Optional SELinux context to be applied.
    SELinuxOption selinux_options = 2;
    // UID to run sandbox processes as, when applicable.
    Int64Value run_as_user = 3;
    // GID to run sandbox processes as, when applicable. run_as_group should only
    // be specified when run_as_user is specified; otherwise, the runtime MUST error.
    Int64Value run_as_group = 8;
    // If set, the root filesystem of the sandbox is read-only.
    bool readonly_rootfs = 4;
    // List of groups applied to the first process run in the sandbox, in
    // addition to the sandbox's primary GID.
    repeated int64 supplemental_groups = 5;
    // Indicates whether the sandbox will be asked to run a privileged
    // container. If a privileged container is to be executed within it, this
    // MUST be true.
    // This allows a sandbox to take additional security precautions if no
    // privileged containers are expected to be run.
    bool privileged = 6;
    // Seccomp profile for the sandbox, candidate values are:
    // * runtime/default: the default profile for the container runtime
    // * unconfined: unconfined profile, ie, no seccomp sandboxing
    // * localhost/<full-path-to-profile>: the profile installed on the node.
    //   <full-path-to-profile> is the full path of the profile.
    // Default: "", which is identical with unconfined.
    string seccomp_profile_path = 7;
}

// LinuxPodSandboxConfig holds platform-specific configurations for Linux
// host platforms and Linux-based containers.
message LinuxPodSandboxConfig {
    // Parent cgroup of the PodSandbox.
    // The cgroupfs style syntax will be used, but the container runtime can
    // convert it to systemd semantics if needed.
    string cgroup_parent = 1;
    // LinuxSandboxSecurityContext holds sandbox security attributes.
    LinuxSandboxSecurityContext security_context = 2;
    // Sysctls holds linux sysctls config for the sandbox.
    map<string, string> sysctls = 3;
}

// PodSandboxMetadata holds all necessary information for building the sandbox name.
// The container runtime is encouraged to expose the metadata associated with the
// PodSandbox in its user interface for better user experience. For example,
// the runtime can construct a unique PodSandboxName based on the metadata.
message PodSandboxMetadata {
    // Pod name of the sandbox. Same as the pod name in the PodSpec.
    string name = 1;
    // Pod UID of the sandbox. Same as the pod UID in the PodSpec.
    string uid = 2;
    // Pod namespace of the sandbox. Same as the pod namespace in the PodSpec.
    string namespace = 3;
    // Attempt number of creating the sandbox. Default: 0.
    uint32 attempt = 4;
}

// PodSandboxConfig holds all the required and optional fields for creating a
// sandbox.
message PodSandboxConfig {
    // Metadata of the sandbox. This information will uniquely identify the
    // sandbox, and the runtime should leverage this to ensure correct
    // operation. The runtime may also use this information to improve UX, such
    // as by constructing a readable name.
    PodSandboxMetadata metadata = 1;
    // Hostname of the sandbox. Hostname could only be empty when the pod
    // network namespace is NODE.
    string hostname = 2;
    // Path to the directory on the host in which container log files are
    // stored.
    // By default the log of a container going into the LogDirectory will be
    // hooked up to STDOUT and STDERR. However, the LogDirectory may contain
    // binary log files with structured logging data from the individual
    // containers. For example, the files might be newline separated JSON
    // structured logs, systemd-journald journal files, gRPC trace files, etc.
    // E.g.,
    //     PodSandboxConfig.LogDirectory = `/var/log/pods/<podUID>/`
    //     ContainerConfig.LogPath = `containerName/Instance#.log`
    //
    // WARNING: Log management and how kubelet should interface with the
    // container logs are under active discussion in
    // https://issues.k8s.io/24677. There *may* be future change of direction
    // for logging as the discussion carries on.
    string log_directory = 3;
    // DNS config for the sandbox.
    DNSConfig dns_config = 4;
    // Port mappings for the sandbox.
    repeated PortMapping port_mappings = 5;
    // Key-value pairs that may be used to scope and select individual resources.
    map<string, string> labels = 6;
    // Unstructured key-value map that may be set by the kubelet to store and
    // retrieve arbitrary metadata. This will include any annotations set on a
    // pod through the Kubernetes API.
    //
    // Annotations MUST NOT be altered by the runtime; the annotations stored
    // here MUST be returned in the PodSandboxStatus associated with the pod
    // this PodSandboxConfig creates.
    //
    // In general, in order to preserve a well-defined interface between the
    // kubelet and the container runtime, annotations SHOULD NOT influence
    // runtime behaviour.
    //
    // Annotations can also be useful for runtime authors to experiment with
    // new features that are opaque to the Kubernetes APIs (both user-facing
    // and the CRI). Whenever possible, however, runtime authors SHOULD
    // consider proposing new typed fields for any new features instead.
    map<string, string> annotations = 7;
    // Optional configurations specific to Linux hosts.
    LinuxPodSandboxConfig linux = 8;
}

message RunPodSandboxRequest {
    // Configuration for creating a PodSandbox.
    PodSandboxConfig config = 1;
    // Named runtime configuration to use for this PodSandbox.
    // If the runtime handler is unknown, this request should be rejected.  An
    // empty string should select the default handler, equivalent to the
    // behavior before this feature was added.
    // See https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md
    string runtime_handler = 2;
}

message RunPodSandboxResponse {
    // ID of the PodSandbox to run.
    string pod_sandbox_id = 1;
}

message StopPodSandboxRequest {
    // ID of the PodSandbox to stop.
    string pod_sandbox_id = 1;
}

message StopPodSandboxResponse {}

message RemovePodSandboxRequest {
    // ID of the PodSandbox to remove.
    string pod_sandbox_id = 1;
}

message RemovePodSandboxResponse {}

message PodSandboxStatusRequest {
    // ID of the PodSandbox for which to retrieve status.
    string pod_sandbox_id = 1;
    // Verbose indicates whether to return extra information about the pod sandbox.
    bool verbose = 2;
}

// PodSandboxNetworkStatus is the status of the network for a PodSandbox.
message PodSandboxNetworkStatus {
    // IP address of the PodSandbox.
    string ip = 1;
}

// Namespace contains paths to the namespaces.
message Namespace {
    // Namespace options for Linux namespaces.
    NamespaceOption options = 2;
}

// LinuxSandboxStatus contains status specific to Linux sandboxes.
message LinuxPodSandboxStatus {
    // Paths to the sandbox's namespaces.
    Namespace namespaces = 1;
}

enum PodSandboxState {
    SANDBOX_READY    = 0;
    SANDBOX_NOTREADY = 1;
}

// PodSandboxStatus contains the status of the PodSandbox.
message PodSandboxStatus {
    // ID of the sandbox.
    string id = 1;
    // Metadata of the sandbox.
    PodSandboxMetadata metadata = 2;
    // State of the sandbox.
    PodSandboxState state = 3;
    // Creation timestamp of the sandbox in nanoseconds. Must be > 0.
    int64 created_at = 4;
    // Network contains network status if network is handled by the runtime.
    PodSandboxNetworkStatus network = 5;
    // Linux-specific status to a pod sandbox.
    LinuxPodSandboxStatus linux = 6;
    // Labels are key-value pairs that may be used to scope and select individual resources.
    map<string, string> labels = 7;
    // Unstructured key-value map holding arbitrary metadata.
    // Annotations MUST NOT be altered by the runtime; the value of this field
    // MUST be identical to that of the corresponding PodSandboxConfig used to
    // instantiate the pod sandbox this status represents.
    map<string, string> annotations = 8;
    // runtime configuration used for this PodSandbox.
    string runtime_handler = 9;
}

message PodSandboxStatusResponse {
    // Status of the PodSandbox.
    PodSandboxStatus status = 1;
    // Info is extra information of the PodSandbox. The key could be arbitrary string, and
    // value should be in json format. The information could include anything useful for
    // debug, e.g. network namespace for linux container based container runtime.
    // It should only be returned non-empty when Verbose is true.
    map<string, string> info = 2;
}

// PodSandboxStateValue is the wrapper of PodSandboxState.
message PodSandboxStateValue {
    // State of the sandbox.
    PodSandboxState state = 1;
}

// PodSandboxFilter is used to filter a list of PodSandboxes.
// All those fields are combined with 'AND'
message PodSandboxFilter {
    // ID of the sandbox.
    string id = 1;
    // State of the sandbox.
    PodSandboxStateValue state = 2;
    // LabelSelector to select matches.
    // Only api.MatchLabels is supported for now and the requirements
    // are ANDed. MatchExpressions is not supported yet.
    map<string, string> label_selector = 3;
}

message ListPodSandboxRequest {
    // PodSandboxFilter to filter a list of PodSandboxes.
    PodSandboxFilter filter = 1;
}


// PodSandbox contains minimal information about a sandbox.
message PodSandbox {
    // ID of the PodSandbox.
    string id = 1;
    // Metadata of the PodSandbox.
    PodSandboxMetadata metadata = 2;
    // State of the PodSandbox.
    PodSandboxState state = 3;
    // Creation timestamps of the PodSandbox in nanoseconds. Must be > 0.
    int64 created_at = 4;
    // Labels of the PodSandbox.
    map<string, string> labels = 5;
    // Unstructured key-value map holding arbitrary metadata.
    // Annotations MUST NOT be altered by the runtime; the value of this field
    // MUST be identical to that of the corresponding PodSandboxConfig used to
    // instantiate this PodSandbox.
    map<string, string> annotations = 6;
    // runtime configuration used for this PodSandbox.
    string runtime_handler = 7;
}

message ListPodSandboxResponse {
    // List of PodSandboxes.
    repeated PodSandbox items = 1;
}

// ImageSpec is an internal representation of an image.  Currently, it wraps the
// value of a Container's Image field (e.g. imageID or imageDigest), but in the
// future it will include more detailed information about the different image types.
message ImageSpec {
    string image = 1;
}

message KeyValue {
    string key = 1;
    string value = 2;
}

// LinuxContainerResources specifies Linux specific configuration for
// resources.
// TODO: Consider using Resources from opencontainers/runtime-spec/specs-go
// directly.
message LinuxContainerResources {
    // CPU CFS (Completely Fair Scheduler) period. Default: 0 (not specified).
    int64 cpu_period = 1;
    // CPU CFS (Completely Fair Scheduler) quota. Default: 0 (not specified).
    int64 cpu_quota = 2;
    // CPU shares (relative weight vs. other containers). Default: 0 (not specified).
    int64 cpu_shares = 3;
    // Memory limit in bytes. Default: 0 (not specified).
    int64 memory_limit_in_bytes = 4;
    // OOMScoreAdj adjusts the oom-killer score. Default: 0 (not specified).
    int64 oom_score_adj = 5;
    // CpusetCpus constrains the allowed set of logical CPUs. Default: "" (not specified).
    string cpuset_cpus = 6;
    // CpusetMems constrains the allowed set of memory nodes. Default: "" (not specified).
    string cpuset_mems = 7;
}

// SELinuxOption are the labels to be applied to the container.
message SELinuxOption {
    string user = 1;
    string role = 2;
    string type = 3;
    string level = 4;
}

// Capability contains the container capabilities to add or drop
message Capability {
    // List of capabilities to add.
    repeated string add_capabilities = 1;
    // List of capabilities to drop.
    repeated string drop_capabilities = 2;
}

// LinuxContainerSecurityContext holds linux security configuration that will be applied to a container.
message LinuxContainerSecurityContext {
    // Capabilities to add or drop.
    Capability capabilities = 1;
    // If set, run container in privileged mode.
    // Privileged mode is incompatible with the following options. If
    // privileged is set, the following features MAY have no effect:
    // 1. capabilities
    // 2. selinux_options
    // 4. seccomp
    // 5. apparmor
    //
    // Privileged mode implies the following specific options are applied:
    // 1. All capabilities are added.
    // 2. Sensitive paths, such as kernel module paths within sysfs, are not masked.
    // 3. Any sysfs and procfs mounts are mounted RW.
    // 4. Apparmor confinement is not applied.
    // 5. Seccomp restrictions are not applied.
    // 6. The device cgroup does not restrict access to any devices.
    // 7. All devices from the host's /dev are available within the container.
    // 8. SELinux restrictions are not applied (e.g. label=disabled).
    bool privileged = 2;
    // Configurations for the container's namespaces.
    // Only used if the container uses namespace for isolation.
    NamespaceOption namespace_options = 3;
    // SELinux context to be optionally applied.
    SELinuxOption selinux_options = 4;
    // UID to run the container process as. Only one of run_as_user and
    // run_as_username can be specified at a time.
    Int64Value run_as_user = 5;
    // GID to run the container process as. run_as_group should only be specified
    // when run_as_user or run_as_username is specified; otherwise, the runtime
    // MUST error.
    Int64Value run_as_group = 12;
    // User name to run the container process as. If specified, the user MUST
    // exist in the container image (i.e. in the /etc/passwd inside the image),
    // and be resolved there by the runtime; otherwise, the runtime MUST error.
    string run_as_username = 6;
    // If set, the root filesystem of the container is read-only.
    bool readonly_rootfs = 7;
    // List of groups applied to the first process run in the container, in
    // addition to the container's primary GID.
    repeated int64 supplemental_groups = 8;
    // AppArmor profile for the container, candidate values are:
    // * runtime/default: equivalent to not specifying a profile.
    // * unconfined: no profiles are loaded
    // * localhost/<profile_name>: profile loaded on the node
    //    (localhost) by name. The possible profile names are detailed at
    //    http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference
    string apparmor_profile = 9;
    // Seccomp profile for the container, candidate values are:
    // * runtime/default: the default profile for the container runtime
    // * unconfined: unconfined profile, ie, no seccomp sandboxing
    // * localhost/<full-path-to-profile>: the profile installed on the node.
    //   <full-path-to-profile> is the full path of the profile.
    // Default: "", which is identical with unconfined.
    string seccomp_profile_path = 10;
    // no_new_privs defines if the flag for no_new_privs should be set on the
    // container.
    bool no_new_privs = 11;
    // masked_paths is a slice of paths that should be masked by the container
    // runtime, this can be passed directly to the OCI spec.
    repeated string masked_paths = 13;
    // readonly_paths is a slice of paths that should be set as readonly by the
    // container runtime, this can be passed directly to the OCI spec.
    repeated string readonly_paths = 14;
}

// LinuxContainerConfig contains platform-specific configuration for
// Linux-based containers.
message LinuxContainerConfig {
    // Resources specification for the container.
    LinuxContainerResources resources = 1;
    // LinuxContainerSecurityContext configuration for the container.
    LinuxContainerSecurityContext security_context = 2;
}

// WindowsContainerSecurityContext holds windows security configuration that will be applied to a container.
message WindowsContainerSecurityContext {
    // User name to run the container process as. If specified, the user MUST
    // exist in the container image and be resolved there by the runtime;
    // otherwise, the runtime MUST return error.
    string run_as_username = 1;
}

// WindowsContainerConfig contains platform-specific configuration for
// Windows-based containers.
message WindowsContainerConfig {
    // Resources specification for the container.<commit_msg>GRPC changes for GMSA support<commit_after>/*
Copyright 2018 The Kubernetes 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.
*/

// To regenerate api.pb.go run hack/update-generated-runtime.sh
syntax = 'proto3';

package runtime.v1alpha2;
option go_package = "v1alpha2";

import "github.com/gogo/protobuf/gogoproto/gogo.proto";

option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) =  true;
option (gogoproto.goproto_getters_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
option (gogoproto.goproto_unrecognized_all) = false;

// Runtime service defines the public APIs for remote container runtimes
service RuntimeService {
    // Version returns the runtime name, runtime version, and runtime API version.
    rpc Version(VersionRequest) returns (VersionResponse) {}

    // RunPodSandbox creates and starts a pod-level sandbox. Runtimes must ensure
    // the sandbox is in the ready state on success.
    rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
    // StopPodSandbox stops any running process that is part of the sandbox and
    // reclaims network resources (e.g., IP addresses) allocated to the sandbox.
    // If there are any running containers in the sandbox, they must be forcibly
    // terminated.
    // This call is idempotent, and must not return an error if all relevant
    // resources have already been reclaimed. kubelet will call StopPodSandbox
    // at least once before calling RemovePodSandbox. It will also attempt to
    // reclaim resources eagerly, as soon as a sandbox is not needed. Hence,
    // multiple StopPodSandbox calls are expected.
    rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}
    // RemovePodSandbox removes the sandbox. If there are any running containers
    // in the sandbox, they must be forcibly terminated and removed.
    // This call is idempotent, and must not return an error if the sandbox has
    // already been removed.
    rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}
    // PodSandboxStatus returns the status of the PodSandbox. If the PodSandbox is not
    // present, returns an error.
    rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {}
    // ListPodSandbox returns a list of PodSandboxes.
    rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}

    // CreateContainer creates a new container in specified PodSandbox
    rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
    // StartContainer starts the container.
    rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}
    // StopContainer stops a running container with a grace period (i.e., timeout).
    // This call is idempotent, and must not return an error if the container has
    // already been stopped.
    // TODO: what must the runtime do after the grace period is reached?
    rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}
    // RemoveContainer removes the container. If the container is running, the
    // container must be forcibly removed.
    // This call is idempotent, and must not return an error if the container has
    // already been removed.
    rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {}
    // ListContainers lists all containers by filters.
    rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
    // ContainerStatus returns status of the container. If the container is not
    // present, returns an error.
    rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}
    // UpdateContainerResources updates ContainerConfig of the container.
    rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}
    // ReopenContainerLog asks runtime to reopen the stdout/stderr log file
    // for the container. This is often called after the log file has been
    // rotated. If the container is not running, container runtime can choose
    // to either create a new log file and return nil, or return an error.
    // Once it returns error, new container log file MUST NOT be created.
    rpc ReopenContainerLog(ReopenContainerLogRequest) returns (ReopenContainerLogResponse) {}

    // ExecSync runs a command in a container synchronously.
    rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}
    // Exec prepares a streaming endpoint to execute a command in the container.
    rpc Exec(ExecRequest) returns (ExecResponse) {}
    // Attach prepares a streaming endpoint to attach to a running container.
    rpc Attach(AttachRequest) returns (AttachResponse) {}
    // PortForward prepares a streaming endpoint to forward ports from a PodSandbox.
    rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}

    // ContainerStats returns stats of the container. If the container does not
    // exist, the call returns an error.
    rpc ContainerStats(ContainerStatsRequest) returns (ContainerStatsResponse) {}
    // ListContainerStats returns stats of all running containers.
    rpc ListContainerStats(ListContainerStatsRequest) returns (ListContainerStatsResponse) {}

    // UpdateRuntimeConfig updates the runtime configuration based on the given request.
    rpc UpdateRuntimeConfig(UpdateRuntimeConfigRequest) returns (UpdateRuntimeConfigResponse) {}

    // Status returns the status of the runtime.
    rpc Status(StatusRequest) returns (StatusResponse) {}
}

// ImageService defines the public APIs for managing images.
service ImageService {
    // ListImages lists existing images.
    rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {}
    // ImageStatus returns the status of the image. If the image is not
    // present, returns a response with ImageStatusResponse.Image set to
    // nil.
    rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {}
    // PullImage pulls an image with authentication config.
    rpc PullImage(PullImageRequest) returns (PullImageResponse) {}
    // RemoveImage removes the image.
    // This call is idempotent, and must not return an error if the image has
    // already been removed.
    rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {}
    // ImageFSInfo returns information of the filesystem that is used to store images.
    rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {}
}

message VersionRequest {
    // Version of the kubelet runtime API.
    string version = 1;
}

message VersionResponse {
    // Version of the kubelet runtime API.
    string version = 1;
    // Name of the container runtime.
    string runtime_name = 2;
    // Version of the container runtime. The string must be
    // semver-compatible.
    string runtime_version = 3;
    // API version of the container runtime. The string must be
    // semver-compatible.
    string runtime_api_version = 4;
}

// DNSConfig specifies the DNS servers and search domains of a sandbox.
message DNSConfig {
    // List of DNS servers of the cluster.
    repeated string servers = 1;
    // List of DNS search domains of the cluster.
    repeated string searches = 2;
    // List of DNS options. See https://linux.die.net/man/5/resolv.conf
    // for all available options.
    repeated string options = 3;
}

enum Protocol {
    TCP = 0;
    UDP = 1;
    SCTP = 2;
}

// PortMapping specifies the port mapping configurations of a sandbox.
message PortMapping {
    // Protocol of the port mapping.
    Protocol protocol = 1;
    // Port number within the container. Default: 0 (not specified).
    int32 container_port = 2;
    // Port number on the host. Default: 0 (not specified).
    int32 host_port = 3;
    // Host IP.
    string host_ip = 4;
}

enum MountPropagation {
    // No mount propagation ("private" in Linux terminology).
    PROPAGATION_PRIVATE = 0;
    // Mounts get propagated from the host to the container ("rslave" in Linux).
    PROPAGATION_HOST_TO_CONTAINER = 1;
    // Mounts get propagated from the host to the container and from the
    // container to the host ("rshared" in Linux).
    PROPAGATION_BIDIRECTIONAL = 2;
}

// Mount specifies a host volume to mount into a container.
message Mount {
    // Path of the mount within the container.
    string container_path = 1;
    // Path of the mount on the host. If the hostPath doesn't exist, then runtimes
    // should report error. If the hostpath is a symbolic link, runtimes should
    // follow the symlink and mount the real destination to container.
    string host_path = 2;
    // If set, the mount is read-only.
    bool readonly = 3;
    // If set, the mount needs SELinux relabeling.
    bool selinux_relabel = 4;
    // Requested propagation mode.
    MountPropagation propagation = 5;
}

// A NamespaceMode describes the intended namespace configuration for each
// of the namespaces (Network, PID, IPC) in NamespaceOption. Runtimes should
// map these modes as appropriate for the technology underlying the runtime.
enum NamespaceMode {
    // A POD namespace is common to all containers in a pod.
    // For example, a container with a PID namespace of POD expects to view
    // all of the processes in all of the containers in the pod.
    POD       = 0;
    // A CONTAINER namespace is restricted to a single container.
    // For example, a container with a PID namespace of CONTAINER expects to
    // view only the processes in that container.
    CONTAINER = 1;
    // A NODE namespace is the namespace of the Kubernetes node.
    // For example, a container with a PID namespace of NODE expects to view
    // all of the processes on the host running the kubelet.
    NODE      = 2;
}

// NamespaceOption provides options for Linux namespaces.
message NamespaceOption {
    // Network namespace for this container/sandbox.
    // Note: There is currently no way to set CONTAINER scoped network in the Kubernetes API.
    // Namespaces currently set by the kubelet: POD, NODE
    NamespaceMode network = 1;
    // PID namespace for this container/sandbox.
    // Note: The CRI default is POD, but the v1.PodSpec default is CONTAINER.
    // The kubelet's runtime manager will set this to CONTAINER explicitly for v1 pods.
    // Namespaces currently set by the kubelet: POD, CONTAINER, NODE
    NamespaceMode pid = 2;
    // IPC namespace for this container/sandbox.
    // Note: There is currently no way to set CONTAINER scoped IPC in the Kubernetes API.
    // Namespaces currently set by the kubelet: POD, NODE
    NamespaceMode ipc = 3;
}

// Int64Value is the wrapper of int64.
message Int64Value {
    // The value.
    int64 value = 1;
}

// LinuxSandboxSecurityContext holds linux security configuration that will be
// applied to a sandbox. Note that:
// 1) It does not apply to containers in the pods.
// 2) It may not be applicable to a PodSandbox which does not contain any running
//    process.
message LinuxSandboxSecurityContext {
    // Configurations for the sandbox's namespaces.
    // This will be used only if the PodSandbox uses namespace for isolation.
    NamespaceOption namespace_options = 1;
    // Optional SELinux context to be applied.
    SELinuxOption selinux_options = 2;
    // UID to run sandbox processes as, when applicable.
    Int64Value run_as_user = 3;
    // GID to run sandbox processes as, when applicable. run_as_group should only
    // be specified when run_as_user is specified; otherwise, the runtime MUST error.
    Int64Value run_as_group = 8;
    // If set, the root filesystem of the sandbox is read-only.
    bool readonly_rootfs = 4;
    // List of groups applied to the first process run in the sandbox, in
    // addition to the sandbox's primary GID.
    repeated int64 supplemental_groups = 5;
    // Indicates whether the sandbox will be asked to run a privileged
    // container. If a privileged container is to be executed within it, this
    // MUST be true.
    // This allows a sandbox to take additional security precautions if no
    // privileged containers are expected to be run.
    bool privileged = 6;
    // Seccomp profile for the sandbox, candidate values are:
    // * runtime/default: the default profile for the container runtime
    // * unconfined: unconfined profile, ie, no seccomp sandboxing
    // * localhost/<full-path-to-profile>: the profile installed on the node.
    //   <full-path-to-profile> is the full path of the profile.
    // Default: "", which is identical with unconfined.
    string seccomp_profile_path = 7;
}

// LinuxPodSandboxConfig holds platform-specific configurations for Linux
// host platforms and Linux-based containers.
message LinuxPodSandboxConfig {
    // Parent cgroup of the PodSandbox.
    // The cgroupfs style syntax will be used, but the container runtime can
    // convert it to systemd semantics if needed.
    string cgroup_parent = 1;
    // LinuxSandboxSecurityContext holds sandbox security attributes.
    LinuxSandboxSecurityContext security_context = 2;
    // Sysctls holds linux sysctls config for the sandbox.
    map<string, string> sysctls = 3;
}

// PodSandboxMetadata holds all necessary information for building the sandbox name.
// The container runtime is encouraged to expose the metadata associated with the
// PodSandbox in its user interface for better user experience. For example,
// the runtime can construct a unique PodSandboxName based on the metadata.
message PodSandboxMetadata {
    // Pod name of the sandbox. Same as the pod name in the PodSpec.
    string name = 1;
    // Pod UID of the sandbox. Same as the pod UID in the PodSpec.
    string uid = 2;
    // Pod namespace of the sandbox. Same as the pod namespace in the PodSpec.
    string namespace = 3;
    // Attempt number of creating the sandbox. Default: 0.
    uint32 attempt = 4;
}

// PodSandboxConfig holds all the required and optional fields for creating a
// sandbox.
message PodSandboxConfig {
    // Metadata of the sandbox. This information will uniquely identify the
    // sandbox, and the runtime should leverage this to ensure correct
    // operation. The runtime may also use this information to improve UX, such
    // as by constructing a readable name.
    PodSandboxMetadata metadata = 1;
    // Hostname of the sandbox. Hostname could only be empty when the pod
    // network namespace is NODE.
    string hostname = 2;
    // Path to the directory on the host in which container log files are
    // stored.
    // By default the log of a container going into the LogDirectory will be
    // hooked up to STDOUT and STDERR. However, the LogDirectory may contain
    // binary log files with structured logging data from the individual
    // containers. For example, the files might be newline separated JSON
    // structured logs, systemd-journald journal files, gRPC trace files, etc.
    // E.g.,
    //     PodSandboxConfig.LogDirectory = `/var/log/pods/<podUID>/`
    //     ContainerConfig.LogPath = `containerName/Instance#.log`
    //
    // WARNING: Log management and how kubelet should interface with the
    // container logs are under active discussion in
    // https://issues.k8s.io/24677. There *may* be future change of direction
    // for logging as the discussion carries on.
    string log_directory = 3;
    // DNS config for the sandbox.
    DNSConfig dns_config = 4;
    // Port mappings for the sandbox.
    repeated PortMapping port_mappings = 5;
    // Key-value pairs that may be used to scope and select individual resources.
    map<string, string> labels = 6;
    // Unstructured key-value map that may be set by the kubelet to store and
    // retrieve arbitrary metadata. This will include any annotations set on a
    // pod through the Kubernetes API.
    //
    // Annotations MUST NOT be altered by the runtime; the annotations stored
    // here MUST be returned in the PodSandboxStatus associated with the pod
    // this PodSandboxConfig creates.
    //
    // In general, in order to preserve a well-defined interface between the
    // kubelet and the container runtime, annotations SHOULD NOT influence
    // runtime behaviour.
    //
    // Annotations can also be useful for runtime authors to experiment with
    // new features that are opaque to the Kubernetes APIs (both user-facing
    // and the CRI). Whenever possible, however, runtime authors SHOULD
    // consider proposing new typed fields for any new features instead.
    map<string, string> annotations = 7;
    // Optional configurations specific to Linux hosts.
    LinuxPodSandboxConfig linux = 8;
}

message RunPodSandboxRequest {
    // Configuration for creating a PodSandbox.
    PodSandboxConfig config = 1;
    // Named runtime configuration to use for this PodSandbox.
    // If the runtime handler is unknown, this request should be rejected.  An
    // empty string should select the default handler, equivalent to the
    // behavior before this feature was added.
    // See https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md
    string runtime_handler = 2;
}

message RunPodSandboxResponse {
    // ID of the PodSandbox to run.
    string pod_sandbox_id = 1;
}

message StopPodSandboxRequest {
    // ID of the PodSandbox to stop.
    string pod_sandbox_id = 1;
}

message StopPodSandboxResponse {}

message RemovePodSandboxRequest {
    // ID of the PodSandbox to remove.
    string pod_sandbox_id = 1;
}

message RemovePodSandboxResponse {}

message PodSandboxStatusRequest {
    // ID of the PodSandbox for which to retrieve status.
    string pod_sandbox_id = 1;
    // Verbose indicates whether to return extra information about the pod sandbox.
    bool verbose = 2;
}

// PodSandboxNetworkStatus is the status of the network for a PodSandbox.
message PodSandboxNetworkStatus {
    // IP address of the PodSandbox.
    string ip = 1;
}

// Namespace contains paths to the namespaces.
message Namespace {
    // Namespace options for Linux namespaces.
    NamespaceOption options = 2;
}

// LinuxSandboxStatus contains status specific to Linux sandboxes.
message LinuxPodSandboxStatus {
    // Paths to the sandbox's namespaces.
    Namespace namespaces = 1;
}

enum PodSandboxState {
    SANDBOX_READY    = 0;
    SANDBOX_NOTREADY = 1;
}

// PodSandboxStatus contains the status of the PodSandbox.
message PodSandboxStatus {
    // ID of the sandbox.
    string id = 1;
    // Metadata of the sandbox.
    PodSandboxMetadata metadata = 2;
    // State of the sandbox.
    PodSandboxState state = 3;
    // Creation timestamp of the sandbox in nanoseconds. Must be > 0.
    int64 created_at = 4;
    // Network contains network status if network is handled by the runtime.
    PodSandboxNetworkStatus network = 5;
    // Linux-specific status to a pod sandbox.
    LinuxPodSandboxStatus linux = 6;
    // Labels are key-value pairs that may be used to scope and select individual resources.
    map<string, string> labels = 7;
    // Unstructured key-value map holding arbitrary metadata.
    // Annotations MUST NOT be altered by the runtime; the value of this field
    // MUST be identical to that of the corresponding PodSandboxConfig used to
    // instantiate the pod sandbox this status represents.
    map<string, string> annotations = 8;
    // runtime configuration used for this PodSandbox.
    string runtime_handler = 9;
}

message PodSandboxStatusResponse {
    // Status of the PodSandbox.
    PodSandboxStatus status = 1;
    // Info is extra information of the PodSandbox. The key could be arbitrary string, and
    // value should be in json format. The information could include anything useful for
    // debug, e.g. network namespace for linux container based container runtime.
    // It should only be returned non-empty when Verbose is true.
    map<string, string> info = 2;
}

// PodSandboxStateValue is the wrapper of PodSandboxState.
message PodSandboxStateValue {
    // State of the sandbox.
    PodSandboxState state = 1;
}

// PodSandboxFilter is used to filter a list of PodSandboxes.
// All those fields are combined with 'AND'
message PodSandboxFilter {
    // ID of the sandbox.
    string id = 1;
    // State of the sandbox.
    PodSandboxStateValue state = 2;
    // LabelSelector to select matches.
    // Only api.MatchLabels is supported for now and the requirements
    // are ANDed. MatchExpressions is not supported yet.
    map<string, string> label_selector = 3;
}

message ListPodSandboxRequest {
    // PodSandboxFilter to filter a list of PodSandboxes.
    PodSandboxFilter filter = 1;
}


// PodSandbox contains minimal information about a sandbox.
message PodSandbox {
    // ID of the PodSandbox.
    string id = 1;
    // Metadata of the PodSandbox.
    PodSandboxMetadata metadata = 2;
    // State of the PodSandbox.
    PodSandboxState state = 3;
    // Creation timestamps of the PodSandbox in nanoseconds. Must be > 0.
    int64 created_at = 4;
    // Labels of the PodSandbox.
    map<string, string> labels = 5;
    // Unstructured key-value map holding arbitrary metadata.
    // Annotations MUST NOT be altered by the runtime; the value of this field
    // MUST be identical to that of the corresponding PodSandboxConfig used to
    // instantiate this PodSandbox.
    map<string, string> annotations = 6;
    // runtime configuration used for this PodSandbox.
    string runtime_handler = 7;
}

message ListPodSandboxResponse {
    // List of PodSandboxes.
    repeated PodSandbox items = 1;
}

// ImageSpec is an internal representation of an image.  Currently, it wraps the
// value of a Container's Image field (e.g. imageID or imageDigest), but in the
// future it will include more detailed information about the different image types.
message ImageSpec {
    string image = 1;
}

message KeyValue {
    string key = 1;
    string value = 2;
}

// LinuxContainerResources specifies Linux specific configuration for
// resources.
// TODO: Consider using Resources from opencontainers/runtime-spec/specs-go
// directly.
message LinuxContainerResources {
    // CPU CFS (Completely Fair Scheduler) period. Default: 0 (not specified).
    int64 cpu_period = 1;
    // CPU CFS (Completely Fair Scheduler) quota. Default: 0 (not specified).
    int64 cpu_quota = 2;
    // CPU shares (relative weight vs. other containers). Default: 0 (not specified).
    int64 cpu_shares = 3;
    // Memory limit in bytes. Default: 0 (not specified).
    int64 memory_limit_in_bytes = 4;
    // OOMScoreAdj adjusts the oom-killer score. Default: 0 (not specified).
    int64 oom_score_adj = 5;
    // CpusetCpus constrains the allowed set of logical CPUs. Default: "" (not specified).
    string cpuset_cpus = 6;
    // CpusetMems constrains the allowed set of memory nodes. Default: "" (not specified).
    string cpuset_mems = 7;
}

// SELinuxOption are the labels to be applied to the container.
message SELinuxOption {
    string user = 1;
    string role = 2;
    string type = 3;
    string level = 4;
}

// Capability contains the container capabilities to add or drop
message Capability {
    // List of capabilities to add.
    repeated string add_capabilities = 1;
    // List of capabilities to drop.
    repeated string drop_capabilities = 2;
}

// LinuxContainerSecurityContext holds linux security configuration that will be applied to a container.
message LinuxContainerSecurityContext {
    // Capabilities to add or drop.
    Capability capabilities = 1;
    // If set, run container in privileged mode.
    // Privileged mode is incompatible with the following options. If
    // privileged is set, the following features MAY have no effect:
    // 1. capabilities
    // 2. selinux_options
    // 4. seccomp
    // 5. apparmor
    //
    // Privileged mode implies the following specific options are applied:
    // 1. All capabilities are added.
    // 2. Sensitive paths, such as kernel module paths within sysfs, are not masked.
    // 3. Any sysfs and procfs mounts are mounted RW.
    // 4. Apparmor confinement is not applied.
    // 5. Seccomp restrictions are not applied.
    // 6. The device cgroup does not restrict access to any devices.
    // 7. All devices from the host's /dev are available within the container.
    // 8. SELinux restrictions are not applied (e.g. label=disabled).
    bool privileged = 2;
    // Configurations for the container's namespaces.
    // Only used if the container uses namespace for isolation.
    NamespaceOption namespace_options = 3;
    // SELinux context to be optionally applied.
    SELinuxOption selinux_options = 4;
    // UID to run the container process as. Only one of run_as_user and
    // run_as_username can be specified at a time.
    Int64Value run_as_user = 5;
    // GID to run the container process as. run_as_group should only be specified
    // when run_as_user or run_as_username is specified; otherwise, the runtime
    // MUST error.
    Int64Value run_as_group = 12;
    // User name to run the container process as. If specified, the user MUST
    // exist in the container image (i.e. in the /etc/passwd inside the image),
    // and be resolved there by the runtime; otherwise, the runtime MUST error.
    string run_as_username = 6;
    // If set, the root filesystem of the container is read-only.
    bool readonly_rootfs = 7;
    // List of groups applied to the first process run in the container, in
    // addition to the container's primary GID.
    repeated int64 supplemental_groups = 8;
    // AppArmor profile for the container, candidate values are:
    // * runtime/default: equivalent to not specifying a profile.
    // * unconfined: no profiles are loaded
    // * localhost/<profile_name>: profile loaded on the node
    //    (localhost) by name. The possible profile names are detailed at
    //    http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference
    string apparmor_profile = 9;
    // Seccomp profile for the container, candidate values are:
    // * runtime/default: the default profile for the container runtime
    // * unconfined: unconfined profile, ie, no seccomp sandboxing
    // * localhost/<full-path-to-profile>: the profile installed on the node.
    //   <full-path-to-profile> is the full path of the profile.
    // Default: "", which is identical with unconfined.
    string seccomp_profile_path = 10;
    // no_new_privs defines if the flag for no_new_privs should be set on the
    // container.
    bool no_new_privs = 11;
    // masked_paths is a slice of paths that should be masked by the container
    // runtime, this can be passed directly to the OCI spec.
    repeated string masked_paths = 13;
    // readonly_paths is a slice of paths that should be set as readonly by the
    // container runtime, this can be passed directly to the OCI spec.
    repeated string readonly_paths = 14;
}

// LinuxContainerConfig contains platform-specific configuration for
// Linux-based containers.
message LinuxContainerConfig {
    // Resources specification for the container.
    LinuxContainerResources resources = 1;
    // LinuxContainerSecurityContext configuration for the container.
    LinuxContainerSecurityContext security_context = 2;
}

// WindowsContainerSecurityContext holds windows security configuration that will be applied to a container.
message WindowsContainerSecurityContext {
    // User name to run the container process as. If specified, the user MUST
    // exist in the container image and be resolved there by the runtime;
    // otherwise, the runtime MUST return error.
    string run_as_username = 1;

    // The contents of the GMSA credential spec to use to run this container.
    string credential_spec = 2;
}

// WindowsContainerConfig contains platform-specific configuration for
// Windows-based containers.
message WindowsContainerConfig {
    // Resources specification for the container.
{'fraction_non_alphanumeric': 0.06684026250505833, 'fraction_numerical': 0.007547900135475131, 'mean_word_length': 3.1327710317748854, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 37, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5268323', 'n_tokens_mistral': 15815, 'n_tokens_neox': 14756, 'n_words': 6709}