mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat(coderd): add endpoint to list provisioner jobs (#16029)
Closes #15190 Updates #15084
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -343,6 +344,47 @@ func (c *Client) OrganizationProvisionerDaemons(ctx context.Context, organizatio
|
||||
return daemons, json.NewDecoder(res.Body).Decode(&daemons)
|
||||
}
|
||||
|
||||
type OrganizationProvisionerJobsOptions struct {
|
||||
Limit int
|
||||
Status []ProvisionerJobStatus
|
||||
}
|
||||
|
||||
func (c *Client) OrganizationProvisionerJobs(ctx context.Context, organizationID uuid.UUID, opts *OrganizationProvisionerJobsOptions) ([]ProvisionerJob, error) {
|
||||
qp := url.Values{}
|
||||
if opts != nil {
|
||||
if opts.Limit > 0 {
|
||||
qp.Add("limit", strconv.Itoa(opts.Limit))
|
||||
}
|
||||
if len(opts.Status) > 0 {
|
||||
qp.Add("status", joinSlice(opts.Status))
|
||||
}
|
||||
}
|
||||
|
||||
res, err := c.Request(ctx, http.MethodGet,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/provisionerjobs?%s", organizationID.String(), qp.Encode()),
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("make request: %w", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, ReadBodyAsError(res)
|
||||
}
|
||||
|
||||
var jobs []ProvisionerJob
|
||||
return jobs, json.NewDecoder(res.Body).Decode(&jobs)
|
||||
}
|
||||
|
||||
func joinSlice[T ~string](s []T) string {
|
||||
var ss []string
|
||||
for _, v := range s {
|
||||
ss = append(ss, string(v))
|
||||
}
|
||||
return strings.Join(ss, ",")
|
||||
}
|
||||
|
||||
// CreateTemplateVersion processes source-code and optionally associates the version with a template.
|
||||
// Executing without a template is useful for validating source-code.
|
||||
func (c *Client) CreateTemplateVersion(ctx context.Context, organizationID uuid.UUID, req CreateTemplateVersionRequest) (TemplateVersion, error) {
|
||||
|
||||
@@ -112,6 +112,34 @@ const (
|
||||
ProvisionerJobUnknown ProvisionerJobStatus = "unknown"
|
||||
)
|
||||
|
||||
func ProvisionerJobStatusEnums() []ProvisionerJobStatus {
|
||||
return []ProvisionerJobStatus{
|
||||
ProvisionerJobPending,
|
||||
ProvisionerJobRunning,
|
||||
ProvisionerJobSucceeded,
|
||||
ProvisionerJobCanceling,
|
||||
ProvisionerJobCanceled,
|
||||
ProvisionerJobFailed,
|
||||
ProvisionerJobUnknown,
|
||||
}
|
||||
}
|
||||
|
||||
// ProvisionerJobInput represents the input for the job.
|
||||
type ProvisionerJobInput struct {
|
||||
TemplateVersionID *uuid.UUID `json:"template_version_id,omitempty" format:"uuid" table:"template version id"`
|
||||
WorkspaceBuildID *uuid.UUID `json:"workspace_build_id,omitempty" format:"uuid" table:"workspace build id"`
|
||||
Error string `json:"error,omitempty" table:"-"`
|
||||
}
|
||||
|
||||
// ProvisionerJobType represents the type of job.
|
||||
type ProvisionerJobType string
|
||||
|
||||
const (
|
||||
ProvisionerJobTypeTemplateVersionImport ProvisionerJobType = "template_version_import"
|
||||
ProvisionerJobTypeWorkspaceBuild ProvisionerJobType = "workspace_build"
|
||||
ProvisionerJobTypeTemplateVersionDryRun ProvisionerJobType = "template_version_dry_run"
|
||||
)
|
||||
|
||||
// JobErrorCode defines the error code returned by job runner.
|
||||
type JobErrorCode string
|
||||
|
||||
@@ -127,19 +155,23 @@ func JobIsMissingParameterErrorCode(code JobErrorCode) bool {
|
||||
|
||||
// ProvisionerJob describes the job executed by the provisioning daemon.
|
||||
type ProvisionerJob struct {
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time"`
|
||||
StartedAt *time.Time `json:"started_at,omitempty" format:"date-time"`
|
||||
CompletedAt *time.Time `json:"completed_at,omitempty" format:"date-time"`
|
||||
CanceledAt *time.Time `json:"canceled_at,omitempty" format:"date-time"`
|
||||
Error string `json:"error,omitempty"`
|
||||
ErrorCode JobErrorCode `json:"error_code,omitempty" enums:"REQUIRED_TEMPLATE_VARIABLES"`
|
||||
Status ProvisionerJobStatus `json:"status" enums:"pending,running,succeeded,canceling,canceled,failed"`
|
||||
WorkerID *uuid.UUID `json:"worker_id,omitempty" format:"uuid"`
|
||||
FileID uuid.UUID `json:"file_id" format:"uuid"`
|
||||
Tags map[string]string `json:"tags"`
|
||||
QueuePosition int `json:"queue_position"`
|
||||
QueueSize int `json:"queue_size"`
|
||||
ID uuid.UUID `json:"id" format:"uuid" table:"id"`
|
||||
CreatedAt time.Time `json:"created_at" format:"date-time" table:"created at,default_sort"`
|
||||
StartedAt *time.Time `json:"started_at,omitempty" format:"date-time" table:"started at"`
|
||||
CompletedAt *time.Time `json:"completed_at,omitempty" format:"date-time" table:"completed at"`
|
||||
CanceledAt *time.Time `json:"canceled_at,omitempty" format:"date-time" table:"canceled at"`
|
||||
Error string `json:"error,omitempty" table:"error"`
|
||||
ErrorCode JobErrorCode `json:"error_code,omitempty" enums:"REQUIRED_TEMPLATE_VARIABLES" table:"error code"`
|
||||
Status ProvisionerJobStatus `json:"status" enums:"pending,running,succeeded,canceling,canceled,failed" table:"status"`
|
||||
WorkerID *uuid.UUID `json:"worker_id,omitempty" format:"uuid" table:"worker id"`
|
||||
FileID uuid.UUID `json:"file_id" format:"uuid" table:"file id"`
|
||||
Tags map[string]string `json:"tags" table:"tags"`
|
||||
QueuePosition int `json:"queue_position" table:"queue position"`
|
||||
QueueSize int `json:"queue_size" table:"queue size"`
|
||||
OrganizationID uuid.UUID `json:"organization_id" format:"uuid" table:"organization id"`
|
||||
Input ProvisionerJobInput `json:"input" table:"input,recursive_inline"`
|
||||
Type ProvisionerJobType `json:"type" table:"type"`
|
||||
AvailableWorkers []uuid.UUID `json:"available_workers,omitempty" format:"uuid" table:"available workers"`
|
||||
}
|
||||
|
||||
// ProvisionerJobLog represents the provisioner log entry annotated with source and level.
|
||||
|
||||
@@ -27,6 +27,7 @@ const (
|
||||
ResourceOrganization RBACResource = "organization"
|
||||
ResourceOrganizationMember RBACResource = "organization_member"
|
||||
ResourceProvisionerDaemon RBACResource = "provisioner_daemon"
|
||||
ResourceProvisionerJobs RBACResource = "provisioner_jobs"
|
||||
ResourceProvisionerKeys RBACResource = "provisioner_keys"
|
||||
ResourceReplicas RBACResource = "replicas"
|
||||
ResourceSystem RBACResource = "system"
|
||||
@@ -82,6 +83,7 @@ var RBACResourceActions = map[RBACResource][]RBACAction{
|
||||
ResourceOrganization: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
||||
ResourceOrganizationMember: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
||||
ResourceProvisionerDaemon: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
||||
ResourceProvisionerJobs: {ActionRead},
|
||||
ResourceProvisionerKeys: {ActionCreate, ActionDelete, ActionRead},
|
||||
ResourceReplicas: {ActionRead},
|
||||
ResourceSystem: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
||||
|
||||
Reference in New Issue
Block a user