1<template>
2  <b-container fluid="xl">
3    <page-title />
4    <b-row class="mb-4">
5      <b-col md="12">
6        <page-section
7          :section-title="$t('pageVirtualMedia.virtualMediaSubTitleFirst')"
8        >
9          <b-row>
10            <b-col v-for="(dev, $index) in proxyDevices" :key="$index" md="6">
11              <b-form-group :label="dev.id" label-class="bold">
12                <form-file
13                  v-if="!dev.isActive"
14                  :id="concatId(dev.id)"
15                  v-model="dev.file"
16                >
17                  <template #invalid>
18                    <b-form-invalid-feedback role="alert">
19                      {{ $t('global.form.required') }}
20                    </b-form-invalid-feedback>
21                  </template>
22                </form-file>
23              </b-form-group>
24              <b-button
25                v-if="!dev.isActive"
26                variant="primary"
27                :disabled="!dev.file"
28                @click="startVM(dev)"
29              >
30                {{ $t('pageVirtualMedia.start') }}
31              </b-button>
32              <b-button
33                v-if="dev.isActive"
34                variant="primary"
35                :disabled="!dev.file"
36                @click="stopVM(dev)"
37              >
38                {{ $t('pageVirtualMedia.stop') }}
39              </b-button>
40            </b-col>
41          </b-row>
42        </page-section>
43      </b-col>
44    </b-row>
45    <b-row v-if="loadImageFromExternalServer" class="mb-4">
46      <b-col md="12">
47        <page-section
48          :section-title="$t('pageVirtualMedia.virtualMediaSubTitleSecond')"
49        >
50          <b-row>
51            <b-col
52              v-for="(device, $index) in legacyDevices"
53              :key="$index"
54              md="6"
55            >
56              <b-form-group
57                :label="device.id"
58                :label-for="device.id"
59                label-class="bold"
60              >
61                <b-button
62                  variant="primary"
63                  :disabled="device.isActive"
64                  @click="configureConnection(device)"
65                >
66                  {{ $t('pageVirtualMedia.configureConnection') }}
67                </b-button>
68
69                <b-button
70                  v-if="!device.isActive"
71                  variant="primary"
72                  class="float-right"
73                  :disabled="!device.serverUri"
74                  @click="startLegacy(device)"
75                >
76                  {{ $t('pageVirtualMedia.start') }}
77                </b-button>
78                <b-button
79                  v-if="device.isActive"
80                  variant="primary"
81                  class="float-right"
82                  @click="stopLegacy(device)"
83                >
84                  {{ $t('pageVirtualMedia.stop') }}
85                </b-button>
86              </b-form-group>
87            </b-col>
88          </b-row>
89        </page-section>
90      </b-col>
91    </b-row>
92    <modal-configure-connection
93      :connection="modalConfigureConnection"
94      @ok="saveConnection"
95    />
96  </b-container>
97</template>
98
99<script>
100import PageTitle from '@/components/Global/PageTitle';
101import PageSection from '@/components/Global/PageSection';
102import BVToastMixin from '@/components/Mixins/BVToastMixin';
103import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
104import ModalConfigureConnection from './ModalConfigureConnection';
105import NbdServer from '@/utilities/NBDServer';
106import FormFile from '@/components/Global/FormFile';
107
108export default {
109  name: 'VirtualMedia',
110  components: { PageTitle, PageSection, ModalConfigureConnection, FormFile },
111  mixins: [BVToastMixin, LoadingBarMixin],
112  data() {
113    return {
114      modalConfigureConnection: null,
115      loadImageFromExternalServer:
116        process.env.VUE_APP_VIRTUAL_MEDIA_LIST_ENABLED === 'true'
117          ? true
118          : false,
119    };
120  },
121  computed: {
122    proxyDevices() {
123      return this.$store.getters['virtualMedia/proxyDevices'];
124    },
125    legacyDevices() {
126      return this.$store.getters['virtualMedia/legacyDevices'];
127    },
128  },
129  created() {
130    if (this.proxyDevices.length > 0 || this.legacyDevices.length > 0) return;
131    this.startLoader();
132    this.$store
133      .dispatch('virtualMedia/getData')
134      .finally(() => this.endLoader());
135  },
136  methods: {
137    startVM(device) {
138      const token = this.$store.getters['authentication/token'];
139      device.nbd = new NbdServer(
140        `wss://${window.location.host}${device.websocket}`,
141        device.file,
142        device.id,
143        token
144      );
145      device.nbd.socketStarted = () =>
146        this.successToast(this.$t('pageVirtualMedia.toast.serverRunning'));
147      device.nbd.errorReadingFile = () =>
148        this.errorToast(this.$t('pageVirtualMedia.toast.errorReadingFile'));
149      device.nbd.socketClosed = (code) => {
150        if (code === 1000)
151          this.successToast(
152            this.$t('pageVirtualMedia.toast.serverClosedSuccessfully')
153          );
154        else
155          this.errorToast(
156            this.$t('pageVirtualMedia.toast.serverClosedWithErrors')
157          );
158        device.file = null;
159        device.isActive = false;
160      };
161
162      device.nbd.start();
163      device.isActive = true;
164    },
165    stopVM(device) {
166      device.nbd.stop();
167    },
168    startLegacy(connectionData) {
169      var data = {};
170      data.Image = connectionData.serverUri;
171      data.UserName = connectionData.username;
172      data.Password = connectionData.password;
173      data.WriteProtected = !connectionData.isRW;
174      this.startLoader();
175      this.$store
176        .dispatch('virtualMedia/mountImage', {
177          id: connectionData.id,
178          data: data,
179        })
180        .then(() => {
181          this.successToast(
182            this.$t('pageVirtualMedia.toast.serverConnectionEstablished')
183          );
184          connectionData.isActive = true;
185        })
186        .catch(() => {
187          this.errorToast(this.$t('pageVirtualMedia.toast.errorMounting'));
188          this.isActive = false;
189        })
190        .finally(() => this.endLoader());
191    },
192    stopLegacy(connectionData) {
193      this.$store
194        .dispatch('virtualMedia/unmountImage', connectionData.id)
195        .then(() => {
196          this.successToast(
197            this.$t('pageVirtualMedia.toast.serverClosedSuccessfully')
198          );
199          connectionData.isActive = false;
200        })
201        .catch(() =>
202          this.errorToast(this.$t('pageVirtualMedia.toast.errorUnmounting'))
203        )
204        .finally(() => this.endLoader());
205    },
206    saveConnection(connectionData) {
207      this.modalConfigureConnection.serverUri = connectionData.serverUri;
208      this.modalConfigureConnection.username = connectionData.username;
209      this.modalConfigureConnection.password = connectionData.password;
210      this.modalConfigureConnection.isRW = connectionData.isRW;
211    },
212    configureConnection(connectionData) {
213      this.modalConfigureConnection = connectionData;
214      this.$bvModal.show('configure-connection');
215    },
216    concatId(val) {
217      return val.split(' ').join('_').toLowerCase();
218    },
219  },
220};
221</script>
222