Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ui] Adds meta to job list stub and displays a pack logo on the jobs index #14833

Merged
merged 9 commits into from
Nov 2, 2022
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))
philrenaud marked this conversation as resolved.
Show resolved Hide resolved
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
}
philrenaud marked this conversation as resolved.
Show resolved Hide resolved

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 }),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question non-blocking: We're making a second request to /jobs/:jobId here. Maybe we should refactor line 33 .findRecord to .query instead?

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