
syntax = "proto3";
option go_package = "github.com/coder/coder/provisionerd/proto";

package provisionerd;

import "provisionersdk/proto/provisioner.proto";

// Empty indicates a successful request/response.
message Empty {}

// AcquiredJob is returned when a provisioner daemon has a job locked.
message AcquiredJob {
    message WorkspaceBuild {
        string workspace_build_id = 1;
        string workspace_name = 2;
        repeated provisioner.ParameterValue parameter_values = 3;
        provisioner.Provision.Metadata metadata = 4;
        bytes state = 5;
    }
    message TemplateImport {
        provisioner.Provision.Metadata metadata = 1;
    }
    message TemplateDryRun {
        repeated provisioner.ParameterValue parameter_values = 1;
        provisioner.Provision.Metadata metadata = 2;
    }

    string job_id = 1;
    int64 created_at = 2;
    string provisioner = 3;
    string user_name = 4;
    bytes template_source_archive = 5;
    oneof type {
        WorkspaceBuild workspace_build = 6;
        TemplateImport template_import = 7;
        TemplateDryRun template_dry_run = 8;
    }
}

message FailedJob {
    message WorkspaceBuild {
        bytes state = 1;
    }
    message TemplateImport {}
    message TemplateDryRun {}

    string job_id = 1;
    string error = 2;
    oneof type {
        WorkspaceBuild workspace_build = 3;
        TemplateImport template_import = 4;
        TemplateDryRun template_dry_run = 5;
    }
}

// CompletedJob is sent when the provisioner daemon completes a job.
message CompletedJob {
    message WorkspaceBuild {
        bytes state = 1;
        repeated provisioner.Resource resources = 2;
    }
    message TemplateImport {
        repeated provisioner.Resource start_resources = 1;
        repeated provisioner.Resource stop_resources = 2;
    }
    message TemplateDryRun {
        repeated provisioner.Resource resources = 1;
    }

    string job_id = 1;
    oneof type {
        WorkspaceBuild workspace_build = 2;
        TemplateImport template_import = 3;
        TemplateDryRun template_dry_run = 4;
    }
}

// LogSource represents the sender of the log.
enum LogSource {
    PROVISIONER_DAEMON = 0;
    PROVISIONER = 1;
}

// Log represents output from a job.
message Log {
    LogSource source = 1;
    provisioner.LogLevel level = 2;
    int64 created_at = 3;
    string stage = 4;
    string output = 5;
}

// This message should be sent periodically as a heartbeat.
message UpdateJobRequest {
    string job_id = 1;
    repeated Log logs = 2;
    repeated provisioner.ParameterSchema parameter_schemas = 3;
    bytes readme = 4;
}

message UpdateJobResponse {
    bool canceled = 1;
    // If parameter schemas are sent, the job will respond
    // with resolved parameter values.
    repeated provisioner.ParameterValue parameter_values = 2;
}

service ProvisionerDaemon {
    // AcquireJob requests a job. Implementations should
    // hold a lock on the job until CompleteJob() is
    // called with the matching ID.
    rpc AcquireJob(Empty) returns (AcquiredJob);

    // UpdateJob streams periodic updates for a job.
    // Implementations should buffer logs so this stream
    // is non-blocking.
    rpc UpdateJob(UpdateJobRequest) returns (UpdateJobResponse);

    // FailJob indicates a job has failed.
    rpc FailJob(FailedJob) returns (Empty);

    // CompleteJob indicates a job has been completed.
    rpc CompleteJob(CompletedJob) returns (Empty);
}
