|
|
|
<template>
|
|
|
|
<card class="card-user" style="max-height:100%">
|
|
|
|
<div class="author">
|
|
|
|
<img class="avatar border-white" src="@/assets/img/docker.png" alt="...">
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<b-container fluid class="bv-example-row">
|
|
|
|
<div class="row text-center">
|
|
|
|
<div class="col-12">
|
|
|
|
<b>Swarmlab hybrid Deploy</b>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<br>
|
|
|
|
<b-row>
|
|
|
|
<b-col cols="8">
|
|
|
|
<ValidationProvider
|
|
|
|
ref="hybrid_image"
|
|
|
|
name="Image"
|
|
|
|
rules="required|alpha_num_image"
|
|
|
|
v-slot="{ errors, ariaMsg, ariaInput, valid, invalid }"
|
|
|
|
>
|
|
|
|
<div class="input-group input-group-sm sm-3">
|
|
|
|
<input type="text"
|
|
|
|
class="form-control"
|
|
|
|
v-bind:class="{'is-valid': isDeployValid.image == 1, 'is-invalid': isDeployValid.image == 2}"
|
|
|
|
name="Image"
|
|
|
|
aria-label="Small"
|
|
|
|
aria-describedby="inputGroup-sizing-sm"
|
|
|
|
placeholder="Image"
|
|
|
|
v-model="deploy.image"
|
|
|
|
v-on:keyup="isValid('image')"
|
|
|
|
>
|
|
|
|
<div class="input-group-append">
|
|
|
|
<button
|
|
|
|
class="ti-info btn btn-outline-secondary"
|
|
|
|
round
|
|
|
|
type="button"
|
|
|
|
@click="showInfo('image')"
|
|
|
|
>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span class="hybrid-field-error">{{ errors[0] }}</span>
|
|
|
|
</ValidationProvider>
|
|
|
|
</b-col>
|
|
|
|
|
|
|
|
<b-col cols="4">
|
|
|
|
<ValidationProvider
|
|
|
|
ref="hybrid_stackname"
|
|
|
|
name="StackName"
|
|
|
|
rules="required|alpha_num_name"
|
|
|
|
v-slot="{ errors, ariaMsg, ariaInput, valid, invalid }"
|
|
|
|
>
|
|
|
|
<div class="input-group input-group-sm sm-3">
|
|
|
|
<input type="text"
|
|
|
|
name="StackName"
|
|
|
|
class="form-control"
|
|
|
|
v-bind:class="{'is-valid': isDeployValid.stackname == 1, 'is-invalid': isDeployValid.stackname == 2}"
|
|
|
|
aria-label="Small"
|
|
|
|
aria-describedby="inputGroup-sizing-sm"
|
|
|
|
placeholder="StackName"
|
|
|
|
v-model="deploy.stackname"
|
|
|
|
v-on:keyup="isValid('stackname')"
|
|
|
|
>
|
|
|
|
<div class="input-group-append">
|
|
|
|
<button
|
|
|
|
class="ti-info btn btn-outline-secondary"
|
|
|
|
round
|
|
|
|
type="button"
|
|
|
|
@click="showInfo('stackname')">
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span class="hybrid-field-error">{{ errors[0] }}</span>
|
|
|
|
</ValidationProvider>
|
|
|
|
</b-col>
|
|
|
|
|
|
|
|
</b-row>
|
|
|
|
<b-row>
|
|
|
|
<b-col cols="8">
|
|
|
|
<ValidationProvider
|
|
|
|
ref="hybrid_name"
|
|
|
|
name="Name"
|
|
|
|
rules="required|alpha_num_name"
|
|
|
|
v-slot="{ errors, ariaMsg, ariaInput, valid, invalid }"
|
|
|
|
>
|
|
|
|
<div class="input-group input-group-sm sm-3">
|
|
|
|
<input type=HybridError
|
|
|
|
name="Name"
|
|
|
|
class="form-control"
|
|
|
|
v-bind:class="{'is-valid': isDeployValid.name == 1, 'is-invalid': isDeployValid.name == 2}"
|
|
|
|
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
|
|
|
|
placeholder="Name"
|
|
|
|
v-model="deploy.name"
|
|
|
|
v-on:keyup="isValid('name')"
|
|
|
|
>
|
|
|
|
<div class="input-group-append">
|
|
|
|
<button
|
|
|
|
class="ti-info btn btn-outline-secondary"
|
|
|
|
round
|
|
|
|
type="button"
|
|
|
|
@click="showInfo('name')">
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span class="hybrid-field-error">{{ errors[0] }}</span>
|
|
|
|
</ValidationProvider>
|
|
|
|
</b-col>
|
|
|
|
<b-col cols="4">
|
|
|
|
<ValidationProvider
|
|
|
|
ref="hybrid_network"
|
|
|
|
name="Network"
|
|
|
|
rules="required|alpha_num_name"
|
|
|
|
v-slot="{ errors, ariaMsg, ariaInput, valid, invalid }"
|
|
|
|
>
|
|
|
|
<div class="input-group input-group-sm sm-3">
|
|
|
|
<input type="text"
|
|
|
|
name="Network"
|
|
|
|
class="form-control"
|
|
|
|
v-bind:class="{'is-valid': isDeployValid.network == 1, 'is-invalid': isDeployValid.network == 2}"
|
|
|
|
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
|
|
|
|
placeholder="Network Name"
|
|
|
|
v-model="deploy.network"
|
|
|
|
v-on:keyup="isValid('network')"
|
|
|
|
>
|
|
|
|
<div class="input-group-append">
|
|
|
|
<button
|
|
|
|
class="ti-info btn btn-outline-secondary"
|
|
|
|
round
|
|
|
|
type="button"
|
|
|
|
@click="showInfo('network')">
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span class="hybrid-field-error">{{ errors[0] }}</span>
|
|
|
|
</ValidationProvider>
|
|
|
|
</b-col>
|
|
|
|
</b-row>
|
|
|
|
|
|
|
|
<b-row>
|
|
|
|
<b-col cols="4">
|
|
|
|
<ValidationProvider
|
|
|
|
ref="hybrid_cpu"
|
|
|
|
name="Cpu"
|
|
|
|
rules="required|alpha_num_cpu"
|
|
|
|
v-slot="{ errors, ariaMsg, ariaInput, valid, invalid }"
|
|
|
|
>
|
|
|
|
<div class="input-group input-group-sm sm-3">
|
|
|
|
<input type="text"
|
|
|
|
name="Cpu"
|
|
|
|
class="form-control"
|
|
|
|
v-bind:class="{'is-valid': isDeployValid.cpu == 1, 'is-invalid': isDeployValid.cpu == 2}"
|
|
|
|
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
|
|
|
|
placeholder="Limit CPU e.g. 0.50"
|
|
|
|
v-model="deploy.cpu"
|
|
|
|
v-on:keyup="isValid('cpu')"
|
|
|
|
>
|
|
|
|
<div class="input-group-append">
|
|
|
|
<button
|
|
|
|
class="ti-info btn btn-outline-secondary"
|
|
|
|
round
|
|
|
|
type="button"
|
|
|
|
@click="showInfo('cpu')"
|
|
|
|
>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span class="hybrid-field-error">{{ errors[0] }}</span>
|
|
|
|
</ValidationProvider>
|
|
|
|
</b-col>
|
|
|
|
<b-col cols="4">
|
|
|
|
<ValidationProvider
|
|
|
|
ref="hybrid_memory"
|
|
|
|
name="Memory"
|
|
|
|
rules="required|alpha_num_memory"
|
|
|
|
v-slot="{ errors, ariaMsg, ariaInput, valid, invalid }"
|
|
|
|
>
|
|
|
|
<div class="input-group input-group-sm sm-3">
|
|
|
|
<input type="text"
|
|
|
|
name="Memory"
|
|
|
|
class="form-control"
|
|
|
|
v-bind:class="{'is-valid': isDeployValid.memory == 1, 'is-invalid': isDeployValid.memory == 2}"
|
|
|
|
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
|
|
|
|
placeholder="Limit Memory e.g. 500"
|
|
|
|
v-model="deploy.memory"
|
|
|
|
v-on:keyup="isValid('memory')"
|
|
|
|
>
|
|
|
|
<div class="input-group-append">
|
|
|
|
<button
|
|
|
|
class="ti-info btn btn-outline-secondary"
|
|
|
|
round
|
|
|
|
type="button"
|
|
|
|
@click="showInfo('memory')">
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span class="hybrid-field-error">{{ errors[0] }}</span>
|
|
|
|
</ValidationProvider>
|
|
|
|
</b-col>
|
|
|
|
<b-col cols="4">
|
|
|
|
<ValidationProvider
|
|
|
|
ref="hybrid_networkport"
|
|
|
|
name="Networkport"
|
|
|
|
rules="mybetween:1,65535"
|
|
|
|
v-slot="{ errors, ariaMsg, ariaInput, valid, invalid }"
|
|
|
|
>
|
|
|
|
<div class="input-group input-group-sm sm-3">
|
|
|
|
<input type="text"
|
|
|
|
name="Networkport"
|
|
|
|
class="form-control"
|
|
|
|
v-bind:class="{'is-valid': isDeployValid.networkport == 1, 'is-invalid': isDeployValid.networkport == 2}"
|
|
|
|
aria-label="Small" aria-describedby="inputGroup-sizing-sm"
|
|
|
|
placeholder="Net Port (inside the container)"
|
|
|
|
v-model="deploy.networkport"
|
|
|
|
v-on:keyup="isValid('networkport')"
|
|
|
|
>
|
|
|
|
<div class="input-group-append">
|
|
|
|
<button
|
|
|
|
class="ti-info btn btn-outline-secondary"
|
|
|
|
round
|
|
|
|
type="button"
|
|
|
|
@click="showInfo('networkport')">
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span class="hybrid-field-error">{{ errors[0] }}</span>
|
|
|
|
</ValidationProvider>
|
|
|
|
</b-col>
|
|
|
|
</b-row>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<!-- -------- lab url ----------------------------------- -->
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<b-row>
|
|
|
|
<b-col cols="12">
|
|
|
|
<ValidationProvider
|
|
|
|
ref="hybrid_url"
|
|
|
|
name="Url"
|
|
|
|
rules="required|alpha_url"
|
|
|
|
v-slot="{ errors, ariaMsg, ariaInput, valid, invalid }"
|
|
|
|
>
|
|
|
|
<div class="input-group input-group-sm sm-3">
|
|
|
|
<input type="text"
|
|
|
|
class="form-control"
|
|
|
|
v-bind:class="{'is-valid': isDeployValid.url == 1, 'is-invalid': isDeployValid.url == 2}"
|
|
|
|
name="Url"
|
|
|
|
aria-label="Small"
|
|
|
|
aria-describedby="inputGroup-sizing-sm"
|
|
|
|
placeholder="link to README file (see info button for more)"
|
|
|
|
v-model="deploy.url"
|
|
|
|
v-on:keyup="isValid('url')"
|
|
|
|
>
|
|
|
|
<div class="input-group-append">
|
|
|
|
<button
|
|
|
|
class="ti-info btn btn-outline-secondary"
|
|
|
|
round
|
|
|
|
type="button"
|
|
|
|
@click="showInfo('url')"
|
|
|
|
>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<span class="hybrid-field-error">{{ errors[0] }}</span>
|
|
|
|
</ValidationProvider>
|
|
|
|
</b-col>
|
|
|
|
</b-row>
|
|
|
|
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<!-- -------- lab startdate ----------------------------------- -->
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<b-row>
|
|
|
|
<b-col cols="6">
|
|
|
|
<div class="input-group input-group-sm mb-3">
|
|
|
|
<div class="input-group-prepend">
|
|
|
|
<button class="btn btn-outline-secondary"
|
|
|
|
type="button"
|
|
|
|
>Start date </button>
|
|
|
|
</div>
|
|
|
|
<date-picker
|
|
|
|
type="date"
|
|
|
|
autocomplete="off"
|
|
|
|
v-model="deploy.startdate"
|
|
|
|
format="YYYY-MM-DD"
|
|
|
|
lang="en"
|
|
|
|
>
|
|
|
|
</date-picker>
|
|
|
|
</div>
|
|
|
|
</b-col>
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<!-- -------- lab starttime ----------------------------------- -->
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<b-col cols="6">
|
|
|
|
<div class="input-group input-group-sm mb-3">
|
|
|
|
<div class="input-group-prepend">
|
|
|
|
<button class="btn btn-outline-secondary"
|
|
|
|
type="button"
|
|
|
|
>Start time</button>
|
|
|
|
</div>
|
|
|
|
<date-picker
|
|
|
|
type="time"
|
|
|
|
:format="'HH:mm'"
|
|
|
|
v-model="deploy.starttime"
|
|
|
|
show-hour
|
|
|
|
show-minute
|
|
|
|
:time-picker-options="timePickerOptions"
|
|
|
|
lang="en"
|
|
|
|
>
|
|
|
|
</date-picker>
|
|
|
|
</div>
|
|
|
|
</b-col>
|
|
|
|
</b-row>
|
|
|
|
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<!-- -------- lab enddate ----------------------------------- -->
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<b-row>
|
|
|
|
<b-col cols="6">
|
|
|
|
<div class="input-group input-group-sm mb-3">
|
|
|
|
<div class="input-group-prepend">
|
|
|
|
<button class="btn btn-outline-secondary"
|
|
|
|
type="button"
|
|
|
|
>End date </button>
|
|
|
|
</div>
|
|
|
|
<date-picker
|
|
|
|
type="date"
|
|
|
|
autocomplete="off"
|
|
|
|
v-model="deploy.enddate"
|
|
|
|
format="YYYY-MM-DD"
|
|
|
|
lang="en"
|
|
|
|
>
|
|
|
|
</date-picker>
|
|
|
|
</div>
|
|
|
|
</b-col>
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<!-- -------- lab endtime ----------------------------------- -->
|
|
|
|
<!-- --------------------------------------------------------- -->
|
|
|
|
<b-col cols="6">
|
|
|
|
<div class="input-group input-group-sm mb-3">
|
|
|
|
<div class="input-group-prepend">
|
|
|
|
<button class="btn btn-outline-secondary"
|
|
|
|
type="button"
|
|
|
|
>End time</button>
|
|
|
|
</div>
|
|
|
|
<date-picker
|
|
|
|
type="time"
|
|
|
|
:format="'HH:mm'"
|
|
|
|
v-model="deploy.endtime"
|
|
|
|
show-hour
|
|
|
|
show-minute
|
|
|
|
:time-picker-options="timePickerOptions"
|
|
|
|
lang="en"
|
|
|
|
>
|
|
|
|
</date-picker>
|
|
|
|
</div>
|
|
|
|
</b-col>
|
|
|
|
</b-row>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<b-row>
|
|
|
|
<b-col cols="6">
|
|
|
|
<div class="input-group input-group-sm sm-3">
|
|
|
|
<div class="input-group-prepend">
|
|
|
|
<button
|
|
|
|
class="ti-cloud-up btn btn-outline-success"
|
|
|
|
round
|
|
|
|
type="button"
|
|
|
|
title="Deploy"
|
|
|
|
@click="add_deploy()"
|
|
|
|
> Deploy
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</b-col>
|
|
|
|
|
|
|
|
<b-col cols="2">
|
|
|
|
</b-col>
|
|
|
|
|
|
|
|
<b-col cols="4">
|
|
|
|
<div class="custom-control custom-switch">
|
|
|
|
<input type="checkbox" class="custom-control-input" id="customStack"
|
|
|
|
v-model="deploy.usersjoin"
|
|
|
|
value="true"
|
|
|
|
unchecked-value="false"
|
|
|
|
>
|
|
|
|
<label class="custom-control-label" for="customStack">Users can join the lab instance</label>
|
|
|
|
</div>
|
|
|
|
</b-col>
|
|
|
|
</b-row>
|
|
|
|
</b-container>
|
|
|
|
</card>
|
|
|
|
</template>
|
|
|
|
<script>
|
|
|
|
import store from '@/store/index'
|
|
|
|
import {mapState, mapGetters, mapActions,dispatch} from 'vuex'
|
|
|
|
import Vue from 'vue'
|
|
|
|
import DatePicker from 'vue2-datepicker'
|
|
|
|
import card from '@/components/Card.vue'
|
|
|
|
import {ApiConfig} from "@/config/index";
|
|
|
|
import { ValidationObserver, ValidationProvider, extend } from 'vee-validate';
|
|
|
|
import { required, alpha_num, between} from 'vee-validate/dist/rules';
|
|
|
|
import 'vue2-datepicker/index.css';
|
|
|
|
|
|
|
|
// No message specified.
|
|
|
|
extend('alpha_num', alpha_num);
|
|
|
|
|
|
|
|
extend('mybetween', between);
|
|
|
|
extend('mybetween', {
|
|
|
|
message: 'The {_field_} field must be a number: 1-65535'
|
|
|
|
});
|
|
|
|
|
|
|
|
//extend('alpha_num_image', alpha_num);
|
|
|
|
extend('alpha_num_image', value => {
|
|
|
|
var regex = new RegExp(/^[A-Za-z0-9\:\.\-\_\/]+$/, 'i');
|
|
|
|
if(regex.test(value)){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return 'The {_field_} field may contain alphabetic characters, numbers, colons, hyphens, slashes, dots and underscores'
|
|
|
|
});
|
|
|
|
|
|
|
|
extend('alpha_num_name', value => {
|
|
|
|
var regex = new RegExp(/^[A-Za-z0-9]+$/, 'i');
|
|
|
|
if(regex.test(value)){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return 'The {_field_} field may contain alphabetic characters and numbers'
|
|
|
|
});
|
|
|
|
|
|
|
|
extend('alpha_num_cpu', value => {
|
|
|
|
//var regex = new RegExp(/^(?:\d{1})?(?:\.\d{1})?$/);
|
|
|
|
var regex = new RegExp(/^(?!0\d)\d+(?:\.\d{1})?$/);
|
|
|
|
if(regex.test(value)){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return 'The {_field_} field may contain numbers and dots e.g 0.5'
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
extend('alpha_num_memory', value => {
|
|
|
|
var regex = new RegExp(/^[0-9]+$/, 'i');
|
|
|
|
if(regex.test(value)){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return 'The {_field_} field may contain numbers e.g 500'
|
|
|
|
});
|
|
|
|
|
|
|
|
extend('alpha_url', value => {
|
|
|
|
var regex = new RegExp(/https?:\/\/(git\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/,'i');
|
|
|
|
//var regex = new RegExp(/^[0-9]+$/, 'i');
|
|
|
|
if(regex.test(value)){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return 'The {_field_} field may contain url'
|
|
|
|
});
|
|
|
|
|
|
|
|
// Override the default message.
|
|
|
|
extend('required', {
|
|
|
|
...required,
|
|
|
|
message: 'This field is required'
|
|
|
|
});
|
|
|
|
export default {
|
|
|
|
components: {
|
|
|
|
DatePicker,
|
|
|
|
ValidationProvider,
|
|
|
|
card
|
|
|
|
},
|
|
|
|
props: {
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return{
|
|
|
|
isHybridError: false,
|
|
|
|
isHybridSuccess: false,
|
|
|
|
token: '',
|
|
|
|
timePickerOptions:{
|
|
|
|
start: '00:00',
|
|
|
|
step: '00:30',
|
|
|
|
end: '23:30'
|
|
|
|
},
|
|
|
|
deploy:{
|
|
|
|
"usersjoin":true
|
|
|
|
},
|
|
|
|
isDeployValid:{
|
|
|
|
"image":3,
|
|
|
|
"name":3,
|
|
|
|
"stackname":3,
|
|
|
|
"network":3,
|
|
|
|
//"networkport":3,
|
|
|
|
"url":3,
|
|
|
|
"cpu":3,
|
|
|
|
"memory":3
|
|
|
|
},
|
|
|
|
isDeployError:{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
var url_string = window.location.href
|
|
|
|
var url = new URL(url_string);
|
|
|
|
this.token = url.searchParams.get("token");
|
|
|
|
//console.log("token "+ this.token);
|
|
|
|
|
|
|
|
},
|
|
|
|
beforeDestroy () {
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
/*
|
|
|
|
async isValidate (event) {
|
|
|
|
this.$nextTick(() => {
|
|
|
|
//await this.isValid(event)
|
|
|
|
//console.log("keywords value: " + this.deploy.image);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
*/
|
|
|
|
async add_deploy(){
|
|
|
|
|
|
|
|
var o = Object.entries(this.deploy)
|
|
|
|
var pvalid = new Promise((resolve, reject) => {
|
|
|
|
o.forEach((value, index, array) => {
|
|
|
|
this.isValid(array[index][0])
|
|
|
|
if (index === array.length -1) resolve();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
pvalid.then(() => {
|
|
|
|
(async () => {
|
|
|
|
var isAllValid = true
|
|
|
|
for (const [key, value] of Object.entries(this.isDeployValid)) {
|
|
|
|
//console.log(`${key}: ${value}`);
|
|
|
|
if(value != 1){
|
|
|
|
isAllValid = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(isAllValid){
|
|
|
|
var log = await store.dispatch("pipelineLLO/adddeploy",{
|
|
|
|
token:this.token,
|
|
|
|
deploy:this.deploy
|
|
|
|
})
|
|
|
|
this.$root.$emit('hybrid_refresh_bootstrap_view')
|
|
|
|
console.log('ok')
|
|
|
|
var info = '<h5>The deploy process is started</h5> Please wait for it to finish before trying again! <br><br>See also in "Manage your deployments" table'
|
|
|
|
this.$swal({
|
|
|
|
type: 'Info',
|
|
|
|
title: 'Info!',
|
|
|
|
icon:'info',
|
|
|
|
html: info,
|
|
|
|
showCloseButton: true,
|
|
|
|
showLoaderOnConfirm: false,
|
|
|
|
allowOutsideClick: false,
|
|
|
|
cancelButtonText: 'No, cancel!',
|
|
|
|
showCancelButton: false,
|
|
|
|
showLoaderOnConfirm: false,
|
|
|
|
reverseButtons: true,
|
|
|
|
focusCancel: true,
|
|
|
|
confirmButtonText: 'Ok!'
|
|
|
|
})
|
|
|
|
}else{
|
|
|
|
var info = "Missing required fields"
|
|
|
|
this.$swal({
|
|
|
|
type: 'Info',
|
|
|
|
title: 'Info!',
|
|
|
|
icon:'info',
|
|
|
|
html: info,
|
|
|
|
showCloseButton: true,
|
|
|
|
showLoaderOnConfirm: false,
|
|
|
|
allowOutsideClick: false,
|
|
|
|
cancelButtonText: 'No, cancel!',
|
|
|
|
showCancelButton: false,
|
|
|
|
showLoaderOnConfirm: false,
|
|
|
|
reverseButtons: true,
|
|
|
|
focusCancel: true,
|
|
|
|
confirmButtonText: 'Ok!'
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
});
|
|
|
|
|
|
|
|
},
|
|
|
|
async showInfo(action){
|
|
|
|
if(action == 'image' ){
|
|
|
|
var info=`<h5>To start, we need to have a <b>docker image </b> <br>
|
|
|
|
<br> We have built some. You can find it here: Menu "Images"</h5>
|
|
|
|
<h6>More Info here: <a href="https://en.wikipedia.org/wiki/Docker_(software)" target="new">Wikipedia</a> , <a href="https://www.docker.com/resources/what-container" target="new">Docker</a> </h6>
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
The field may contain alphabetic characters, numbers, colons, hyphens, slashes, dots and underscores
|
|
|
|
`
|
|
|
|
}else if(action == 'stackname'){
|
|
|
|
var info=`<h5>To start, we need to have a <b>Stack Name </b> <br>
|
|
|
|
<br> This will bring up all the services, volumes, networks and everything else <br> in an isolated environment.
|
|
|
|
</h6>
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
The field may contain alphabetic characters and numbers
|
|
|
|
`
|
|
|
|
}else if(action == 'network'){
|
|
|
|
var info=`<h5>To start, we need to have a <b>Network </b> <br>
|
|
|
|
<br> This will bring up all the services, volumes, networks and everything else <br> in an isolated network environment.
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
Services running inside any of this networks containers have access (not limited by any firewall) to all other services.
|
|
|
|
<br>
|
|
|
|
</h5>
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
The field may contain alphabetic characters and numbers
|
|
|
|
|
|
|
|
`
|
|
|
|
}else if(action == 'url'){
|
|
|
|
var info=`<h5><b>Git Repo url </b></h5>
|
|
|
|
<br> The location of the file describing your service. (most comonly README)</br>
|
|
|
|
<br>
|
|
|
|
</br>
|
|
|
|
</h5>
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
The field may contain any valid url BUT it must be under https://git.swarmlab.io
|
|
|
|
`
|
|
|
|
}else if(action == 'networkport'){
|
|
|
|
var info=`<h5><b>Network Port </b></h5>
|
|
|
|
<br>
|
|
|
|
<h5>
|
|
|
|
By default, when you create a container, <b>it does not publish any of its ports to the outside world. </b>
|
|
|
|
<br>
|
|
|
|
To make a port available to Services which are not connected to the Stack network, we use this port.
|
|
|
|
</h5>
|
|
|
|
<br>
|
|
|
|
<h5>
|
|
|
|
<u>
|
|
|
|
To make a service available we have to know the port number used by these service inside the container.
|
|
|
|
</u>
|
|
|
|
<br>
|
|
|
|
<b>Please insert that here.</b>
|
|
|
|
</h5>
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
(The port for outside connections is automatically generated and you dont have to worry about it!)
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
The field may contain numbers
|
|
|
|
`
|
|
|
|
}else if(action == 'cpu'){
|
|
|
|
var info=`<h5>To start, we need to have a <b>CPU </b> Limit <br>
|
|
|
|
<br> Limit the specific CPUs or cores a container can use
|
|
|
|
</h6>
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
The field may contain numbers and dots e.g 0.5
|
|
|
|
`
|
|
|
|
}else if(action == 'memory'){
|
|
|
|
var info=`<h5>To start, we need to have a <b>Memory </b> Limit
|
|
|
|
<br> <br> Limit the specific Memoty a container can use <br>
|
|
|
|
e.g 200
|
|
|
|
<br>
|
|
|
|
(MB)
|
|
|
|
</h6>
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
<h6>
|
|
|
|
<i>
|
|
|
|
It is important <b>not</b> to allow a running container to consume too much of the host machine’s memory.
|
|
|
|
</i>
|
|
|
|
</h6>
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
The field may contain numbers
|
|
|
|
`
|
|
|
|
}else if(action == 'name'){
|
|
|
|
var info=`<h5>To start, we need to have a <b>Name </b><br>
|
|
|
|
This name is only for your own use. The system completely disregards it!
|
|
|
|
</h5>
|
|
|
|
<br>
|
|
|
|
<br>
|
|
|
|
The field may contain alphabetic characters and numbers
|
|
|
|
`
|
|
|
|
}
|
|
|
|
this.$swal({
|
|
|
|
type: 'Info',
|
|
|
|
title: 'Info!',
|
|
|
|
icon:'info',
|
|
|
|
html: info,
|
|
|
|
showCloseButton: true,
|
|
|
|
showLoaderOnConfirm: false,
|
|
|
|
allowOutsideClick: false,
|
|
|
|
cancelButtonText: 'No, cancel!',
|
|
|
|
showCancelButton: false,
|
|
|
|
showLoaderOnConfirm: false,
|
|
|
|
reverseButtons: true,
|
|
|
|
focusCancel: true,
|
|
|
|
confirmButtonText: 'Ok!'
|
|
|
|
})
|
|
|
|
},
|
|
|
|
async isValid(f){
|
|
|
|
|
|
|
|
// ------------
|
|
|
|
// validate
|
|
|
|
// ------------
|
|
|
|
if(f == 'image'){
|
|
|
|
//console.log(this.deploy.image)
|
|
|
|
var field = await this.$refs.hybrid_image.validate();
|
|
|
|
if(field.valid == true){
|
|
|
|
this.isDeployValid.image = 1
|
|
|
|
}else{
|
|
|
|
this.isDeployValid.image = 2
|
|
|
|
}
|
|
|
|
//console.log(JSON.stringify(f_image))
|
|
|
|
//console.log(this.isDeployValid.image)
|
|
|
|
}else if(f == 'stackname'){
|
|
|
|
var field = await this.$refs.hybrid_stackname.validate();
|
|
|
|
if(field.valid == true){
|
|
|
|
this.isDeployValid.stackname = 1
|
|
|
|
}else{
|
|
|
|
this.isDeployValid.stackname = 2
|
|
|
|
}
|
|
|
|
}else if(f == 'network'){
|
|
|
|
var field = await this.$refs.hybrid_network.validate();
|
|
|
|
if(field.valid == true){
|
|
|
|
this.isDeployValid.network = 1
|
|
|
|
}else{
|
|
|
|
this.isDeployValid.network = 2
|
|
|
|
}
|
|
|
|
}else if(f == 'url'){
|
|
|
|
var field = await this.$refs.hybrid_url.validate();
|
|
|
|
if(field.valid == true){
|
|
|
|
this.isDeployValid.url = 1
|
|
|
|
}else{
|
|
|
|
this.isDeployValid.url = 2
|
|
|
|
}
|
|
|
|
}else if(f == 'networkport'){
|
|
|
|
var field = await this.$refs.hybrid_networkport.validate();
|
|
|
|
//console.log('port '+JSON.stringify(field))
|
|
|
|
if(field.valid == true){
|
|
|
|
this.isDeployValid.networkport = 1
|
|
|
|
}else{
|
|
|
|
this.isDeployValid.networkport = 2
|
|
|
|
}
|
|
|
|
}else if(f == 'cpu'){
|
|
|
|
var field = await this.$refs.hybrid_cpu.validate();
|
|
|
|
if(field.valid == true){
|
|
|
|
this.isDeployValid.cpu = 1
|
|
|
|
}else{
|
|
|
|
this.isDeployValid.cpu = 2
|
|
|
|
}
|
|
|
|
}else if(f == 'memory'){
|
|
|
|
var field = await this.$refs.hybrid_memory.validate();
|
|
|
|
if(field.valid == true){
|
|
|
|
this.isDeployValid.memory = 1
|
|
|
|
}else{
|
|
|
|
this.isDeployValid.memory = 2
|
|
|
|
}
|
|
|
|
}else if(f == 'name'){
|
|
|
|
var field = await this.$refs.hybrid_name.validate();
|
|
|
|
if(field.valid == true){
|
|
|
|
this.isDeployValid.name = 1
|
|
|
|
}else{
|
|
|
|
this.isDeployValid.name = 2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
actions: {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
<style>
|
|
|
|
.flex-fixed-width-item {
|
|
|
|
flex: 0 0 100px;
|
|
|
|
}
|
|
|
|
.modalinfo {
|
|
|
|
z-index: 10000000 !important;
|
|
|
|
position:fixed;
|
|
|
|
}
|
|
|
|
/* a container with flex-direction column */
|
|
|
|
|
|
|
|
.vue-notifyjs.notifications{
|
|
|
|
.alert{
|
|
|
|
z-index: 100;
|
|
|
|
}
|
|
|
|
.list-move {
|
|
|
|
transition: transform 0.3s, opacity 0.4s;
|
|
|
|
}
|
|
|
|
.list-item {
|
|
|
|
display: inline-block;
|
|
|
|
margin-right: 10px;
|
|
|
|
|
|
|
|
}
|
|
|
|
.list-enter-active {
|
|
|
|
transition: transform 0.2s ease-in, opacity 0.4s ease-in;
|
|
|
|
}
|
|
|
|
.list-leave-active {
|
|
|
|
transition: transform 1s ease-out, opacity 0.4s ease-out;
|
|
|
|
}
|
|
|
|
|
|
|
|
.list-enter {
|
|
|
|
opacity: 0;
|
|
|
|
transform: scale(1.1);
|
|
|
|
|
|
|
|
}
|
|
|
|
.list-leave-to {
|
|
|
|
opacity: 0;
|
|
|
|
transform: scale(1.2, 0.7);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pre {
|
|
|
|
//background-color: rgb(255, 247, 229);
|
|
|
|
background-color: #eff0f1;
|
|
|
|
border: 1px solid blue;
|
|
|
|
//white-space: pre-line;
|
|
|
|
}
|
|
|
|
.hybrid-field-error {
|
|
|
|
color: red;
|
|
|
|
}
|
|
|
|
|
|
|
|
.hybrid-error {
|
|
|
|
color: red;
|
|
|
|
}
|
|
|
|
</style>
|