Skip to content

Commit

Permalink
[ui] Adds meta to job list stub and displays a pack logo on the jobs …
Browse files Browse the repository at this point in the history
…index (#14833)

* Adds meta to job list stub and displays a pack logo on the jobs index

* Changelog

* Modifying struct for optional meta param

* Explicitly ask for meta anytime I look up a job from index or job page

* Test case for the endpoint

* adding meta field to API struct and ommitting from response if empty

* passthru method added to api/jobs.list

* Meta param listed in docs for jobs list

* Update api/jobs.go

Co-authored-by: Tim Gross <tgross@hashicorp.com>

Co-authored-by: Tim Gross <tgross@hashicorp.com>
  • Loading branch information
philrenaud and tgross committed Nov 2, 2022
1 parent 8a95f12 commit 1a29e72
Show file tree
Hide file tree
Showing 13 changed files with 94 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .changelog/14833.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
ui: Adds a "Pack" tag and logo on the jobs list index when appropriate
```
24 changes: 23 additions & 1 deletion api/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,31 @@ func (j *Jobs) RegisterOpts(job *Job, opts *RegisterOptions, q *WriteOptions) (*
return &resp, wm, nil
}

type JobListFields struct {
Meta bool
}
type JobListOptions struct {
Fields *JobListFields
}

// List is used to list all of the existing jobs.
func (j *Jobs) List(q *QueryOptions) ([]*JobListStub, *QueryMeta, error) {
return j.ListOptions(nil, q)
}

// List is used to list all of the existing jobs.
func (j *Jobs) ListOptions(opts *JobListOptions, q *QueryOptions) ([]*JobListStub, *QueryMeta, error) {
var resp []*JobListStub
qm, err := j.client.query("/v1/jobs", &resp, q)

destinationURL := "/v1/jobs"

if opts != nil && opts.Fields != nil {
qp := url.Values{}
qp.Add("meta", fmt.Sprint(opts.Fields.Meta))
destinationURL = destinationURL + "?" + qp.Encode()
}

qm, err := j.client.query(destinationURL, &resp, q)
if err != nil {
return nil, qm, err
}
Expand Down Expand Up @@ -1063,6 +1084,7 @@ type JobListStub struct {
ModifyIndex uint64
JobModifyIndex uint64
SubmitTime int64
Meta map[string]string `json:",omitempty"`
}

// JobIDSort is used to sort jobs by their job ID's.
Expand Down
10 changes: 10 additions & 0 deletions command/agent/job_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ func (s *HTTPServer) jobListRequest(resp http.ResponseWriter, req *http.Request)
return nil, nil
}

args.Fields = &structs.JobStubFields{}
// Parse meta query param
jobMeta, err := parseBool(req, "meta")
if err != nil {
return nil, err
}
if jobMeta != nil {
args.Fields.Meta = *jobMeta
}

var out structs.JobListResponse
if err := s.agent.RPC("Job.List", &args, &out); err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion command/job_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (c *JobStatusCommand) Run(args []string) int {

// Invoke list mode if no job ID.
if len(args) == 0 {
jobs, _, err := client.Jobs().List(nil)
jobs, _, err := client.Jobs().ListOptions(nil, nil)

if err != nil {
c.Ui.Error(fmt.Sprintf("Error querying jobs: %s", err))
Expand Down
2 changes: 1 addition & 1 deletion nomad/job_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1377,7 +1377,7 @@ func (j *Job) List(args *structs.JobListRequest, reply *structs.JobListResponse)
if err != nil || summary == nil {
return fmt.Errorf("unable to look up summary for job: %v", job.ID)
}
jobs = append(jobs, job.Stub(summary))
jobs = append(jobs, job.Stub(summary, args.Fields))
return nil
})
if err != nil {
Expand Down
17 changes: 17 additions & 0 deletions nomad/job_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5113,6 +5113,7 @@ func TestJobEndpoint_ListJobs(t *testing.T) {
require.Len(t, resp2.Jobs, 1)
require.Equal(t, job.ID, resp2.Jobs[0].ID)
require.Equal(t, job.Namespace, resp2.Jobs[0].Namespace)
require.Nil(t, resp2.Jobs[0].Meta)

// Lookup the jobs by prefix
get = &structs.JobListRequest{
Expand All @@ -5129,6 +5130,22 @@ func TestJobEndpoint_ListJobs(t *testing.T) {
require.Len(t, resp3.Jobs, 1)
require.Equal(t, job.ID, resp3.Jobs[0].ID)
require.Equal(t, job.Namespace, resp3.Jobs[0].Namespace)

// Lookup jobs with a meta parameter
get = &structs.JobListRequest{
QueryOptions: structs.QueryOptions{
Region: "global",
Namespace: job.Namespace,
Prefix: resp2.Jobs[0].ID[:4],
},
Fields: &structs.JobStubFields{
Meta: true,
},
}
var resp4 structs.JobListResponse
err = msgpackrpc.CallWithCodec(codec, "Job.List", get, &resp4)
require.NoError(t, err)
require.Equal(t, job.Meta["owner"], resp4.Jobs[0].Meta["owner"])
}

// TestJobEndpoint_ListJobs_AllNamespaces_OSS asserts that server
Expand Down
19 changes: 17 additions & 2 deletions nomad/structs/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,12 @@ type JobSpecificRequest struct {
// JobListRequest is used to parameterize a list request
type JobListRequest struct {
QueryOptions
Fields *JobStubFields
}

// Stub returns a summarized version of the job
type JobStubFields struct {
Meta bool
}

// JobPlanRequest is used for the Job.Plan endpoint to trigger a dry-run
Expand Down Expand Up @@ -4517,8 +4523,8 @@ func (j *Job) HasUpdateStrategy() bool {
}

// Stub is used to return a summary of the job
func (j *Job) Stub(summary *JobSummary) *JobListStub {
return &JobListStub{
func (j *Job) Stub(summary *JobSummary, fields *JobStubFields) *JobListStub {
jobStub := &JobListStub{
ID: j.ID,
Namespace: j.Namespace,
ParentID: j.ParentID,
Expand All @@ -4538,6 +4544,14 @@ func (j *Job) Stub(summary *JobSummary) *JobListStub {
SubmitTime: j.SubmitTime,
JobSummary: summary,
}

if fields != nil {
if fields.Meta {
jobStub.Meta = j.Meta
}
}

return jobStub
}

// IsPeriodic returns whether a job is periodic.
Expand Down Expand Up @@ -4721,6 +4735,7 @@ type JobListStub struct {
ModifyIndex uint64
JobModifyIndex uint64
SubmitTime int64
Meta map[string]string `json:",omitempty"`
}

// JobSummary summarizes the state of the allocations of a job
Expand Down
4 changes: 2 additions & 2 deletions ui/app/routes/jobs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default class IndexRoute extends Route.extend(
model(params) {
return RSVP.hash({
jobs: this.store
.query('job', { namespace: params.qpNamespace })
.query('job', { namespace: params.qpNamespace, meta: true })
.catch(notifyForbidden(this)),
namespaces: this.store.findAll('namespace'),
});
Expand All @@ -32,7 +32,7 @@ export default class IndexRoute extends Route.extend(
controller.set('namespacesWatch', this.watchNamespaces.perform());
controller.set(
'modelWatch',
this.watchJobs.perform({ namespace: controller.qpNamesapce })
this.watchJobs.perform({ namespace: controller.qpNamespace, meta: true })
);
}

Expand Down
2 changes: 1 addition & 1 deletion ui/app/routes/jobs/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default class JobRoute extends Route {
const relatedModelsQueries = [
job.get('allocations'),
job.get('evaluations'),
this.store.query('job', { namespace }),
this.store.query('job', { namespace, meta: true }),
this.store.findAll('namespace'),
];

Expand Down
5 changes: 4 additions & 1 deletion ui/app/routes/jobs/job/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export default class IndexRoute extends Route.extend(WithWatchers) {
this.watchLatestDeployment.perform(model),
list:
model.get('hasChildren') &&
this.watchAllJobs.perform({ namespace: model.namespace.get('name') }),
this.watchAllJobs.perform({
namespace: model.namespace.get('name'),
meta: true,
}),
nodes:
model.get('hasClientStatus') &&
this.can.can('read client') &&
Expand Down
5 changes: 5 additions & 0 deletions ui/app/styles/core/tag.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@
vertical-align: 2px;
}

&.is-pack {
position: relative;
top: 3px;
}

.icon {
height: 1rem;
width: 1rem;
Expand Down
8 changes: 8 additions & 0 deletions ui/app/templates/components/job-row.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
class="is-primary"
>
{{this.job.name}}

{{#if this.job.meta.structured.pack}}
<span data-test-pack-tag class="tag is-pack">
{{x-icon "box" class= "test"}}
<span>Pack</span>
</span>
{{/if}}

</LinkTo>
</td>
{{#if this.system.shouldShowNamespaces}}
Expand Down
2 changes: 2 additions & 0 deletions website/content/api-docs/jobs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ The table below shows this endpoint's support for
- `namespace` `(string: "default")` - Specifies the target namespace. Specifying
`*` would return all jobs across all the authorized namespaces.

- `meta` `(bool: false)` - If set, jobs returned will include a [meta](/docs/job-specification/meta) field containing all

### Sample Request

```shell-session
Expand Down

0 comments on commit 1a29e72

Please sign in to comment.