// Copyright (c) Huawei Technologies Co., Ltd. 2019-2020. All rights reserved.
// iSulad-img licensed under the Mulan PSL v1.
// You can use this software according to the terms and conditions of the Mulan PSL v1.
// You may obtain a copy of Mulan PSL v1 at:
//     http://license.coscl.org.cn/MulanPSL
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
// PURPOSE.
// See the Mulan PSL v1 for more details.
// Description: iSulad image kit
// Author: liuhao
// Create: 2019-07-12

// Since some of this code is derived from Kubernetes, their copyright
// is retained here....
//
// 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.

// The original version of this proto can be found at
// https://github.com/cri-o/cri-o/blob/master/vendor/k8s.io/cri-api/pkg/apis/runtime/v1alpha2/api.proto

syntax = 'proto3';

package isula;

// 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) {}
    //  Get image information
    rpc ImageInfo(ImageInfoRequest) returns (ImageInfoResponse) {}
    // 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) {}
    // Load image from file
    rpc LoadImage(LoadImageRequest) returns (LoadImageResponose) {}

    // isulad image services
    // get all Container rootfs
    rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
    // create rootfs for container
    rpc ContainerPrepare(ContainerPrepareRequest) returns (ContainerPrepareResponse) {}
    // remove rootfs of container
    rpc ContainerRemove(ContainerRemoveRequest) returns (ContainerRemoveResponse) {}
    // mount rwlayer for container
    rpc ContainerMount(ContainerMountRequest) returns (ContainerMountResponse) {}
    // umount rwlayer of container
    rpc ContainerUmount(ContainerUmountRequest) returns (ContainerUmountResponse) {}
    // export container rootfs
    rpc ContainerExport(ContainerExportRequest) returns (ContainerExportResponse) {}

    // get filesystem usage of container
    rpc ContainerFsUsage(ContainerFsUsageRequest) returns (ContainerFsUsageResponse) {}

    // get status of graphdriver
    rpc GraphdriverStatus(GraphdriverStatusRequest) returns (GraphdriverStatusResponse) {}

    // login registry
    rpc Login(LoginRequest) returns (LoginResponse) {}
    // logout registry
    rpc Logout(LogoutRequest) returns (LogoutResponse) {}

    // health check service
    rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse) {}
}

message HealthCheckRequest {}

message HealthCheckResponse {
    string errmsg = 1;
    uint32 cc = 2;
}

message LoginRequest {
    string server = 1;
    string username = 2;
    string password = 3;
}

message LoginResponse {
    string errmsg = 1;
    uint32 cc = 2;
}

message LogoutRequest {
    string server = 1;
}

message LogoutResponse {
    string errmsg = 1;
    uint32 cc = 2;
}

message ContainerExportRequest {
    string name_id = 1;
    string output = 2;
    uint32 uid = 3;
    uint32 gid = 4;
    uint32 offset = 5;
}

message ContainerExportResponse {
    string errmsg = 1;
    uint32 cc = 2;
}

message LoadImageRequest {
    string file = 1;
    string tag = 2;
}

message LoadImageResponose {
    string outmsg = 1;
    string errmsg = 2;
    uint32 cc = 3;
}

message GraphdriverStatusRequest {}

message GraphdriverStatusResponse {
    string status = 1;
    string errmsg = 2;
    uint32 cc = 3;
}

message ContainerFsUsageRequest {
    string name_id = 1;
}

message ContainerFsUsageResponse {
    string usage = 1;
    string errmsg = 2;
    uint32 cc = 3;
}

message ContainerUmountRequest {
    string name_id = 1;
    bool force = 2;
}

message ContainerUmountResponse {
    string errmsg = 1;
    uint32 cc = 2;
}

message ContainerMountRequest {
    string name_id = 1;
}

message ContainerMountResponse {
    string errmsg = 1;
    uint32 cc = 2;
}

message ContainerRemoveRequest {
    string name_id = 1;
}

message ContainerRemoveResponse {
    string errmsg = 1;
    uint32 cc = 2;
}

message ContainerPrepareRequest {
    string image = 1;
    string id = 2;
    string name = 3;
    repeated string storage_opts = 4;
}

message ContainerPrepareResponse {
    string mount_point = 1;
    string image_conf = 2;
    string errmsg = 3;
    uint32 cc = 4;
}

message ListContainersRequest {}

message ListContainersResponse {
    map<string, bool> containers = 1;
    string errmsg = 2;
    uint32 cc = 3;
}

// 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;
}

// 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.
    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;
}

// NamespaceOption provides options for Linux namespaces.
message NamespaceOption {
    // If set, use the host's network namespace.
    bool host_network = 1;
    // If set, use the host's PID namespace.
    bool host_pid = 2;
    // If set, use the host's IPC namespace.
    bool host_ipc = 3;
}

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

// SELinuxOption are the labels to be applied to the container.
message SELinuxOption {
    string user = 1;
    string role = 2;
    string type = 3;
    string level = 4;
}
// 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;
    // 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:
    // * docker/default: the default profile for the docker 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.
    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;
}
// 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 ImageFilter {
    // Spec of the image.
    ImageSpec image = 1;
}

message ListImagesRequest {
    // Filter to list images.
    ImageFilter filter = 1;
    bool check = 2;
}

// Basic information about a container image.
message Image {
    // ID of the image.
    string id = 1;
    // Other names by which this image is known.
    repeated string repo_tags = 2;
    // Digests by which this image is known.
    repeated string repo_digests = 3;
    // Size of the image in bytes. Must be > 0.
    uint64 size = 4;
    // UID that will run the command(s). This is used as a default if no user is
    // specified when creating the container. UID and the following user name
    // are mutually exclusive.
    Int64Value uid = 5;
    // User name that will run the command(s). This is used if UID is not set
    // and no user is specified when creating container.
    string username = 6;

    // Create time of image
    string created = 7;

    // Load time of image
    string loaded = 8;

    // oci image spec
    ImageSpec spec = 9;
}

message ListImagesResponse {
    // List of images.
    repeated Image images = 1;

    string errmsg = 2;
    uint32 cc = 3;
}

message ImageStatusRequest {
    // Spec of the image.
    ImageSpec image = 1;
    // Verbose indicates whether to return extra information about the image.
    bool verbose = 2;
}

message ImageStatusResponse {
    // Status of the image.
    Image image = 1;
    // Info is extra information of the Image. The key could be abitrary string, and
    // value should be in json format. The information could include anything useful
    // for debug, e.g. image config for oci image based container runtime.
    // It should only be returned non-empty when Verbose is true.
    map<string, string> info = 2;

    string errmsg = 3;
    uint32 cc = 4;
}

message ImageInfoRequest {
    ImageSpec image = 1;
}

message ImageInfoResponse {
    string spec = 1;
    string errmsg = 2;
    uint32 cc = 3;
}

// AuthConfig contains authorization information for connecting to a registry.
message AuthConfig {
    string username = 1;
    string password = 2;
    string auth = 3;
    string server_address = 4;
    // IdentityToken is used to authenticate the user and get
    // an access token for the registry.
    string identity_token = 5;
    // RegistryToken is a bearer token to be sent to a registry
    string registry_token = 6;
}

message PullImageRequest {
    // Spec of the image.
    ImageSpec image = 1;
    // Authentication configuration for pulling the image.
    AuthConfig auth = 2;
    // Config of the PodSandbox, which is used to pull image in PodSandbox context.
    PodSandboxConfig sandbox_config = 3;
}

message PullImageResponse {
    // Reference to the image in use. For most runtimes, this should be an
    // image ID or digest.
    string image_ref = 1;
    string errmsg = 2;
    uint32 cc = 3;
}

message RemoveImageRequest {
    // Spec of the image to remove.
    ImageSpec image = 1;

    bool force = 2;
}

message RemoveImageResponse {
    string errmsg = 1;
    uint32 cc = 2;
}

message ImageFsInfoRequest {}

// UInt64Value is the wrapper of uint64.
message UInt64Value {
    // The value.
    uint64 value = 1;
}

// StorageIdentifier uniquely identify the storage..
message StorageIdentifier{
    // UUID of the device.
    string uuid = 1;
}

// FilesystemUsage provides the filesystem usage information.
message FilesystemUsage {
    // Timestamp in nanoseconds at which the information were collected. Must be > 0.
    int64 timestamp = 1;
    // The underlying storage of the filesystem.
    StorageIdentifier storage_id = 2;
    // UsedBytes represents the bytes used for images on the filesystem.
    // This may differ from the total bytes used on the filesystem and may not
    // equal CapacityBytes - AvailableBytes.
    UInt64Value used_bytes = 3;
    // InodesUsed represents the inodes used by the images.
    // This may not equal InodesCapacity - InodesAvailable because the underlying
    // filesystem may also be used for purposes other than storing images.
    UInt64Value inodes_used = 4;
}

message ImageFsInfoResponse {
    // Information of image filesystem(s).
    repeated FilesystemUsage image_filesystems = 1;

    string errmsg = 2;
    uint32 cc = 3;
}
