Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Nomad
Commits
8c600acb
Commit
8c600acb
authored
3 years ago
by
Jai Bhagat
Browse files
Options
Download
Email Patches
Plain Diff
ui: prettify js files
parent
635e9370
Changes
291
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
ui/app/controllers/exec.js
+21
-7
ui/app/controllers/exec.js
ui/app/controllers/jobs/index.js
+23
-6
ui/app/controllers/jobs/index.js
ui/app/controllers/jobs/job/allocations.js
+36
-9
ui/app/controllers/jobs/job/allocations.js
ui/app/controllers/jobs/job/clients.js
+28
-8
ui/app/controllers/jobs/job/clients.js
ui/app/controllers/jobs/job/definition.js
+3
-1
ui/app/controllers/jobs/job/definition.js
ui/app/controllers/jobs/job/deployments.js
+3
-1
ui/app/controllers/jobs/job/deployments.js
ui/app/controllers/jobs/job/index.js
+8
-2
ui/app/controllers/jobs/job/index.js
ui/app/controllers/jobs/job/task-group.js
+30
-8
ui/app/controllers/jobs/job/task-group.js
ui/app/controllers/jobs/job/versions.js
+6
-2
ui/app/controllers/jobs/job/versions.js
ui/app/controllers/optimize.js
+31
-9
ui/app/controllers/optimize.js
ui/app/controllers/topology.js
+26
-8
ui/app/controllers/topology.js
ui/app/helpers/bind.js
+4
-1
ui/app/helpers/bind.js
ui/app/helpers/is-object.js
+2
-1
ui/app/helpers/is-object.js
ui/app/helpers/x-icon.js
+3
-1
ui/app/helpers/x-icon.js
ui/app/mixins/searchable.js
+11
-3
ui/app/mixins/searchable.js
ui/app/mixins/sortable-factory.js
+8
-3
ui/app/mixins/sortable-factory.js
ui/app/mixins/window-resizable.js
+4
-1
ui/app/mixins/window-resizable.js
ui/app/mixins/with-watchers.js
+4
-1
ui/app/mixins/with-watchers.js
ui/app/models/allocation.js
+9
-3
ui/app/models/allocation.js
ui/app/models/deployment.js
+12
-3
ui/app/models/deployment.js
with
272 additions
and
78 deletions
+272
-78
ui/app/controllers/exec.js
+
21
-
7
View file @
8c600acb
...
...
@@ -25,18 +25,25 @@ export default class ExecController extends Controller {
@
computed
(
'
model.allocations.@each.clientStatus
'
)
get
pendingAndRunningAllocations
()
{
return
this
.
model
.
allocations
.
filter
(
(
allocation
)
=>
allocation
.
clientStatus
===
'
pending
'
||
allocation
.
clientStatus
===
'
running
'
(
allocation
)
=>
allocation
.
clientStatus
===
'
pending
'
||
allocation
.
clientStatus
===
'
running
'
);
}
@
mapBy
(
'
pendingAndRunningAllocations
'
,
'
taskGroup
'
)
pendingAndRunningTaskGroups
;
@
mapBy
(
'
pendingAndRunningAllocations
'
,
'
taskGroup
'
)
pendingAndRunningTaskGroups
;
@
uniq
(
'
pendingAndRunningTaskGroups
'
)
uniquePendingAndRunningTaskGroups
;
taskGroupSorting
=
[
'
name
'
];
@
sort
(
'
uniquePendingAndRunningTaskGroups
'
,
'
taskGroupSorting
'
)
sortedTaskGroups
;
@
sort
(
'
uniquePendingAndRunningTaskGroups
'
,
'
taskGroupSorting
'
)
sortedTaskGroups
;
setUpTerminal
(
Terminal
)
{
this
.
terminal
=
new
Terminal
({
fontFamily
:
'
monospace
'
,
fontWeight
:
'
400
'
});
this
.
terminal
=
new
Terminal
({
fontFamily
:
'
monospace
'
,
fontWeight
:
'
400
'
,
});
window
.
execTerminal
=
this
.
terminal
;
// Issue to improve: https://github.com/hashicorp/nomad/issues/7457
this
.
terminal
.
write
(
ANSI_UI_GRAY_400
);
...
...
@@ -64,7 +71,10 @@ export default class ExecController extends Controller {
allocation
=
this
.
allocations
.
findBy
(
'
shortId
'
,
this
.
allocationShortId
);
}
else
{
allocation
=
this
.
allocations
.
find
((
allocation
)
=>
allocation
.
states
.
filterBy
(
'
isActive
'
).
mapBy
(
'
name
'
).
includes
(
this
.
taskName
)
allocation
.
states
.
filterBy
(
'
isActive
'
)
.
mapBy
(
'
name
'
)
.
includes
(
this
.
taskName
)
);
}
...
...
@@ -94,7 +104,9 @@ export default class ExecController extends Controller {
this
.
terminal
.
writeln
(
''
);
}
this
.
terminal
.
writeln
(
'
Customize your command, then hit ‘return’ to run.
'
);
this
.
terminal
.
writeln
(
'
Customize your command, then hit ‘return’ to run.
'
);
this
.
terminal
.
writeln
(
''
);
this
.
terminal
.
write
(
`$ nomad alloc exec -i -t -task
${
escapeTaskName
(
taskName
)}
${
...
...
@@ -126,7 +138,9 @@ export default class ExecController extends Controller {
new
ExecSocketXtermAdapter
(
this
.
terminal
,
this
.
socket
,
this
.
token
.
secret
);
}
else
{
this
.
terminal
.
writeln
(
`Failed to open a socket because task
${
this
.
taskName
}
is not active.`
);
this
.
terminal
.
writeln
(
`Failed to open a socket because task
${
this
.
taskName
}
is not active.`
);
}
}
}
This diff is collapsed.
Click to expand it.
ui/app/controllers/jobs/index.js
+
23
-
6
View file @
8c600acb
...
...
@@ -8,11 +8,17 @@ import { scheduleOnce } from '@ember/runloop';
import
intersection
from
'
lodash.intersection
'
;
import
Sortable
from
'
nomad-ui/mixins/sortable
'
;
import
Searchable
from
'
nomad-ui/mixins/searchable
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
,
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
classic
from
'
ember-classic-decorator
'
;
@
classic
export
default
class
IndexController
extends
Controller
.
extend
(
Sortable
,
Searchable
)
{
export
default
class
IndexController
extends
Controller
.
extend
(
Sortable
,
Searchable
)
{
@
service
system
;
@
service
userSettings
;
...
...
@@ -100,7 +106,9 @@ export default class IndexController extends Controller.extend(Sortable, Searcha
@
computed
(
'
selectionDatacenter
'
,
'
visibleJobs.[]
'
)
get
optionsDatacenter
()
{
const
flatten
=
(
acc
,
val
)
=>
acc
.
concat
(
val
);
const
allDatacenters
=
new
Set
(
this
.
visibleJobs
.
mapBy
(
'
datacenters
'
).
reduce
(
flatten
,
[]));
const
allDatacenters
=
new
Set
(
this
.
visibleJobs
.
mapBy
(
'
datacenters
'
).
reduce
(
flatten
,
[])
);
// Remove any invalid datacenters from the query param/selection
const
availableDatacenters
=
Array
.
from
(
allDatacenters
).
compact
();
...
...
@@ -144,7 +152,10 @@ export default class IndexController extends Controller.extend(Sortable, Searcha
const
availablePrefixes
=
prefixes
.
mapBy
(
'
prefix
'
);
scheduleOnce
(
'
actions
'
,
()
=>
{
// eslint-disable-next-line ember/no-side-effects
this
.
set
(
'
qpPrefix
'
,
serialize
(
intersection
(
availablePrefixes
,
this
.
selectionPrefix
)));
this
.
set
(
'
qpPrefix
'
,
serialize
(
intersection
(
availablePrefixes
,
this
.
selectionPrefix
))
);
});
// Sort, format, and include the count in the label
...
...
@@ -216,12 +227,18 @@ export default class IndexController extends Controller.extend(Sortable, Searcha
return
false
;
}
if
(
datacenters
.
length
&&
!
job
.
get
(
'
datacenters
'
).
find
((
dc
)
=>
datacenters
.
includes
(
dc
)))
{
if
(
datacenters
.
length
&&
!
job
.
get
(
'
datacenters
'
).
find
((
dc
)
=>
datacenters
.
includes
(
dc
))
)
{
return
false
;
}
const
name
=
job
.
get
(
'
name
'
);
if
(
prefixes
.
length
&&
!
prefixes
.
find
((
prefix
)
=>
name
.
startsWith
(
prefix
)))
{
if
(
prefixes
.
length
&&
!
prefixes
.
find
((
prefix
)
=>
name
.
startsWith
(
prefix
))
)
{
return
false
;
}
...
...
This diff is collapsed.
Click to expand it.
ui/app/controllers/jobs/job/allocations.js
+
36
-
9
View file @
8c600acb
...
...
@@ -7,7 +7,10 @@ import intersection from 'lodash.intersection';
import
Sortable
from
'
nomad-ui/mixins/sortable
'
;
import
Searchable
from
'
nomad-ui/mixins/searchable
'
;
import
WithNamespaceResetting
from
'
nomad-ui/mixins/with-namespace-resetting
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
,
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
classic
from
'
ember-classic-decorator
'
;
@
classic
...
...
@@ -61,18 +64,32 @@ export default class AllocationsController extends Controller.extend(
return
this
.
get
(
'
model.allocations
'
)
||
[];
}
@
computed
(
'
allocations.[]
'
,
'
selectionStatus
'
,
'
selectionClient
'
,
'
selectionTaskGroup
'
)
@
computed
(
'
allocations.[]
'
,
'
selectionStatus
'
,
'
selectionClient
'
,
'
selectionTaskGroup
'
)
get
filteredAllocations
()
{
const
{
selectionStatus
,
selectionClient
,
selectionTaskGroup
}
=
this
;
return
this
.
allocations
.
filter
((
alloc
)
=>
{
if
(
selectionStatus
.
length
&&
!
selectionStatus
.
includes
(
alloc
.
clientStatus
))
{
if
(
selectionStatus
.
length
&&
!
selectionStatus
.
includes
(
alloc
.
clientStatus
)
)
{
return
false
;
}
if
(
selectionClient
.
length
&&
!
selectionClient
.
includes
(
alloc
.
get
(
'
node.shortId
'
)))
{
if
(
selectionClient
.
length
&&
!
selectionClient
.
includes
(
alloc
.
get
(
'
node.shortId
'
))
)
{
return
false
;
}
if
(
selectionTaskGroup
.
length
&&
!
selectionTaskGroup
.
includes
(
alloc
.
taskGroupName
))
{
if
(
selectionTaskGroup
.
length
&&
!
selectionTaskGroup
.
includes
(
alloc
.
taskGroupName
)
)
{
return
false
;
}
return
true
;
...
...
@@ -104,12 +121,17 @@ export default class AllocationsController extends Controller.extend(
@
computed
(
'
model.allocations.[]
'
,
'
selectionClient
'
)
get
optionsClients
()
{
const
clients
=
Array
.
from
(
new
Set
(
this
.
model
.
allocations
.
mapBy
(
'
node.shortId
'
))).
compact
();
const
clients
=
Array
.
from
(
new
Set
(
this
.
model
.
allocations
.
mapBy
(
'
node.shortId
'
))
).
compact
();
// Update query param when the list of clients changes.
scheduleOnce
(
'
actions
'
,
()
=>
{
// eslint-disable-next-line ember/no-side-effects
this
.
set
(
'
qpClient
'
,
serialize
(
intersection
(
clients
,
this
.
selectionClient
)));
this
.
set
(
'
qpClient
'
,
serialize
(
intersection
(
clients
,
this
.
selectionClient
))
);
});
return
clients
.
sort
().
map
((
c
)
=>
({
key
:
c
,
label
:
c
}));
...
...
@@ -117,12 +139,17 @@ export default class AllocationsController extends Controller.extend(
@
computed
(
'
model.allocations.[]
'
,
'
selectionTaskGroup
'
)
get
optionsTaskGroups
()
{
const
taskGroups
=
Array
.
from
(
new
Set
(
this
.
model
.
allocations
.
mapBy
(
'
taskGroupName
'
))).
compact
();
const
taskGroups
=
Array
.
from
(
new
Set
(
this
.
model
.
allocations
.
mapBy
(
'
taskGroupName
'
))
).
compact
();
// Update query param when the list of task groups changes.
scheduleOnce
(
'
actions
'
,
()
=>
{
// eslint-disable-next-line ember/no-side-effects
this
.
set
(
'
qpTaskGroup
'
,
serialize
(
intersection
(
taskGroups
,
this
.
selectionTaskGroup
)));
this
.
set
(
'
qpTaskGroup
'
,
serialize
(
intersection
(
taskGroups
,
this
.
selectionTaskGroup
))
);
});
return
taskGroups
.
sort
().
map
((
tg
)
=>
({
key
:
tg
,
label
:
tg
}));
...
...
This diff is collapsed.
Click to expand it.
ui/app/controllers/jobs/job/clients.js
+
28
-
8
View file @
8c600acb
...
...
@@ -8,7 +8,10 @@ import SortableFactory from 'nomad-ui/mixins/sortable-factory';
import
Searchable
from
'
nomad-ui/mixins/searchable
'
;
import
WithNamespaceResetting
from
'
nomad-ui/mixins/with-namespace-resetting
'
;
import
jobClientStatus
from
'
nomad-ui/utils/properties/job-client-status
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
,
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
classic
from
'
ember-classic-decorator
'
;
@
classic
...
...
@@ -96,7 +99,10 @@ export default class ClientsController extends Controller.extend(
return
this
.
nodes
.
filter
((
node
)
=>
{
if
(
statuses
.
length
&&
!
statuses
.
includes
(
this
.
jobClientStatus
.
byNode
[
node
.
id
]))
{
if
(
statuses
.
length
&&
!
statuses
.
includes
(
this
.
jobClientStatus
.
byNode
[
node
.
id
])
)
{
return
false
;
}
if
(
datacenters
.
length
&&
!
datacenters
.
includes
(
node
.
datacenter
))
{
...
...
@@ -109,7 +115,9 @@ export default class ClientsController extends Controller.extend(
return
true
;
})
.
map
((
node
)
=>
{
const
allocations
=
this
.
job
.
allocations
.
filter
((
alloc
)
=>
alloc
.
get
(
'
node.id
'
)
==
node
.
id
);
const
allocations
=
this
.
job
.
allocations
.
filter
(
(
alloc
)
=>
alloc
.
get
(
'
node.id
'
)
==
node
.
id
);
return
{
node
,
...
...
@@ -137,12 +145,17 @@ export default class ClientsController extends Controller.extend(
@
computed
(
'
selectionDatacenter
'
,
'
nodes
'
)
get
optionsDatacenter
()
{
const
datacenters
=
Array
.
from
(
new
Set
(
this
.
nodes
.
mapBy
(
'
datacenter
'
))).
compact
();
const
datacenters
=
Array
.
from
(
new
Set
(
this
.
nodes
.
mapBy
(
'
datacenter
'
))
).
compact
();
// Update query param when the list of datacenters changes.
scheduleOnce
(
'
actions
'
,
()
=>
{
// eslint-disable-next-line ember/no-side-effects
this
.
set
(
'
qpDatacenter
'
,
serialize
(
intersection
(
datacenters
,
this
.
selectionDatacenter
)));
this
.
set
(
'
qpDatacenter
'
,
serialize
(
intersection
(
datacenters
,
this
.
selectionDatacenter
))
);
});
return
datacenters
.
sort
().
map
((
dc
)
=>
({
key
:
dc
,
label
:
dc
}));
...
...
@@ -150,15 +163,22 @@ export default class ClientsController extends Controller.extend(
@
computed
(
'
selectionClientClass
'
,
'
nodes
'
)
get
optionsClientClass
()
{
const
clientClasses
=
Array
.
from
(
new
Set
(
this
.
nodes
.
mapBy
(
'
nodeClass
'
))).
compact
();
const
clientClasses
=
Array
.
from
(
new
Set
(
this
.
nodes
.
mapBy
(
'
nodeClass
'
))
).
compact
();
// Update query param when the list of datacenters changes.
scheduleOnce
(
'
actions
'
,
()
=>
{
// eslint-disable-next-line ember/no-side-effects
this
.
set
(
'
qpClientClass
'
,
serialize
(
intersection
(
clientClasses
,
this
.
selectionClientClass
)));
this
.
set
(
'
qpClientClass
'
,
serialize
(
intersection
(
clientClasses
,
this
.
selectionClientClass
))
);
});
return
clientClasses
.
sort
().
map
((
clientClass
)
=>
({
key
:
clientClass
,
label
:
clientClass
}));
return
clientClasses
.
sort
()
.
map
((
clientClass
)
=>
({
key
:
clientClass
,
label
:
clientClass
}));
}
@
action
...
...
This diff is collapsed.
Click to expand it.
ui/app/controllers/jobs/job/definition.js
+
3
-
1
View file @
8c600acb
...
...
@@ -4,7 +4,9 @@ import { alias } from '@ember/object/computed';
import
classic
from
'
ember-classic-decorator
'
;
@
classic
export
default
class
DefinitionController
extends
Controller
.
extend
(
WithNamespaceResetting
)
{
export
default
class
DefinitionController
extends
Controller
.
extend
(
WithNamespaceResetting
)
{
@
alias
(
'
model.job
'
)
job
;
@
alias
(
'
model.definition
'
)
definition
;
...
...
This diff is collapsed.
Click to expand it.
ui/app/controllers/jobs/job/deployments.js
+
3
-
1
View file @
8c600acb
...
...
@@ -4,6 +4,8 @@ import { alias } from '@ember/object/computed';
import
classic
from
'
ember-classic-decorator
'
;
@
classic
export
default
class
DeploymentsController
extends
Controller
.
extend
(
WithNamespaceResetting
)
{
export
default
class
DeploymentsController
extends
Controller
.
extend
(
WithNamespaceResetting
)
{
@
alias
(
'
model
'
)
job
;
}
This diff is collapsed.
Click to expand it.
ui/app/controllers/jobs/job/index.js
+
8
-
2
View file @
8c600acb
...
...
@@ -6,7 +6,9 @@ import { action } from '@ember/object';
import
classic
from
'
ember-classic-decorator
'
;
@
classic
export
default
class
IndexController
extends
Controller
.
extend
(
WithNamespaceResetting
)
{
export
default
class
IndexController
extends
Controller
.
extend
(
WithNamespaceResetting
)
{
@
service
system
;
queryParams
=
[
...
...
@@ -38,7 +40,11 @@ export default class IndexController extends Controller.extend(WithNamespaceRese
@
action
gotoTaskGroup
(
taskGroup
)
{
this
.
transitionToRoute
(
'
jobs.job.task-group
'
,
taskGroup
.
get
(
'
job
'
),
taskGroup
);
this
.
transitionToRoute
(
'
jobs.job.task-group
'
,
taskGroup
.
get
(
'
job
'
),
taskGroup
);
}
@
action
...
...
This diff is collapsed.
Click to expand it.
ui/app/controllers/jobs/job/task-group.js
+
30
-
8
View file @
8c600acb
...
...
@@ -9,7 +9,10 @@ import { qpBuilder } from 'nomad-ui/utils/classes/query-params';
import
Sortable
from
'
nomad-ui/mixins/sortable
'
;
import
Searchable
from
'
nomad-ui/mixins/searchable
'
;
import
WithNamespaceResetting
from
'
nomad-ui/mixins/with-namespace-resetting
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
,
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
classic
from
'
ember-classic-decorator
'
;
@
classic
...
...
@@ -65,10 +68,16 @@ export default class TaskGroupController extends Controller.extend(
const
{
selectionStatus
,
selectionClient
}
=
this
;
return
this
.
allocations
.
filter
((
alloc
)
=>
{
if
(
selectionStatus
.
length
&&
!
selectionStatus
.
includes
(
alloc
.
clientStatus
))
{
if
(
selectionStatus
.
length
&&
!
selectionStatus
.
includes
(
alloc
.
clientStatus
)
)
{
return
false
;
}
if
(
selectionClient
.
length
&&
!
selectionClient
.
includes
(
alloc
.
get
(
'
node.shortId
'
)))
{
if
(
selectionClient
.
length
&&
!
selectionClient
.
includes
(
alloc
.
get
(
'
node.shortId
'
))
)
{
return
false
;
}
...
...
@@ -94,15 +103,23 @@ export default class TaskGroupController extends Controller.extend(
@
computed
(
'
sortedScaleEvents.@each.hasCount
'
,
function
()
{
const
countEventsCount
=
this
.
sortedScaleEvents
.
filterBy
(
'
hasCount
'
).
length
;
return
countEventsCount
>
1
&&
countEventsCount
>=
this
.
sortedScaleEvents
.
length
/
2
;
return
(
countEventsCount
>
1
&&
countEventsCount
>=
this
.
sortedScaleEvents
.
length
/
2
);
})
shouldShowScaleEventTimeline
;
@
computed
(
'
model.job.{namespace,runningDeployment}
'
)
get
tooltipText
()
{
if
(
this
.
can
.
cannot
(
'
scale job
'
,
null
,
{
namespace
:
this
.
model
.
job
.
namespace
.
get
(
'
name
'
)
}))
if
(
this
.
can
.
cannot
(
'
scale job
'
,
null
,
{
namespace
:
this
.
model
.
job
.
namespace
.
get
(
'
name
'
),
})
)
return
"
You aren't allowed to scale task groups
"
;
if
(
this
.
model
.
job
.
runningDeployment
)
return
'
You cannot scale task groups during a deployment
'
;
if
(
this
.
model
.
job
.
runningDeployment
)
return
'
You cannot scale task groups during a deployment
'
;
return
undefined
;
}
...
...
@@ -128,12 +145,17 @@ export default class TaskGroupController extends Controller.extend(
@
computed
(
'
model.allocations.[]
'
,
'
selectionClient
'
)
get
optionsClients
()
{
const
clients
=
Array
.
from
(
new
Set
(
this
.
model
.
allocations
.
mapBy
(
'
node.shortId
'
))).
compact
();
const
clients
=
Array
.
from
(
new
Set
(
this
.
model
.
allocations
.
mapBy
(
'
node.shortId
'
))
).
compact
();
// Update query param when the list of clients changes.
scheduleOnce
(
'
actions
'
,
()
=>
{
// eslint-disable-next-line ember/no-side-effects
this
.
set
(
'
qpClient
'
,
serialize
(
intersection
(
clients
,
this
.
selectionClient
)));
this
.
set
(
'
qpClient
'
,
serialize
(
intersection
(
clients
,
this
.
selectionClient
))
);
});
return
clients
.
sort
().
map
((
dc
)
=>
({
key
:
dc
,
label
:
dc
}));
...
...
This diff is collapsed.
Click to expand it.
ui/app/controllers/jobs/job/versions.js
+
6
-
2
View file @
8c600acb
...
...
@@ -12,14 +12,18 @@ const errorLevelToAlertClass = {
};
@
classic
export
default
class
VersionsController
extends
Controller
.
extend
(
WithNamespaceResetting
)
{
export
default
class
VersionsController
extends
Controller
.
extend
(
WithNamespaceResetting
)
{
error
=
null
;
@
alias
(
'
model
'
)
job
;
@
computed
(
'
error.level
'
)
get
errorLevelClass
()
{
return
errorLevelToAlertClass
[
this
.
get
(
'
error.level
'
)]
||
alertClassFallback
;
return
(
errorLevelToAlertClass
[
this
.
get
(
'
error.level
'
)]
||
alertClassFallback
);
}
onDismiss
()
{
...
...
This diff is collapsed.
Click to expand it.
ui/app/controllers/optimize.js
+
31
-
9
View file @
8c600acb
...
...
@@ -7,7 +7,10 @@ import { inject as service } from '@ember/service';
import
{
scheduleOnce
}
from
'
@ember/runloop
'
;
import
{
task
}
from
'
ember-concurrency
'
;
import
intersection
from
'
lodash.intersection
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
{
serialize
,
deserializedQueryParam
as
selection
,
}
from
'
nomad-ui/utils/qp-serialize
'
;
import
EmberObject
,
{
computed
}
from
'
@ember/object
'
;
import
{
alias
}
from
'
@ember/object/computed
'
;
...
...
@@ -104,13 +107,17 @@ export default class OptimizeController extends Controller {
get
optionsDatacenter
()
{
const
flatten
=
(
acc
,
val
)
=>
acc
.
concat
(
val
);
const
allDatacenters
=
new
Set
(
this
.
summaries
.
mapBy
(
'
job.datacenters
'
).
reduce
(
flatten
,
[]));
const
allDatacenters
=
new
Set
(
this
.
summaries
.
mapBy
(
'
job.datacenters
'
).
reduce
(
flatten
,
[])
);
// Remove any invalid datacenters from the query param/selection
const
availableDatacenters
=
Array
.
from
(
allDatacenters
).
compact
();
scheduleOnce
(
'
actions
'
,
()
=>
{
// eslint-disable-next-line ember/no-side-effects
this
.
qpDatacenter
=
serialize
(
intersection
(
availableDatacenters
,
this
.
selectionDatacenter
));
this
.
qpDatacenter
=
serialize
(
intersection
(
availableDatacenters
,
this
.
selectionDatacenter
)
);
});
return
availableDatacenters
.
sort
().
map
((
dc
)
=>
({
key
:
dc
,
label
:
dc
}));
...
...
@@ -144,7 +151,9 @@ export default class OptimizeController extends Controller {
const
availablePrefixes
=
prefixes
.
mapBy
(
'
prefix
'
);
scheduleOnce
(
'
actions
'
,
()
=>
{
// eslint-disable-next-line ember/no-side-effects
this
.
qpPrefix
=
serialize
(
intersection
(
availablePrefixes
,
this
.
selectionPrefix
));
this
.
qpPrefix
=
serialize
(
intersection
(
availablePrefixes
,
this
.
selectionPrefix
)
);
});
// Sort, format, and include the count in the label
...
...
@@ -171,7 +180,10 @@ export default class OptimizeController extends Controller {
return
false
;
}
if
(
this
.
qpNamespace
!==
'
*
'
&&
job
.
get
(
'
namespace.name
'
)
!==
this
.
qpNamespace
)
{
if
(
this
.
qpNamespace
!==
'
*
'
&&
job
.
get
(
'
namespace.name
'
)
!==
this
.
qpNamespace
)
{
return
false
;
}
...
...
@@ -183,12 +195,18 @@ export default class OptimizeController extends Controller {
return
false
;
}
if
(
datacenters
.
length
&&
!
job
.
get
(
'
datacenters
'
).
find
((
dc
)
=>
datacenters
.
includes
(
dc
)))
{
if
(
datacenters
.
length
&&
!
job
.
get
(
'
datacenters
'
).
find
((
dc
)
=>
datacenters
.
includes
(
dc
))
)
{
return
false
;
}
const
name
=
job
.
get
(
'
name
'
);
if
(
prefixes
.
length
&&
!
prefixes
.
find
((
prefix
)
=>
name
.
startsWith
(
prefix
)))
{
if
(
prefixes
.
length
&&
!
prefixes
.
find
((
prefix
)
=>
name
.
startsWith
(
prefix
))
)
{
return
false
;
}
...
...
@@ -207,8 +225,12 @@ export default class OptimizeController extends Controller {
// This is a task because the accordion uses timeouts for animation
// eslint-disable-next-line require-yield
@(
task
(
function
*
()
{
const
currentSummaryIndex
=
this
.
filteredSummaries
.
indexOf
(
this
.
activeRecommendationSummary
);
const
nextSummary
=
this
.
filteredSummaries
.
objectAt
(
currentSummaryIndex
+
1
);
const
currentSummaryIndex
=
this
.
filteredSummaries
.
indexOf
(
this
.
activeRecommendationSummary
);
const
nextSummary
=
this
.
filteredSummaries
.
objectAt
(
currentSummaryIndex
+
1
);
if
(
nextSummary
)
{
this
.
transitionToSummary
(
nextSummary
);
...
...
This diff is collapsed.
Click to expand it.
ui/app/controllers/topology.js
+
26
-
8
View file @
8c600acb
...
...
@@ -31,13 +31,17 @@ export default class TopologyControllers extends Controller {
@
computed
(
'
model.nodes.@each.resources
'
)
get
totalMemory
()
{
const
mibs
=
this
.
model
.
nodes
.
mapBy
(
'
resources.memory
'
).
reduce
(
sumAggregator
,
0
);
const
mibs
=
this
.
model
.
nodes
.
mapBy
(
'
resources.memory
'
)
.
reduce
(
sumAggregator
,
0
);
return
mibs
*
1024
*
1024
;
}
@
computed
(
'
model.nodes.@each.resources
'
)
get
totalCPU
()
{
return
this
.
model
.
nodes
.
mapBy
(
'
resources.cpu
'
).
reduce
((
sum
,
cpu
)
=>
sum
+
(
cpu
||
0
),
0
);
return
this
.
model
.
nodes
.
mapBy
(
'
resources.cpu
'
)
.
reduce
((
sum
,
cpu
)
=>
sum
+
(
cpu
||
0
),
0
);
}
@
computed
(
'
totalMemory
'
)
...
...
@@ -70,7 +74,9 @@ export default class TopologyControllers extends Controller {
@
computed
(
'
scheduledAllocations.@each.allocatedResources
'
)
get
totalReservedCPU
()
{
return
this
.
scheduledAllocations
.
mapBy
(
'
allocatedResources.cpu
'
).
reduce
(
sumAggregator
,
0
);
return
this
.
scheduledAllocations
.
mapBy
(
'
allocatedResources.cpu
'
)
.
reduce
(
sumAggregator
,
0
);
}
@
computed
(
'
totalMemory
'
,
'
totalReservedMemory
'
)
...
...
@@ -85,23 +91,35 @@ export default class TopologyControllers extends Controller {
return
this
.
totalReservedCPU
/
this
.
totalCPU
;
}
@
computed
(
'
activeAllocation.taskGroupName
'
,
'
scheduledAllocations.@each.{job,taskGroupName}
'
)
@
computed
(
'
activeAllocation.taskGroupName
'
,
'
scheduledAllocations.@each.{job,taskGroupName}
'
)
get
siblingAllocations
()
{
if
(
!
this
.
activeAllocation
)
return
[];
const
taskGroup
=
this
.
activeAllocation
.
taskGroupName
;
const
jobId
=
this
.
activeAllocation
.
belongsTo
(
'
job
'
).
id
();
return
this
.
scheduledAllocations
.
filter
((
allocation
)
=>
{
return
allocation
.
taskGroupName
===
taskGroup
&&
allocation
.
belongsTo
(
'
job
'
).
id
()
===
jobId
;
return
(
allocation
.
taskGroupName
===
taskGroup
&&
allocation
.
belongsTo
(
'
job
'
).
id
()
===
jobId
);
});
}
@
computed
(
'
activeNode
'
)
get
nodeUtilization
()
{
const
node
=
this
.
activeNode
;
const
[
formattedMemory
,
memoryUnits
]
=
reduceBytes
(
node
.
memory
*
1024
*
1024
);
const
totalReservedMemory
=
node
.
allocations
.
mapBy
(
'
memory
'
).
reduce
(
sumAggregator
,
0
);
const
totalReservedCPU
=
node
.
allocations
.
mapBy
(
'
cpu
'
).
reduce
(
sumAggregator
,
0
);
const
[
formattedMemory
,
memoryUnits
]
=
reduceBytes
(
node
.
memory
*
1024
*
1024
);
const
totalReservedMemory
=
node
.
allocations
.
mapBy
(
'
memory
'
)
.
reduce
(
sumAggregator
,
0
);
const
totalReservedCPU
=
node
.
allocations
.
mapBy
(
'
cpu
'
)
.
reduce
(
sumAggregator
,
0
);
return
{
totalMemoryFormatted
:
formattedMemory
.
toFixed
(
2
),
...
...
This diff is collapsed.
Click to expand it.
ui/app/helpers/bind.js
+
4
-
1
View file @
8c600acb
...
...
@@ -9,7 +9,10 @@ import { assert } from '@ember/debug';
* Returns a version of a function bound to the template target (e.g., component or controller)
*/
export
function
bind
([
func
,
target
])
{
assert
(
'
A function is required as the first argument
'
,
typeof
func
===
'
function
'
);
assert
(
'
A function is required as the first argument
'
,
typeof
func
===
'
function
'
);
assert
(
'
A context is required as the second argument
'
,
target
);
return
func
.
bind
(
target
);
}
...
...
This diff is collapsed.
Click to expand it.
ui/app/helpers/is-object.js
+
2
-
1
View file @
8c600acb
import
Helper
from
'
@ember/component/helper
'
;
export
function
isObject
([
value
])
{
const
isObject
=
!
Array
.
isArray
(
value
)
&&
value
!==
null
&&
typeof
value
===
'
object
'
;
const
isObject
=
!
Array
.
isArray
(
value
)
&&
value
!==
null
&&
typeof
value
===
'
object
'
;
return
isObject
;
}
...
...
This diff is collapsed.
Click to expand it.
ui/app/helpers/x-icon.js
+
3
-
1
View file @
8c600acb
...
...
@@ -13,7 +13,9 @@ import SVGs from '../svgs';
*/
export
function
xIcon
(
params
,
options
)
{
const
name
=
params
[
0
];
const
classes
=
[
options
.
class
,
'
icon
'
,
`icon-is-
${
name
}
`
].
compact
().
join
(
'
'
);
const
classes
=
[
options
.
class
,
'
icon
'
,
`icon-is-
${
name
}
`
]
.
compact
()
.
join
(
'
'
);
return
inlineSvg
(
SVGs
,
name
,
{
class
:
classes
});
}
...
...
This diff is collapsed.
Click to expand it.
ui/app/mixins/searchable.js
+
11
-
3
View file @
8c600acb
...
...
@@ -95,7 +95,11 @@ export default Mixin.create({
if
(
this
.
exactMatchEnabled
)
{
results
.
push
(
...
exactMatchSearch
(
searchTerm
,
this
.
listToSearch
,
this
.
exactMatchSearchProps
)
...
exactMatchSearch
(
searchTerm
,
this
.
listToSearch
,
this
.
exactMatchSearchProps
)
);
}
...
...
@@ -114,7 +118,9 @@ export default Mixin.create({
}
if
(
this
.
regexEnabled
)
{
results
.
push
(...
regexSearch
(
searchTerm
,
this
.
listToSearch
,
this
.
regexSearchProps
));
results
.
push
(
...
regexSearch
(
searchTerm
,
this
.
listToSearch
,
this
.
regexSearchProps
)
);
}
return
results
.
uniq
();
...
...
@@ -134,7 +140,9 @@ function regexSearch(term, list, keys) {
const
regex
=
new
RegExp
(
term
,
'
i
'
);
// Test the value of each key for each object against the regex
// All that match are returned.
return
list
.
filter
((
item
)
=>
keys
.
some
((
key
)
=>
regex
.
test
(
get
(
item
,
key
))));
return
list
.
filter
((
item
)
=>
keys
.
some
((
key
)
=>
regex
.
test
(
get
(
item
,
key
)))
);
}
catch
(
e
)
{
// Swallow the error; most likely due to an eager search of an incomplete regex
}
...
...
This diff is collapsed.
Click to expand it.
ui/app/mixins/sortable-factory.js
+
8
-
3
View file @
8c600acb
...
...
@@ -19,7 +19,9 @@ import { warn } from '@ember/debug';
- listSorted: a copy of listToSort that has been sorted
*/
export
default
function
sortableFactory
(
properties
,
fromSortableMixin
)
{
const
eachProperties
=
properties
.
map
((
property
)
=>
`listToSort.@each.
${
property
}
`
);
const
eachProperties
=
properties
.
map
(
(
property
)
=>
`listToSort.@each.
${
property
}
`
);
// eslint-disable-next-line ember/no-new-mixins
return
Mixin
.
create
({
...
...
@@ -44,10 +46,13 @@ export default function sortableFactory(properties, fromSortableMixin) {
'
Using SortableFactory without property keys means the list will only sort when the members change, not when any of their properties change.
'
;
if
(
fromSortableMixin
)
{
message
+=
'
The Sortable mixin is deprecated in favor of SortableFactory.
'
;
message
+=
'
The Sortable mixin is deprecated in favor of SortableFactory.
'
;
}
warn
(
message
,
properties
.
length
>
0
,
{
id
:
'
nomad.no-sortable-properties
'
});
warn
(
message
,
properties
.
length
>
0
,
{
id
:
'
nomad.no-sortable-properties
'
,
});
// eslint-disable-next-line ember/no-side-effects
this
.
set
(
'
_sortableFactoryWarningPrinted
'
,
true
);
}
...
...
This diff is collapsed.
Click to expand it.
ui/app/mixins/window-resizable.js
+
4
-
1
View file @
8c600acb
...
...
@@ -6,7 +6,10 @@ import { on } from '@ember/object/evented';
// eslint-disable-next-line ember/no-new-mixins
export
default
Mixin
.
create
({
windowResizeHandler
()
{
assert
(
'
windowResizeHandler needs to be overridden in the Component
'
,
false
);
assert
(
'
windowResizeHandler needs to be overridden in the Component
'
,
false
);
},
setupWindowResize
:
on
(
'
didInsertElement
'
,
function
()
{
...
...
This diff is collapsed.
Click to expand it.
ui/app/mixins/with-watchers.js
+
4
-
1
View file @
8c600acb
...
...
@@ -36,7 +36,10 @@ export default Mixin.create(WithVisibilityDetection, {
actions
:
{
willTransition
(
transition
)
{
// Don't cancel watchers if transitioning into a sub-route
if
(
!
transition
.
intent
.
name
||
!
transition
.
intent
.
name
.
startsWith
(
this
.
routeName
))
{
if
(
!
transition
.
intent
.
name
||
!
transition
.
intent
.
name
.
startsWith
(
this
.
routeName
)
)
{
this
.
cancelAllWatchers
();
}
...
...
This diff is collapsed.
Click to expand it.
ui/app/models/allocation.js
+
9
-
3
View file @
8c600acb
...
...
@@ -77,8 +77,10 @@ export default class Allocation extends Model {
@
belongsTo
(
'
allocation
'
,
{
inverse
:
'
nextAllocation
'
})
previousAllocation
;
@
belongsTo
(
'
allocation
'
,
{
inverse
:
'
previousAllocation
'
})
nextAllocation
;
@
hasMany
(
'
allocation
'
,
{
inverse
:
'
preemptedByAllocation
'
})
preemptedAllocations
;
@
belongsTo
(
'
allocation
'
,
{
inverse
:
'
preemptedAllocations
'
})
preemptedByAllocation
;
@
hasMany
(
'
allocation
'
,
{
inverse
:
'
preemptedByAllocation
'
})
preemptedAllocations
;
@
belongsTo
(
'
allocation
'
,
{
inverse
:
'
preemptedAllocations
'
})
preemptedByAllocation
;
@
attr
(
'
boolean
'
)
wasPreempted
;
@
belongsTo
(
'
evaluation
'
)
followUpEvaluation
;
...
...
@@ -135,7 +137,11 @@ export default class Allocation extends Model {
return
this
.
get
(
'
rescheduleEvents.length
'
)
>
0
||
this
.
nextAllocation
;
}
@
computed
(
'
clientStatus
'
,
'
followUpEvaluation.content
'
,
'
nextAllocation.content
'
)
@
computed
(
'
clientStatus
'
,
'
followUpEvaluation.content
'
,
'
nextAllocation.content
'
)
get
hasStoppedRescheduling
()
{
return
(
!
this
.
get
(
'
nextAllocation.content
'
)
&&
...
...
This diff is collapsed.
Click to expand it.
ui/app/models/deployment.js
+
12
-
3
View file @
8c600acb
...
...
@@ -24,7 +24,10 @@ export default class Deployment extends Model {
this
.
status
===
'
running
'
&&
this
.
taskGroupSummaries
.
toArray
()
.
some
((
summary
)
=>
summary
.
get
(
'
requiresPromotion
'
)
&&
!
summary
.
get
(
'
promoted
'
))
.
some
(
(
summary
)
=>
summary
.
get
(
'
requiresPromotion
'
)
&&
!
summary
.
get
(
'
promoted
'
)
)
);
}
...
...
@@ -38,7 +41,10 @@ export default class Deployment extends Model {
@
computed
(
'
versionNumber
'
,
'
job.versions.content.@each.number
'
)
get
version
()
{
return
(
this
.
get
(
'
job.versions
'
)
||
[]).
findBy
(
'
number
'
,
this
.
versionNumber
);
return
(
this
.
get
(
'
job.versions
'
)
||
[]).
findBy
(
'
number
'
,
this
.
versionNumber
);
}
// Dependent keys can only go one level past an @each so an alias is needed
...
...
@@ -65,7 +71,10 @@ export default class Deployment extends Model {
}
promote
()
{
assert
(
'
A deployment needs to requirePromotion to be promoted
'
,
this
.
requiresPromotion
);
assert
(
'
A deployment needs to requirePromotion to be promoted
'
,
this
.
requiresPromotion
);
return
this
.
store
.
adapterFor
(
'
deployment
'
).
promote
(
this
);
}
...
...
This diff is collapsed.
Click to expand it.
Prev
1
2
3
4
5
6
7
8
…
15
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment