You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2020/08/04 22:26:06 UTC
[airavata-django-portal] 01/02: AIRAVATA-3330 Refactor UI component
and require at least one queue
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
commit b392b987f93ef05d027f581cf9dde622921df936
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Tue Aug 4 17:53:23 2020 -0400
AIRAVATA-3330 Refactor UI component and require at least one queue
---
.../BatchQueueResourcePolicy.vue | 14 +-
.../ComputePreference.vue | 135 +++-----------
.../ComputeResourcePolicyEditor.vue | 197 +++++++++++++++++++++
.../js/models/ComputeResourcePolicy.js | 38 ++--
4 files changed, 251 insertions(+), 133 deletions(-)
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/BatchQueueResourcePolicy.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/BatchQueueResourcePolicy.vue
index 1a3dc11..7a06851 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/BatchQueueResourcePolicy.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/BatchQueueResourcePolicy.vue
@@ -16,7 +16,7 @@
:max="batchQueue.maxNodes"
:formatter="numberFormatter"
:placeholder="'Max Nodes: ' + batchQueue.maxNodes"
- :state="validationFeedback.maxAllowedNodes.state"
+ :state="validationFeedback.maxAllowedNodes.state"
>
</b-form-input>
</b-form-group>
@@ -37,7 +37,7 @@
:max="batchQueue.maxProcessors"
:formatter="numberFormatter"
:placeholder="'Max Cores: ' + batchQueue.maxProcessors"
- :state="validationFeedback.maxAllowedCores.state"
+ :state="validationFeedback.maxAllowedCores.state"
>
</b-form-input>
</b-form-group>
@@ -46,7 +46,9 @@
<b-form-group
label="Maximum Allowed Wall Time"
label-for="max-allowed-walltime"
- :invalid-feedback="validationFeedback.maxAllowedWalltime.invalidFeedback"
+ :invalid-feedback="
+ validationFeedback.maxAllowedWalltime.invalidFeedback
+ "
:state="validationFeedback.maxAllowedWalltime.state"
>
<b-form-input
@@ -58,7 +60,7 @@
:max="batchQueue.maxRunTime"
:formatter="numberFormatter"
:placeholder="'Max Wall Time: ' + batchQueue.maxRunTime"
- :state="validationFeedback.maxAllowedWalltime.state"
+ :state="validationFeedback.maxAllowedWalltime.state"
>
</b-form-input>
</b-form-group>
@@ -113,9 +115,9 @@ export default {
},
validate() {
if (this.valid) {
- this.$emit('valid');
+ this.$emit("valid");
} else {
- this.$emit('invalid');
+ this.$emit("invalid");
}
}
},
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue
index 013370b..7c3b38c 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue
@@ -104,42 +104,19 @@
<div class="card">
<div class="card-body">
<h5 class="card-title">Policy</h5>
- <b-form-group
- label="Allowed Queues"
- v-if="localComputeResourcePolicy"
- >
- <div
- v-for="batchQueue in computeResource.batchQueues"
- :key="batchQueue.queueName"
- >
- <b-form-checkbox
- :checked="
- localComputeResourcePolicy.allowedBatchQueues.includes(
- batchQueue.queueName
- )
- "
- @input="batchQueueChecked(batchQueue, $event)"
- >
- {{ batchQueue.queueName }}
- </b-form-checkbox>
- <batch-queue-resource-policy
- v-if="
- localComputeResourcePolicy.allowedBatchQueues.includes(
- batchQueue.queueName
- )
- "
- :batch-queue="batchQueue"
- :value="
- localBatchQueueResourcePolicies.find(
- pol => pol.queuename === batchQueue.queueName
- )
- "
- @input="updatedBatchQueueResourcePolicy(batchQueue, $event)"
- @valid="recordValidBatchQueueResourcePolicy(batchQueue)"
- @invalid="recordInvalidBatchQueueResourcePolicy(batchQueue)"
- />
- </div>
- </b-form-group>
+ <compute-resource-policy-editor
+ :batch-queues="computeResource.batchQueues"
+ :compute-resource-policy="localComputeResourcePolicy"
+ :batch-queue-resource-policies="localBatchQueueResourcePolicies"
+ @compute-resource-policy-updated="
+ localComputeResourcePolicy = $event
+ "
+ @batch-queue-resource-policies-updated="
+ localBatchQueueResourcePolicies = $event
+ "
+ @valid="computeResourcePolicyInvalid = false"
+ @invalid="computeResourcePolicyInvalid = true"
+ />
</div>
</div>
</div>
@@ -179,9 +156,9 @@
<script>
import DjangoAiravataAPI from "django-airavata-api";
-import BatchQueueResourcePolicy from "./BatchQueueResourcePolicy.vue";
import SSHCredentialSelector from "../../credentials/SSHCredentialSelector.vue";
import ComputeResourceReservationList from "./ComputeResourceReservationList";
+import ComputeResourcePolicyEditor from "./ComputeResourcePolicyEditor";
import { models, services, errors } from "django-airavata-api";
import {
@@ -194,10 +171,10 @@ import {
export default {
name: "compute-preference",
components: {
- BatchQueueResourcePolicy,
"delete-button": components.DeleteButton,
"ssh-credential-selector": SSHCredentialSelector,
- ComputeResourceReservationList
+ ComputeResourceReservationList,
+ ComputeResourcePolicyEditor
},
props: {
id: {
@@ -268,8 +245,8 @@ export default {
jobSubmissionInterfaces: []
},
validationErrors: null,
- invalidBatchQueueResourcePolicies: [],
- reservationsInvalid: false
+ reservationsInvalid: false,
+ computeResourcePolicyInvalid: false
};
},
computed: {
@@ -284,14 +261,9 @@ export default {
},
valid() {
return (
- this.allowedInvalidBatchQueueResourcePolicies.length === 0 &&
Object.keys(this.groupComputeResourceValidation).length === 0 &&
- !this.reservationsInvalid
- );
- },
- allowedInvalidBatchQueueResourcePolicies() {
- return this.invalidBatchQueueResourcePolicies.filter(queueName =>
- this.localComputeResourcePolicy.allowedBatchQueues.includes(queueName)
+ !this.reservationsInvalid &&
+ !this.computeResourcePolicyInvalid
);
},
queueNames() {
@@ -300,54 +272,6 @@ export default {
},
mixins: [mixins.VModelMixin],
methods: {
- batchQueueChecked: function(batchQueue, checked) {
- if (checked) {
- this.localComputeResourcePolicy.allowedBatchQueues.push(
- batchQueue.queueName
- );
- } else {
- const queueIndex = this.localComputeResourcePolicy.allowedBatchQueues.indexOf(
- batchQueue.queueName
- );
- this.localComputeResourcePolicy.allowedBatchQueues.splice(
- queueIndex,
- 1
- );
- // Remove batchQueueResourcePolicy if it exists
- const policyIndex = this.localBatchQueueResourcePolicies.findIndex(
- pol => pol.queuename === batchQueue.queueName
- );
- if (policyIndex >= 0) {
- this.localBatchQueueResourcePolicies.splice(policyIndex, 1);
- }
- }
- },
- updatedBatchQueueResourcePolicy: function(
- batchQueue,
- batchQueueResourcePolicy
- ) {
- const queueName = batchQueue.queueName;
- if (batchQueueResourcePolicy) {
- const existingPolicy = this.localBatchQueueResourcePolicies.find(
- pol => pol.queuename === queueName
- );
- if (existingPolicy) {
- Object.assign(existingPolicy, batchQueueResourcePolicy);
- } else {
- // For new BatchQueueResourcePolicy instances, set the parent ids
- batchQueueResourcePolicy.groupResourceProfileId = this.id;
- batchQueueResourcePolicy.computeResourceId = this.host_id;
- this.localBatchQueueResourcePolicies.push(batchQueueResourcePolicy);
- }
- } else {
- const existingPolicyIndex = this.localBatchQueueResourcePolicies.findIndex(
- pol => pol.queuename === queueName
- );
- if (existingPolicyIndex >= 0) {
- this.localBatchQueueResourcePolicies.splice(existingPolicyIndex, 1);
- }
- }
- },
fetchComputeResource: function(id) {
return DjangoAiravataAPI.utils.FetchUtils.get(
"/api/compute-resources/" + encodeURIComponent(id) + "/"
@@ -452,25 +376,6 @@ export default {
this.localComputeResourcePolicy = defaultComputeResourcePolicy;
});
},
- recordValidBatchQueueResourcePolicy(batchQueue) {
- if (
- this.invalidBatchQueueResourcePolicies.includes(batchQueue.queueName)
- ) {
- const index = this.invalidBatchQueueResourcePolicies.indexOf(
- batchQueue.queueName
- );
- this.invalidBatchQueueResourcePolicies.splice(index, 1);
- }
- this.validate(); // propagate validation
- },
- recordInvalidBatchQueueResourcePolicy(batchQueue) {
- if (
- !this.invalidBatchQueueResourcePolicies.includes(batchQueue.queueName)
- ) {
- this.invalidBatchQueueResourcePolicies.push(batchQueue.queueName);
- }
- this.validate(); // propagate validation
- },
validate() {
if (this.valid) {
this.$emit("valid");
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputeResourcePolicyEditor.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputeResourcePolicyEditor.vue
new file mode 100644
index 0000000..3f61d08
--- /dev/null
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputeResourcePolicyEditor.vue
@@ -0,0 +1,197 @@
+<template>
+ <b-form-group
+ label="Allowed Queues"
+ v-if="localComputeResourcePolicy"
+ :invalid-feedback="validationFeedback.allowedBatchQueues.invalidFeedback"
+ :state="validationFeedback.allowedBatchQueues.state"
+ >
+ <div v-for="batchQueue in batchQueues" :key="batchQueue.queueName">
+ <b-form-checkbox
+ :checked="
+ localComputeResourcePolicy.allowedBatchQueues.includes(
+ batchQueue.queueName
+ )
+ "
+ @input="batchQueueChecked(batchQueue, $event)"
+ >
+ {{ batchQueue.queueName }}
+ </b-form-checkbox>
+ <batch-queue-resource-policy
+ v-if="
+ localComputeResourcePolicy.allowedBatchQueues.includes(
+ batchQueue.queueName
+ )
+ "
+ :batch-queue="batchQueue"
+ :value="
+ localBatchQueueResourcePolicies.find(
+ pol => pol.queuename === batchQueue.queueName
+ )
+ "
+ @input="updatedBatchQueueResourcePolicy(batchQueue, $event)"
+ @valid="recordValidBatchQueueResourcePolicy(batchQueue)"
+ @invalid="recordInvalidBatchQueueResourcePolicy(batchQueue)"
+ />
+ </div>
+ </b-form-group>
+</template>
+
+<script>
+import BatchQueueResourcePolicy from "./BatchQueueResourcePolicy.vue";
+
+import { models } from "django-airavata-api";
+import { errors } from "django-airavata-common-ui";
+
+export default {
+ name: "compute-resource-policy-editor",
+ props: {
+ batchQueues: {
+ type: Array
+ },
+ computeResourcePolicy: {
+ type: models.ComputeResourcePolicy
+ },
+ batchQueueResourcePolicies: {
+ type: Array
+ }
+ },
+ components: {
+ BatchQueueResourcePolicy
+ },
+ data: function() {
+ return {
+ localComputeResourcePolicy: this.computeResourcePolicy
+ ? this.computeResourcePolicy.clone()
+ : null,
+ localBatchQueueResourcePolicies: this.batchQueueResourcePolicies
+ ? this.batchQueueResourcePolicies.map(pol => pol.clone())
+ : [],
+ validationErrors: null,
+ invalidBatchQueueResourcePolicies: []
+ };
+ },
+ computed: {
+ computeResourcePolicyValidation() {
+ return this.localComputeResourcePolicy.validate();
+ },
+ validationFeedback() {
+ return errors.ValidationErrors.createValidationFeedback(
+ this.localComputeResourcePolicy,
+ this.computeResourcePolicyValidation
+ );
+ },
+ valid() {
+ return (
+ this.allowedInvalidBatchQueueResourcePolicies.length === 0 &&
+ Object.keys(this.computeResourcePolicyValidation).length === 0
+ );
+ },
+ allowedInvalidBatchQueueResourcePolicies() {
+ return this.invalidBatchQueueResourcePolicies.filter(queueName =>
+ this.localComputeResourcePolicy.allowedBatchQueues.includes(queueName)
+ );
+ }
+ },
+ methods: {
+ batchQueueChecked: function(batchQueue, checked) {
+ if (checked) {
+ this.localComputeResourcePolicy.allowedBatchQueues.push(
+ batchQueue.queueName
+ );
+ } else {
+ const queueIndex = this.localComputeResourcePolicy.allowedBatchQueues.indexOf(
+ batchQueue.queueName
+ );
+ this.localComputeResourcePolicy.allowedBatchQueues.splice(
+ queueIndex,
+ 1
+ );
+ // Remove batchQueueResourcePolicy if it exists
+ const policyIndex = this.localBatchQueueResourcePolicies.findIndex(
+ pol => pol.queuename === batchQueue.queueName
+ );
+ if (policyIndex >= 0) {
+ this.localBatchQueueResourcePolicies.splice(policyIndex, 1);
+ }
+ this.$emit(
+ "batch-queue-resource-policies-updated",
+ this.localBatchQueueResourcePolicies
+ );
+ }
+ this.validate();
+ this.$emit(
+ "compute-resource-policy-updated",
+ this.localComputeResourcePolicy
+ );
+ },
+ updatedBatchQueueResourcePolicy: function(
+ batchQueue,
+ batchQueueResourcePolicy
+ ) {
+ const queueName = batchQueue.queueName;
+ if (batchQueueResourcePolicy) {
+ const existingPolicy = this.localBatchQueueResourcePolicies.find(
+ pol => pol.queuename === queueName
+ );
+ if (existingPolicy) {
+ Object.assign(existingPolicy, batchQueueResourcePolicy);
+ } else {
+ this.localComputeResourcePolicy.populateParentIdsOnBatchQueueResourcePolicy(
+ batchQueueResourcePolicy
+ );
+ this.localBatchQueueResourcePolicies.push(batchQueueResourcePolicy);
+ }
+ } else {
+ const existingPolicyIndex = this.localBatchQueueResourcePolicies.findIndex(
+ pol => pol.queuename === queueName
+ );
+ if (existingPolicyIndex >= 0) {
+ this.localBatchQueueResourcePolicies.splice(existingPolicyIndex, 1);
+ }
+ }
+ this.$emit(
+ "batch-queue-resource-policies-updated",
+ this.localBatchQueueResourcePolicies
+ );
+ },
+ recordValidBatchQueueResourcePolicy(batchQueue) {
+ if (
+ this.invalidBatchQueueResourcePolicies.includes(batchQueue.queueName)
+ ) {
+ const index = this.invalidBatchQueueResourcePolicies.indexOf(
+ batchQueue.queueName
+ );
+ this.invalidBatchQueueResourcePolicies.splice(index, 1);
+ }
+ this.validate(); // propagate validation
+ },
+ recordInvalidBatchQueueResourcePolicy(batchQueue) {
+ if (
+ !this.invalidBatchQueueResourcePolicies.includes(batchQueue.queueName)
+ ) {
+ this.invalidBatchQueueResourcePolicies.push(batchQueue.queueName);
+ }
+ this.validate(); // propagate validation
+ },
+ validate() {
+ if (this.valid) {
+ this.$emit("valid");
+ } else {
+ this.$emit("invalid");
+ }
+ }
+ },
+ watch: {
+ computeResourcePolicy(value) {
+ this.localComputeResourcePolicy = value.clone();
+ },
+ batchQueueResourcePolicies(value) {
+ this.localBatchQueueResourcePolicies = value
+ ? value.map(p => p.clone())
+ : [];
+ }
+ }
+};
+</script>
+
+<style></style>
diff --git a/django_airavata/apps/api/static/django_airavata_api/js/models/ComputeResourcePolicy.js b/django_airavata/apps/api/static/django_airavata_api/js/models/ComputeResourcePolicy.js
index 82b97d5..b40d6a0 100644
--- a/django_airavata/apps/api/static/django_airavata_api/js/models/ComputeResourcePolicy.js
+++ b/django_airavata/apps/api/static/django_airavata_api/js/models/ComputeResourcePolicy.js
@@ -1,20 +1,34 @@
-import BaseModel from './BaseModel'
-
+import BaseModel from "./BaseModel";
const FIELDS = [
- 'resourcePolicyId',
- 'computeResourceId',
- 'groupResourceProfileId',
- {
- name: 'allowedBatchQueues',
- type: 'string',
- list: true
- }
+ "resourcePolicyId",
+ "computeResourceId",
+ "groupResourceProfileId",
+ {
+ name: "allowedBatchQueues",
+ type: "string",
+ list: true,
+ },
];
export default class ComputeResourcePolicy extends BaseModel {
+ constructor(data = {}) {
+ super(FIELDS, data);
+ }
+
+ populateParentIdsOnBatchQueueResourcePolicy(batchQueueResourcePolicy) {
+ // For new BatchQueueResourcePolicy instances, set the parent ids
+ batchQueueResourcePolicy.groupResourceProfileId = this.groupResourceProfileId;
+ batchQueueResourcePolicy.computeResourceId = this.computeResourceId;
+ return batchQueueResourcePolicy;
+ }
- constructor(data = {}) {
- super(FIELDS, data);
+ validate() {
+ let validationResults = {};
+ if (!this.allowedBatchQueues || this.allowedBatchQueues.length === 0) {
+ validationResults["allowedBatchQueues"] =
+ "Must select at least one queue.";
}
+ return validationResults;
+ }
}