syntax = "proto3";

package machine;

import "common/common.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/siderolabs/talos/pkg/machinery/api/machine";
option java_package = "dev.talos.api.machine";

// The machine service definition.
service ImageService {
  // List images in the containerd.
  rpc List(ImageServiceListRequest) returns (stream ImageServiceListResponse);
  // Pull an image into the containerd.
  rpc Pull(ImageServicePullRequest) returns (stream ImageServicePullResponse);
  // Import an image from a stream (tarball).
  rpc Import(stream ImageServiceImportRequest) returns (ImageServiceImportResponse);
  // Remove an image from the containerd.
  rpc Remove(ImageServiceRemoveRequest) returns (google.protobuf.Empty);
  // Verify an image signature.
  rpc Verify(ImageServiceVerifyRequest) returns (ImageServiceVerifyResponse);
}

message ImageServiceListRequest {
  common.ContainerdInstance containerd = 1;
}

message ImageServiceListResponse {
  string name = 1;
  string digest = 2;
  int64 size = 3;
  google.protobuf.Timestamp created_at = 4;
  map<string, string> labels = 5;
}

message ImageServicePullRequest {
  common.ContainerdInstance containerd = 1;
  // Image reference to pull.
  string image_ref = 3;
}

message ImageServicePullResponse {
  oneof response {
    // Name of the pulled image (when done).
    string name = 1;
    // Progress of the image pull (intermediate updates).
    ImageServicePullProgress pull_progress = 2;
  }
}

message ImageServiceImportRequest {
  oneof request {
    // Containerd instance to use.
    common.ContainerdInstance containerd = 1;
    // Chunk of the image tarball.
    common.Data image_chunk = 2;
  }
}

message ImageServiceImportResponse {
  // Name of the imported image.
  string name = 1;
}

message ImageServicePullLayerProgress {
  enum Status {
    // Keep this in sync with ImagePullLayerProgress.Status.
    DOWNLOADING = 0;
    DOWNLOAD_COMPLETE = 1;
    EXTRACTING = 2;
    EXTRACT_COMPLETE = 3;
    ALREADY_EXISTS = 4;
  }
  Status status = 1;
  google.protobuf.Duration elapsed = 2;
  int64 offset = 3;
  int64 total = 4;
}

message ImageServicePullProgress {
  string layer_id = 1;
  ImageServicePullLayerProgress progress = 2;
}

message ImageServiceRemoveRequest {
  common.ContainerdInstance containerd = 1;
  // Image reference to remove.
  string image_ref = 2;
}

message ImageServiceVerifyRequest {
  // Image reference to verify.
  //
  // The image reference could be either in:
  //  * the digest form (e.g. "docker.io/library/nginx@sha256:abc123...") to ensure that the exact image is verified.
  //  * the tag form (e.g. "docker.io/library/nginx:latest") to verify the image currently pointed by the tag, and the resolved
  //    digested will be returned in the response.
  //
  // Any other format will cause the error.
  string image_ref = 1;
  // Authentication credentials for the registry (if needed).
  //
  // By default Talos will use configured auth, but additional
  // image pull secret can be submitted here.
  ImageServiceCredentials credentials = 2;
}

message ImageServiceCredentials {
  // Host of the registry (e.g. "docker.io").
  string host = 1;
  // Username for the registry.
  string username = 2;
  // Password (token) for the registry.
  string password = 3;
}

message ImageServiceVerifyResponse {
  // Was the image verified: if it didn't match any verify rule, false will be returned.
  // If the image matched the rule, but the verification failed, an error will be returned.
  bool verified = 1;
  // Free-form verification result message, e.g. with details about the matched rule and how the image was verified.
  string message = 2;
  // The pinned image reference with resolved digest that was verified (e.g. "docker.io/library/nginx@sha256:abc123...").
  //
  // This is only set if verified=true.
  string digested_image_ref = 3;
}
