summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/locales/en-US.json12
-rw-r--r--src/store/modules/Control/VirtualMediaStore.js33
-rw-r--r--src/views/Control/VirtualMedia/ModalConfigureConnection.vue142
-rw-r--r--src/views/Control/VirtualMedia/VirtualMedia.vue81
4 files changed, 253 insertions, 15 deletions
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index 85e2a3aa..f3eb3e2f 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -636,11 +636,21 @@
},
"pageVirtualMedia": {
"configureConnection": "Configure Connection",
+ "defaultDeviceName": "Virtual media device",
+ "start": "Start",
+ "stop": "Stop",
"virtualMediaSubTitleFirst": "Save image in a web browser",
"virtualMediaSubTitleSecond": "Load image from external server",
- "defaultDeviceName": "Virtual media device",
+ "modal": {
+ "password": "Password",
+ "serverUri": "External server URI",
+ "title": "Legacy mode configuration",
+ "username": "Username"
+ },
"toast": {
+ "errorMounting": "Error mounting",
"errorReadingFile": "Error reading file. Closing server.",
+ "errorUnmounting": "Error unmounting",
"serverRunning": "Server running",
"serverClosedSuccessfully": "Server closed successfully",
"serverClosedWithErrors": "Server closed with errors"
diff --git a/src/store/modules/Control/VirtualMediaStore.js b/src/store/modules/Control/VirtualMediaStore.js
index e01cfce1..13ef8ee6 100644
--- a/src/store/modules/Control/VirtualMediaStore.js
+++ b/src/store/modules/Control/VirtualMediaStore.js
@@ -44,10 +44,12 @@ const VirtualMediaStore = {
.then(devices => api.all(devices.map(device => api.get(device))))
.then(devices => {
const deviceData = devices.map(device => {
+ const isActive = device.data?.Inserted === true ? true : false;
return {
id: device.data?.Id,
transferProtocolType: device.data?.TransferProtocolType,
- websocket: device.data?.Oem?.OpenBMC?.WebSocketEndpoint
+ websocket: device.data?.Oem?.OpenBMC?.WebSocketEndpoint,
+ isActive: isActive
};
});
const proxyDevices = deviceData
@@ -55,8 +57,7 @@ const VirtualMediaStore = {
.map(device => {
return {
...device,
- file: null,
- isActive: false
+ file: null
};
});
const legacyDevices = deviceData
@@ -64,7 +65,10 @@ const VirtualMediaStore = {
.map(device => {
return {
...device,
- address: ''
+ serverUri: '',
+ username: '',
+ password: '',
+ isRW: false
};
});
commit('setProxyDevicesData', proxyDevices);
@@ -73,6 +77,27 @@ const VirtualMediaStore = {
.catch(error => {
console.log('Virtual Media:', error);
});
+ },
+ async mountImage(_, { id, data }) {
+ return await api
+ .post(
+ `/redfish/v1/Managers/bmc/VirtualMedia/${id}/Actions/VirtualMedia.InsertMedia`,
+ data
+ )
+ .catch(error => {
+ console.log('Mount image:', error);
+ throw new Error();
+ });
+ },
+ async unmountImage(_, id) {
+ return await api
+ .post(
+ `/redfish/v1/Managers/bmc/VirtualMedia/${id}/Actions/VirtualMedia.EjectMedia`
+ )
+ .catch(error => {
+ console.log('Unmount image:', error);
+ throw new Error();
+ });
}
}
};
diff --git a/src/views/Control/VirtualMedia/ModalConfigureConnection.vue b/src/views/Control/VirtualMedia/ModalConfigureConnection.vue
new file mode 100644
index 00000000..4401a04f
--- /dev/null
+++ b/src/views/Control/VirtualMedia/ModalConfigureConnection.vue
@@ -0,0 +1,142 @@
+<template>
+ <b-modal
+ id="configure-connection"
+ ref="modal"
+ @ok="onOk"
+ @hidden="resetForm"
+ @show="initModal"
+ >
+ <template v-slot:modal-title>
+ {{ $t('pageVirtualMedia.modal.title') }}
+ </template>
+ <b-form>
+ <b-form-group
+ :label="$t('pageVirtualMedia.modal.serverUri')"
+ label-for="serverUri"
+ >
+ <b-form-input
+ id="serverUri"
+ v-model="form.serverUri"
+ type="text"
+ :state="getValidationState($v.form.serverUri)"
+ data-test-id="configureConnection-input-serverUri"
+ @input="$v.form.serverUri.$touch()"
+ />
+ <b-form-invalid-feedback role="alert">
+ <template v-if="!$v.form.serverUri.required">
+ {{ $t('global.form.fieldRequired') }}
+ </template>
+ </b-form-invalid-feedback>
+ </b-form-group>
+ <b-form-group
+ :label="$t('pageVirtualMedia.modal.username')"
+ label-for="username"
+ >
+ <b-form-input
+ id="username"
+ v-model="form.username"
+ type="text"
+ data-test-id="configureConnection-input-username"
+ />
+ </b-form-group>
+ <b-form-group
+ :label="$t('pageVirtualMedia.modal.password')"
+ label-for="password"
+ >
+ <b-form-input
+ id="password"
+ v-model="form.password"
+ type="password"
+ data-test-id="configureConnection-input-password"
+ />
+ </b-form-group>
+ <b-form-group>
+ <b-form-checkbox
+ v-model="form.isRW"
+ data-test-id="configureConnection-input-isRW"
+ name="check-button"
+ >
+ RW
+ </b-form-checkbox>
+ </b-form-group>
+ </b-form>
+ <template v-slot:modal-ok>
+ {{ $t('global.action.save') }}
+ </template>
+ </b-modal>
+</template>
+
+<script>
+import { required } from 'vuelidate/lib/validators';
+import VuelidateMixin from '../../../components/Mixins/VuelidateMixin.js';
+
+export default {
+ mixins: [VuelidateMixin],
+ props: {
+ connection: {
+ type: Object,
+ default: null,
+ validator: prop => {
+ console.log(prop);
+ return true;
+ }
+ }
+ },
+ data() {
+ return {
+ form: {
+ serverUri: null,
+ username: null,
+ password: null,
+ isRW: false
+ }
+ };
+ },
+ watch: {
+ connection: function(value) {
+ if (value === null) return;
+ Object.assign(this.form, value);
+ }
+ },
+ validations() {
+ return {
+ form: {
+ serverUri: {
+ required
+ }
+ }
+ };
+ },
+ methods: {
+ handleSubmit() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+ let connectionData = {};
+ Object.assign(connectionData, this.form);
+ this.$emit('ok', connectionData);
+ this.closeModal();
+ },
+ initModal() {
+ if (this.connection) {
+ Object.assign(this.form, this.connection);
+ }
+ },
+ closeModal() {
+ this.$nextTick(() => {
+ this.$refs.modal.hide();
+ });
+ },
+ resetForm() {
+ this.form.serverUri = null;
+ this.form.username = null;
+ this.form.password = null;
+ this.form.isRW = false;
+ this.$v.$reset();
+ },
+ onOk(bvModalEvt) {
+ bvModalEvt.preventDefault();
+ this.handleSubmit();
+ }
+ }
+};
+</script>
diff --git a/src/views/Control/VirtualMedia/VirtualMedia.vue b/src/views/Control/VirtualMedia/VirtualMedia.vue
index a9a575d5..5460eb46 100644
--- a/src/views/Control/VirtualMedia/VirtualMedia.vue
+++ b/src/views/Control/VirtualMedia/VirtualMedia.vue
@@ -26,7 +26,7 @@
:disabled="!dev.file"
@click="startVM(dev)"
>
- {{ 'Start' }}
+ {{ $t('pageVirtualMedia.start') }}
</b-button>
<b-button
v-if="dev.isActive"
@@ -34,7 +34,7 @@
:disabled="!dev.file"
@click="stopVM(dev)"
>
- {{ 'Stop' }}
+ {{ $t('pageVirtualMedia.stop') }}
</b-button>
</b-col>
</b-row>
@@ -57,17 +57,30 @@
:label-for="device.id"
label-class="bold"
>
- <b-button variant="primary" @click="configureConnection()">
+ <b-button
+ variant="primary"
+ :disabled="device.isActive"
+ @click="configureConnection(device)"
+ >
{{ $t('pageVirtualMedia.configureConnection') }}
</b-button>
<b-button
+ v-if="!device.isActive"
variant="primary"
class="float-right"
- :disabled="!device.address"
+ :disabled="!device.serverUri"
@click="startLegacy(device)"
>
- {{ 'Start' }}
+ {{ $t('pageVirtualMedia.start') }}
+ </b-button>
+ <b-button
+ v-if="device.isActive"
+ variant="primary"
+ class="float-right"
+ @click="stopLegacy(device)"
+ >
+ {{ $t('pageVirtualMedia.stop') }}
</b-button>
</b-form-group>
</b-col>
@@ -75,6 +88,10 @@
</page-section>
</b-col>
</b-row>
+ <modal-configure-connection
+ :connection="modalConfigureConnection"
+ @ok="saveConnection"
+ />
</b-container>
</template>
@@ -83,14 +100,16 @@ import PageTitle from '@/components/Global/PageTitle';
import PageSection from '@/components/Global/PageSection';
import BVToastMixin from '@/components/Mixins/BVToastMixin';
import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import ModalConfigureConnection from './ModalConfigureConnection';
import NbdServer from '@/utilities/NBDServer';
export default {
name: 'VirtualMedia',
- components: { PageTitle, PageSection },
+ components: { PageTitle, PageSection, ModalConfigureConnection },
mixins: [BVToastMixin, LoadingBarMixin],
data() {
return {
+ modalConfigureConnection: null,
loadImageFromExternalServer:
process.env.VUE_APP_VIRTUAL_MEDIA_LIST_ENABLED === 'true' ? true : false
};
@@ -142,11 +161,53 @@ export default {
stopVM(device) {
device.nbd.stop();
},
- startLegacy() {
- console.log('starting legacy...');
+ startLegacy(connectionData) {
+ var data = {};
+ data.Image = connectionData.serverUri;
+ data.UserName = connectionData.username;
+ data.Password = connectionData.password;
+ data.WriteProtected = connectionData.isRW;
+ this.startLoader();
+ this.$store
+ .dispatch('virtualMedia/mountImage', {
+ id: connectionData.id,
+ data: data
+ })
+ .then(() => {
+ this.successToast(
+ this.$t('pageVirtualMedia.toast.serverClosedSuccessfully')
+ );
+ connectionData.isActive = true;
+ })
+ .catch(() => {
+ this.errorToast(this.$t('pageVirtualMedia.toast.errorMounting'));
+ this.isActive = false;
+ })
+ .finally(() => this.endLoader());
+ },
+ stopLegacy(connectionData) {
+ this.$store
+ .dispatch('virtualMedia/unmountImage', connectionData.id)
+ .then(() => {
+ this.successToast(
+ this.$t('pageVirtualMedia.toast.serverClosedSuccessfully')
+ );
+ connectionData.isActive = false;
+ })
+ .catch(() =>
+ this.errorToast(this.$t('pageVirtualMedia.toast.errorUnmounting'))
+ )
+ .finally(() => this.endLoader());
+ },
+ saveConnection(connectionData) {
+ this.modalConfigureConnection.serverUri = connectionData.serverUri;
+ this.modalConfigureConnection.username = connectionData.username;
+ this.modalConfigureConnection.password = connectionData.password;
+ this.modalConfigureConnection.isRW = connectionData.isRW;
},
- configureConnection() {
- this.warningToast('This option is unavialable. We are working on it.');
+ configureConnection(connectionData) {
+ this.modalConfigureConnection = connectionData;
+ this.$bvModal.show('configure-connection');
}
}
};