mirror of https://github.com/coder/coder.git
feat: add README parsing to template versions (#1500)
This commit is contained in:
parent
0f9559a784
commit
98ccd0eb89
|
@ -73,6 +73,10 @@
|
|||
{
|
||||
"match": "database/queries/*.sql",
|
||||
"cmd": "make gen"
|
||||
},
|
||||
{
|
||||
"match": "provisionerd/proto/provisionerd.proto",
|
||||
"cmd": "make provisionerd/proto/provisionerd.pb.go",
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -78,7 +78,7 @@ var AuditableResources = auditMap(map[any]map[string]Action{
|
|||
"created_at": ActionIgnore, // Never changes, but is implicit and not helpful in a diff.
|
||||
"updated_at": ActionIgnore, // Changes, but is implicit and not helpful in a diff.
|
||||
"name": ActionTrack,
|
||||
"description": ActionTrack,
|
||||
"readme": ActionTrack,
|
||||
"job_id": ActionIgnore, // Not helpful in a diff because jobs aren't tracked in audit logs.
|
||||
},
|
||||
&database.User{}: {
|
||||
|
|
|
@ -175,8 +175,8 @@ func New(options *Options) (http.Handler, func()) {
|
|||
r.Use(
|
||||
apiKeyMiddleware,
|
||||
httpmw.ExtractTemplateParam(options.Database),
|
||||
httpmw.ExtractOrganizationParam(options.Database),
|
||||
)
|
||||
|
||||
r.Get("/", api.template)
|
||||
r.Delete("/", api.deleteTemplate)
|
||||
r.Route("/versions", func(r chi.Router) {
|
||||
|
@ -189,7 +189,6 @@ func New(options *Options) (http.Handler, func()) {
|
|||
r.Use(
|
||||
apiKeyMiddleware,
|
||||
httpmw.ExtractTemplateVersionParam(options.Database),
|
||||
httpmw.ExtractOrganizationParam(options.Database),
|
||||
)
|
||||
|
||||
r.Get("/", api.templateVersion)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/exp/slices"
|
||||
|
@ -1189,7 +1190,7 @@ func (q *fakeQuerier) InsertTemplateVersion(_ context.Context, arg database.Inse
|
|||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
Name: arg.Name,
|
||||
Description: arg.Description,
|
||||
Readme: arg.Readme,
|
||||
JobID: arg.JobID,
|
||||
}
|
||||
q.templateVersions = append(q.templateVersions, version)
|
||||
|
@ -1478,7 +1479,7 @@ func (q *fakeQuerier) UpdateTemplateActiveVersionByID(_ context.Context, arg dat
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, template := range q.templates {
|
||||
if template.ID.String() != arg.ID.String() {
|
||||
if template.ID != arg.ID {
|
||||
continue
|
||||
}
|
||||
template.ActiveVersionID = arg.ActiveVersionID
|
||||
|
@ -1493,7 +1494,7 @@ func (q *fakeQuerier) UpdateTemplateDeletedByID(_ context.Context, arg database.
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, template := range q.templates {
|
||||
if template.ID.String() != arg.ID.String() {
|
||||
if template.ID != arg.ID {
|
||||
continue
|
||||
}
|
||||
template.Deleted = arg.Deleted
|
||||
|
@ -1508,7 +1509,7 @@ func (q *fakeQuerier) UpdateTemplateVersionByID(_ context.Context, arg database.
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, templateVersion := range q.templateVersions {
|
||||
if templateVersion.ID.String() != arg.ID.String() {
|
||||
if templateVersion.ID != arg.ID {
|
||||
continue
|
||||
}
|
||||
templateVersion.TemplateID = arg.TemplateID
|
||||
|
@ -1519,12 +1520,28 @@ func (q *fakeQuerier) UpdateTemplateVersionByID(_ context.Context, arg database.
|
|||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) UpdateTemplateVersionDescriptionByJobID(_ context.Context, arg database.UpdateTemplateVersionDescriptionByJobIDParams) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, templateVersion := range q.templateVersions {
|
||||
if templateVersion.JobID != arg.JobID {
|
||||
continue
|
||||
}
|
||||
templateVersion.Readme = arg.Readme
|
||||
templateVersion.UpdatedAt = time.Now()
|
||||
q.templateVersions[index] = templateVersion
|
||||
return nil
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) UpdateProvisionerDaemonByID(_ context.Context, arg database.UpdateProvisionerDaemonByIDParams) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, daemon := range q.provisionerDaemons {
|
||||
if arg.ID.String() != daemon.ID.String() {
|
||||
if arg.ID != daemon.ID {
|
||||
continue
|
||||
}
|
||||
daemon.UpdatedAt = arg.UpdatedAt
|
||||
|
@ -1540,7 +1557,7 @@ func (q *fakeQuerier) UpdateWorkspaceAgentConnectionByID(_ context.Context, arg
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, agent := range q.provisionerJobAgents {
|
||||
if agent.ID.String() != arg.ID.String() {
|
||||
if agent.ID != arg.ID {
|
||||
continue
|
||||
}
|
||||
agent.FirstConnectedAt = arg.FirstConnectedAt
|
||||
|
@ -1557,7 +1574,7 @@ func (q *fakeQuerier) UpdateProvisionerJobByID(_ context.Context, arg database.U
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, job := range q.provisionerJobs {
|
||||
if arg.ID.String() != job.ID.String() {
|
||||
if arg.ID != job.ID {
|
||||
continue
|
||||
}
|
||||
job.UpdatedAt = arg.UpdatedAt
|
||||
|
@ -1572,7 +1589,7 @@ func (q *fakeQuerier) UpdateProvisionerJobWithCancelByID(_ context.Context, arg
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, job := range q.provisionerJobs {
|
||||
if arg.ID.String() != job.ID.String() {
|
||||
if arg.ID != job.ID {
|
||||
continue
|
||||
}
|
||||
job.CanceledAt = arg.CanceledAt
|
||||
|
@ -1587,7 +1604,7 @@ func (q *fakeQuerier) UpdateProvisionerJobWithCompleteByID(_ context.Context, ar
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, job := range q.provisionerJobs {
|
||||
if arg.ID.String() != job.ID.String() {
|
||||
if arg.ID != job.ID {
|
||||
continue
|
||||
}
|
||||
job.UpdatedAt = arg.UpdatedAt
|
||||
|
@ -1604,7 +1621,7 @@ func (q *fakeQuerier) UpdateWorkspaceAutostart(_ context.Context, arg database.U
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, workspace := range q.workspaces {
|
||||
if workspace.ID.String() != arg.ID.String() {
|
||||
if workspace.ID != arg.ID {
|
||||
continue
|
||||
}
|
||||
workspace.AutostartSchedule = arg.AutostartSchedule
|
||||
|
@ -1620,7 +1637,7 @@ func (q *fakeQuerier) UpdateWorkspaceAutostop(_ context.Context, arg database.Up
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, workspace := range q.workspaces {
|
||||
if workspace.ID.String() != arg.ID.String() {
|
||||
if workspace.ID != arg.ID {
|
||||
continue
|
||||
}
|
||||
workspace.AutostopSchedule = arg.AutostopSchedule
|
||||
|
@ -1636,7 +1653,7 @@ func (q *fakeQuerier) UpdateWorkspaceBuildByID(_ context.Context, arg database.U
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, workspaceBuild := range q.workspaceBuilds {
|
||||
if workspaceBuild.ID.String() != arg.ID.String() {
|
||||
if workspaceBuild.ID != arg.ID {
|
||||
continue
|
||||
}
|
||||
workspaceBuild.UpdatedAt = arg.UpdatedAt
|
||||
|
@ -1653,7 +1670,7 @@ func (q *fakeQuerier) UpdateWorkspaceDeletedByID(_ context.Context, arg database
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
for index, workspace := range q.workspaces {
|
||||
if workspace.ID.String() != arg.ID.String() {
|
||||
if workspace.ID != arg.ID {
|
||||
continue
|
||||
}
|
||||
workspace.Deleted = arg.Deleted
|
||||
|
|
|
@ -234,7 +234,7 @@ CREATE TABLE template_versions (
|
|||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
description character varying(1048576) NOT NULL,
|
||||
readme character varying(1048576) NOT NULL,
|
||||
job_id uuid NOT NULL
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE template_versions RENAME README TO description;
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE template_versions RENAME description TO readme;
|
|
@ -446,7 +446,7 @@ type TemplateVersion struct {
|
|||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"description"`
|
||||
Readme string `db:"readme" json:"readme"`
|
||||
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ type querier interface {
|
|||
UpdateTemplateActiveVersionByID(ctx context.Context, arg UpdateTemplateActiveVersionByIDParams) error
|
||||
UpdateTemplateDeletedByID(ctx context.Context, arg UpdateTemplateDeletedByIDParams) error
|
||||
UpdateTemplateVersionByID(ctx context.Context, arg UpdateTemplateVersionByIDParams) error
|
||||
UpdateTemplateVersionDescriptionByJobID(ctx context.Context, arg UpdateTemplateVersionDescriptionByJobIDParams) error
|
||||
UpdateUserHashedPassword(ctx context.Context, arg UpdateUserHashedPasswordParams) error
|
||||
UpdateUserProfile(ctx context.Context, arg UpdateUserProfileParams) (User, error)
|
||||
UpdateUserRoles(ctx context.Context, arg UpdateUserRolesParams) (User, error)
|
||||
|
|
|
@ -1830,7 +1830,7 @@ func (q *sqlQuerier) UpdateTemplateDeletedByID(ctx context.Context, arg UpdateTe
|
|||
|
||||
const getTemplateVersionByID = `-- name: GetTemplateVersionByID :one
|
||||
SELECT
|
||||
id, template_id, organization_id, created_at, updated_at, name, description, job_id
|
||||
id, template_id, organization_id, created_at, updated_at, name, readme, job_id
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
|
@ -1847,7 +1847,7 @@ func (q *sqlQuerier) GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (
|
|||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.Readme,
|
||||
&i.JobID,
|
||||
)
|
||||
return i, err
|
||||
|
@ -1855,7 +1855,7 @@ func (q *sqlQuerier) GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (
|
|||
|
||||
const getTemplateVersionByJobID = `-- name: GetTemplateVersionByJobID :one
|
||||
SELECT
|
||||
id, template_id, organization_id, created_at, updated_at, name, description, job_id
|
||||
id, template_id, organization_id, created_at, updated_at, name, readme, job_id
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
|
@ -1872,7 +1872,7 @@ func (q *sqlQuerier) GetTemplateVersionByJobID(ctx context.Context, jobID uuid.U
|
|||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.Readme,
|
||||
&i.JobID,
|
||||
)
|
||||
return i, err
|
||||
|
@ -1880,7 +1880,7 @@ func (q *sqlQuerier) GetTemplateVersionByJobID(ctx context.Context, jobID uuid.U
|
|||
|
||||
const getTemplateVersionByTemplateIDAndName = `-- name: GetTemplateVersionByTemplateIDAndName :one
|
||||
SELECT
|
||||
id, template_id, organization_id, created_at, updated_at, name, description, job_id
|
||||
id, template_id, organization_id, created_at, updated_at, name, readme, job_id
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
|
@ -1903,7 +1903,7 @@ func (q *sqlQuerier) GetTemplateVersionByTemplateIDAndName(ctx context.Context,
|
|||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.Readme,
|
||||
&i.JobID,
|
||||
)
|
||||
return i, err
|
||||
|
@ -1911,7 +1911,7 @@ func (q *sqlQuerier) GetTemplateVersionByTemplateIDAndName(ctx context.Context,
|
|||
|
||||
const getTemplateVersionsByTemplateID = `-- name: GetTemplateVersionsByTemplateID :many
|
||||
SELECT
|
||||
id, template_id, organization_id, created_at, updated_at, name, description, job_id
|
||||
id, template_id, organization_id, created_at, updated_at, name, readme, job_id
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
|
@ -1972,7 +1972,7 @@ func (q *sqlQuerier) GetTemplateVersionsByTemplateID(ctx context.Context, arg Ge
|
|||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.Readme,
|
||||
&i.JobID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
|
@ -1997,11 +1997,11 @@ INSERT INTO
|
|||
created_at,
|
||||
updated_at,
|
||||
"name",
|
||||
description,
|
||||
readme,
|
||||
job_id
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, template_id, organization_id, created_at, updated_at, name, description, job_id
|
||||
($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, template_id, organization_id, created_at, updated_at, name, readme, job_id
|
||||
`
|
||||
|
||||
type InsertTemplateVersionParams struct {
|
||||
|
@ -2011,7 +2011,7 @@ type InsertTemplateVersionParams struct {
|
|||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"description"`
|
||||
Readme string `db:"readme" json:"readme"`
|
||||
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
||||
}
|
||||
|
||||
|
@ -2023,7 +2023,7 @@ func (q *sqlQuerier) InsertTemplateVersion(ctx context.Context, arg InsertTempla
|
|||
arg.CreatedAt,
|
||||
arg.UpdatedAt,
|
||||
arg.Name,
|
||||
arg.Description,
|
||||
arg.Readme,
|
||||
arg.JobID,
|
||||
)
|
||||
var i TemplateVersion
|
||||
|
@ -2034,7 +2034,7 @@ func (q *sqlQuerier) InsertTemplateVersion(ctx context.Context, arg InsertTempla
|
|||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.Readme,
|
||||
&i.JobID,
|
||||
)
|
||||
return i, err
|
||||
|
@ -2061,6 +2061,26 @@ func (q *sqlQuerier) UpdateTemplateVersionByID(ctx context.Context, arg UpdateTe
|
|||
return err
|
||||
}
|
||||
|
||||
const updateTemplateVersionDescriptionByJobID = `-- name: UpdateTemplateVersionDescriptionByJobID :exec
|
||||
UPDATE
|
||||
template_versions
|
||||
SET
|
||||
readme = $2,
|
||||
updated_at = now()
|
||||
WHERE
|
||||
job_id = $1
|
||||
`
|
||||
|
||||
type UpdateTemplateVersionDescriptionByJobIDParams struct {
|
||||
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
||||
Readme string `db:"readme" json:"readme"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpdateTemplateVersionDescriptionByJobID(ctx context.Context, arg UpdateTemplateVersionDescriptionByJobIDParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateTemplateVersionDescriptionByJobID, arg.JobID, arg.Readme)
|
||||
return err
|
||||
}
|
||||
|
||||
const getAllUserRoles = `-- name: GetAllUserRoles :one
|
||||
SELECT
|
||||
-- username is returned just to help for logging purposes
|
||||
|
|
|
@ -66,7 +66,7 @@ INSERT INTO
|
|||
created_at,
|
||||
updated_at,
|
||||
"name",
|
||||
description,
|
||||
readme,
|
||||
job_id
|
||||
)
|
||||
VALUES
|
||||
|
@ -80,3 +80,12 @@ SET
|
|||
updated_at = $3
|
||||
WHERE
|
||||
id = $1;
|
||||
|
||||
-- name: UpdateTemplateVersionDescriptionByJobID :exec
|
||||
UPDATE
|
||||
template_versions
|
||||
SET
|
||||
readme = $2,
|
||||
updated_at = now()
|
||||
WHERE
|
||||
job_id = $1;
|
||||
|
|
|
@ -348,6 +348,16 @@ func (server *provisionerdServer) UpdateJob(ctx context.Context, request *proto.
|
|||
}
|
||||
}
|
||||
|
||||
if len(request.Readme) > 0 {
|
||||
err := server.Database.UpdateTemplateVersionDescriptionByJobID(ctx, database.UpdateTemplateVersionDescriptionByJobIDParams{
|
||||
JobID: job.ID,
|
||||
Readme: string(request.Readme),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("update template version description: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(request.ParameterSchemas) > 0 {
|
||||
for _, protoParameter := range request.ParameterSchemas {
|
||||
validationTypeSystem, err := convertValidationTypeSystem(protoParameter.ValidationTypeSystem)
|
||||
|
|
|
@ -357,7 +357,7 @@ func (api *api) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
|||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
Name: namesgenerator.GetRandomName(1),
|
||||
Description: "",
|
||||
Readme: "",
|
||||
JobID: provisionerJob.ID,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -407,5 +407,6 @@ func convertTemplateVersion(version database.TemplateVersion, job codersdk.Provi
|
|||
UpdatedAt: version.UpdatedAt,
|
||||
Name: version.Name,
|
||||
Job: job,
|
||||
Readme: version.Readme,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -216,7 +216,7 @@ func (api *api) workspaceAgentListen(rw http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if build.ID.String() != latestBuild.ID.String() {
|
||||
if build.ID != latestBuild.ID {
|
||||
return xerrors.New("build is outdated")
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -144,7 +144,7 @@ func (api *api) handleAuthInstanceID(rw http.ResponseWriter, r *http.Request, in
|
|||
})
|
||||
return
|
||||
}
|
||||
if latestHistory.ID.String() != resourceHistory.ID.String() {
|
||||
if latestHistory.ID != resourceHistory.ID {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: fmt.Sprintf("resource found for id %q, but isn't registered on the latest history", instanceID),
|
||||
})
|
||||
|
|
|
@ -21,6 +21,7 @@ type TemplateVersion struct {
|
|||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Name string `json:"name"`
|
||||
Job ProvisionerJob `json:"job"`
|
||||
Readme string `json:"readme"`
|
||||
}
|
||||
|
||||
// TemplateVersionParameterSchema represents a parameter parsed from template version source.
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
protobuf "google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/coder/coder/provisionersdk"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.20.0
|
||||
// protoc v3.19.4
|
||||
// source: provisionerd/proto/provisionerd.proto
|
||||
|
||||
package proto
|
||||
|
@ -502,6 +502,7 @@ type UpdateJobRequest struct {
|
|||
JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"`
|
||||
Logs []*Log `protobuf:"bytes,2,rep,name=logs,proto3" json:"logs,omitempty"`
|
||||
ParameterSchemas []*proto.ParameterSchema `protobuf:"bytes,3,rep,name=parameter_schemas,json=parameterSchemas,proto3" json:"parameter_schemas,omitempty"`
|
||||
Readme []byte `protobuf:"bytes,4,opt,name=readme,proto3" json:"readme,omitempty"`
|
||||
}
|
||||
|
||||
func (x *UpdateJobRequest) Reset() {
|
||||
|
@ -557,6 +558,13 @@ func (x *UpdateJobRequest) GetParameterSchemas() []*proto.ParameterSchema {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *UpdateJobRequest) GetReadme() []byte {
|
||||
if x != nil {
|
||||
return x.Readme
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UpdateJobResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -1046,7 +1054,7 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
|
|||
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61,
|
||||
0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x9b, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61,
|
||||
0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xb3, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06,
|
||||
0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f,
|
||||
0x62, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
|
@ -1056,39 +1064,40 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
|
|||
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68,
|
||||
0x65, 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63,
|
||||
0x68, 0x65, 0x6d, 0x61, 0x73, 0x22, 0x77, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a,
|
||||
0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50,
|
||||
0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70,
|
||||
0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2a, 0x34,
|
||||
0x0a, 0x09, 0x4c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50,
|
||||
0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f,
|
||||
0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e,
|
||||
0x45, 0x52, 0x10, 0x01, 0x32, 0x98, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x0a, 0x41, 0x63,
|
||||
0x71, 0x75, 0x69, 0x72, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71,
|
||||
0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, 0x4a, 0x6f,
|
||||
0x62, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64,
|
||||
0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12,
|
||||
0x3e, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1a,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42,
|
||||
0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f,
|
||||
0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x22, 0x77, 0x0a,
|
||||
0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x12, 0x46,
|
||||
0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
|
||||
0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
|
||||
0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2a, 0x34, 0x0a, 0x09, 0x4c, 0x6f, 0x67, 0x53, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e,
|
||||
0x45, 0x52, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50,
|
||||
0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x32, 0x98, 0x02, 0x0a,
|
||||
0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d,
|
||||
0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x0a, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x4a, 0x6f, 0x62,
|
||||
0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e,
|
||||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62,
|
||||
0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1e, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37,
|
||||
0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a,
|
||||
0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
|
||||
0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a,
|
||||
0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
|
||||
0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65,
|
||||
0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -83,6 +83,7 @@ message UpdateJobRequest {
|
|||
string job_id = 1;
|
||||
repeated Log logs = 2;
|
||||
repeated provisioner.ParameterSchema parameter_schemas = 3;
|
||||
bytes readme = 4;
|
||||
}
|
||||
|
||||
message UpdateJobResponse {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
@ -361,8 +362,8 @@ func (p *Server) runJob(ctx context.Context, job *proto.AcquiredJob) {
|
|||
return
|
||||
}
|
||||
// #nosec
|
||||
path := filepath.Join(p.opts.WorkDirectory, header.Name)
|
||||
if !strings.HasPrefix(path, filepath.Clean(p.opts.WorkDirectory)) {
|
||||
headerPath := filepath.Join(p.opts.WorkDirectory, header.Name)
|
||||
if !strings.HasPrefix(headerPath, filepath.Clean(p.opts.WorkDirectory)) {
|
||||
p.failActiveJobf("tar attempts to target relative upper directory")
|
||||
return
|
||||
}
|
||||
|
@ -372,36 +373,36 @@ func (p *Server) runJob(ctx context.Context, job *proto.AcquiredJob) {
|
|||
}
|
||||
switch header.Typeflag {
|
||||
case tar.TypeDir:
|
||||
err = os.MkdirAll(path, mode)
|
||||
err = os.MkdirAll(headerPath, mode)
|
||||
if err != nil {
|
||||
p.failActiveJobf("mkdir %q: %s", path, err)
|
||||
p.failActiveJobf("mkdir %q: %s", headerPath, err)
|
||||
return
|
||||
}
|
||||
p.opts.Logger.Debug(context.Background(), "extracted directory", slog.F("path", path))
|
||||
p.opts.Logger.Debug(context.Background(), "extracted directory", slog.F("path", headerPath))
|
||||
case tar.TypeReg:
|
||||
file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, mode)
|
||||
file, err := os.OpenFile(headerPath, os.O_CREATE|os.O_RDWR, mode)
|
||||
if err != nil {
|
||||
p.failActiveJobf("create file %q (mode %s): %s", path, mode, err)
|
||||
p.failActiveJobf("create file %q (mode %s): %s", headerPath, mode, err)
|
||||
return
|
||||
}
|
||||
// Max file size of 10MB.
|
||||
size, err := io.CopyN(file, reader, (1<<20)*10)
|
||||
// Max file size of 10MiB.
|
||||
size, err := io.CopyN(file, reader, 10<<20)
|
||||
if errors.Is(err, io.EOF) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
_ = file.Close()
|
||||
p.failActiveJobf("copy file %q: %s", path, err)
|
||||
p.failActiveJobf("copy file %q: %s", headerPath, err)
|
||||
return
|
||||
}
|
||||
err = file.Close()
|
||||
if err != nil {
|
||||
p.failActiveJobf("close file %q: %s", path, err)
|
||||
p.failActiveJobf("close file %q: %s", headerPath, err)
|
||||
return
|
||||
}
|
||||
p.opts.Logger.Debug(context.Background(), "extracted file",
|
||||
slog.F("size_bytes", size),
|
||||
slog.F("path", path),
|
||||
slog.F("path", headerPath),
|
||||
slog.F("mode", mode),
|
||||
)
|
||||
}
|
||||
|
@ -411,6 +412,7 @@ func (p *Server) runJob(ctx context.Context, job *proto.AcquiredJob) {
|
|||
case *proto.AcquiredJob_TemplateImport_:
|
||||
p.opts.Logger.Debug(context.Background(), "acquired job is template import")
|
||||
|
||||
p.runReadmeParse(ctx, job)
|
||||
p.runTemplateImport(ctx, shutdown, provisioner, job)
|
||||
case *proto.AcquiredJob_WorkspaceBuild_:
|
||||
p.opts.Logger.Debug(context.Background(), "acquired job is workspace provision",
|
||||
|
@ -450,6 +452,51 @@ func (p *Server) runJob(ctx context.Context, job *proto.AcquiredJob) {
|
|||
}
|
||||
}
|
||||
|
||||
// ReadmeFile is the location we look for to extract documentation from template
|
||||
// versions.
|
||||
const ReadmeFile = "README.md"
|
||||
|
||||
func (p *Server) runReadmeParse(ctx context.Context, job *proto.AcquiredJob) {
|
||||
client, ok := p.client()
|
||||
if !ok {
|
||||
p.failActiveJobf("client disconnected")
|
||||
return
|
||||
}
|
||||
|
||||
fi, err := os.ReadFile(path.Join(p.opts.WorkDirectory, ReadmeFile))
|
||||
if err != nil {
|
||||
_, err := client.UpdateJob(ctx, &proto.UpdateJobRequest{
|
||||
JobId: job.GetJobId(),
|
||||
Logs: []*proto.Log{{
|
||||
Source: proto.LogSource_PROVISIONER_DAEMON,
|
||||
Level: sdkproto.LogLevel_DEBUG,
|
||||
Stage: "No README.md provided",
|
||||
CreatedAt: time.Now().UTC().UnixMilli(),
|
||||
}},
|
||||
})
|
||||
if err != nil {
|
||||
p.failActiveJobf("write log: %s", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
_, err = client.UpdateJob(ctx, &proto.UpdateJobRequest{
|
||||
JobId: job.GetJobId(),
|
||||
Logs: []*proto.Log{{
|
||||
Source: proto.LogSource_PROVISIONER_DAEMON,
|
||||
Level: sdkproto.LogLevel_INFO,
|
||||
Stage: "Adding README.md...",
|
||||
CreatedAt: time.Now().UTC().UnixMilli(),
|
||||
}},
|
||||
Readme: fi,
|
||||
})
|
||||
if err != nil {
|
||||
p.failActiveJobf("write log: %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Server) runTemplateImport(ctx, shutdown context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob) {
|
||||
client, ok := p.client()
|
||||
if !ok {
|
||||
|
|
|
@ -214,6 +214,7 @@ func TestProvisionerd(t *testing.T) {
|
|||
didLog atomic.Bool
|
||||
didAcquireJob atomic.Bool
|
||||
didDryRun atomic.Bool
|
||||
didReadme atomic.Bool
|
||||
completeChan = make(chan struct{})
|
||||
completeOnce sync.Once
|
||||
)
|
||||
|
@ -230,7 +231,8 @@ func TestProvisionerd(t *testing.T) {
|
|||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
"test.txt": "content",
|
||||
provisionerd.ReadmeFile: "# A cool template 😎\n",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_TemplateImport_{
|
||||
TemplateImport: &proto.AcquiredJob_TemplateImport{
|
||||
|
@ -240,9 +242,12 @@ func TestProvisionerd(t *testing.T) {
|
|||
}, nil
|
||||
},
|
||||
updateJob: func(ctx context.Context, update *proto.UpdateJobRequest) (*proto.UpdateJobResponse, error) {
|
||||
if len(update.Logs) != 0 {
|
||||
if len(update.Logs) > 0 {
|
||||
didLog.Store(true)
|
||||
}
|
||||
if len(update.Readme) > 0 {
|
||||
didReadme.Store(true)
|
||||
}
|
||||
return &proto.UpdateJobResponse{}, nil
|
||||
},
|
||||
completeJob: func(ctx context.Context, job *proto.CompletedJob) (*proto.Empty, error) {
|
||||
|
|
|
@ -231,9 +231,10 @@ export interface TemplateVersion {
|
|||
readonly updated_at: string
|
||||
readonly name: string
|
||||
readonly job: ProvisionerJob
|
||||
readonly readme: string
|
||||
}
|
||||
|
||||
// From codersdk/templateversions.go:30:6
|
||||
// From codersdk/templateversions.go:31:6
|
||||
export interface TemplateVersionParameter {
|
||||
// Named type "github.com/coder/coder/coderd/database.ParameterValue" unknown, using "any"
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
@ -242,7 +243,7 @@ export interface TemplateVersionParameter {
|
|||
readonly default_source_value: boolean
|
||||
}
|
||||
|
||||
// From codersdk/templateversions.go:27:6
|
||||
// From codersdk/templateversions.go:28:6
|
||||
export interface TemplateVersionParameterSchema {
|
||||
readonly id: string
|
||||
readonly created_at: string
|
||||
|
|
Loading…
Reference in New Issue