mirror of
https://github.com/retspen/webvirtcloud
synced 2026-03-21 18:14:51 +00:00
commit
cd798eb9b7
94 changed files with 1874 additions and 1697 deletions
|
|
@ -22,7 +22,7 @@
|
|||
How to update <code>gstfsd</code> daemon on hypervisor:
|
||||
|
||||
```bash
|
||||
wget -O - https://clck.ru/9VMRH | sudo tee -a /usr/local/bin/gstfsd
|
||||
wget -O - https://bit.ly/2NAaWXG | sudo tee -a /usr/local/bin/gstfsd
|
||||
sudo service supervisor restart
|
||||
```
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ sudo service supervisor restart
|
|||
Setup libvirt and KVM on server
|
||||
|
||||
```bash
|
||||
wget -O - https://clck.ru/9V9fH | sudo sh
|
||||
wget -O - https://bit.ly/36baWUu | sudo sh
|
||||
```
|
||||
|
||||
Done!!
|
||||
|
|
|
|||
|
|
@ -4,8 +4,10 @@ from instances.models import Instance
|
|||
def refresh_instance_database(compute):
|
||||
domains = compute.proxy.wvm.listAllDomains()
|
||||
domain_names = [d.name() for d in domains]
|
||||
domain_uuids = [d.UUIDString() for d in domains]
|
||||
# Delete instances that're not on host from DB
|
||||
Instance.objects.filter(compute=compute).exclude(name__in=domain_names).delete()
|
||||
Instance.objects.filter(compute=compute).exclude(uuid__in=domain_uuids).delete()
|
||||
# Create instances that're on host but not in DB
|
||||
names = Instance.objects.filter(compute=compute).values_list('name', flat=True)
|
||||
for domain in domains:
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
Django==2.2.17
|
||||
Django==2.2.19
|
||||
django-bootstrap4==2.3.1
|
||||
django-icons==2.2.0
|
||||
django-icons==2.2.1
|
||||
django-login-required-middleware==0.5.0
|
||||
django-otp==1.0.2
|
||||
django-qr-code==1.3.1
|
||||
gunicorn==20.0.4
|
||||
importlib-metadata==2.0.0
|
||||
libsass==0.20.1
|
||||
libvirt-python==6.9.0
|
||||
lxml==4.6.1
|
||||
libvirt-python==7.1.0
|
||||
lxml==4.6.3
|
||||
qrcode==6.1
|
||||
rwlock==0.0.7
|
||||
websockify==0.9.0
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[program:gstfsd]
|
||||
command=/srv/webvirtcloud/venv/bin/python3 /usr/local/bin/gstfsd
|
||||
command=/usr/bin/python3 /usr/local/bin/gstfsd
|
||||
directory=/usr/local/bin
|
||||
user=root
|
||||
autostart=true
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ echowarn() {
|
|||
# DESCRIPTION: Echo debug information to stdout.
|
||||
#-------------------------------------------------------------------------------
|
||||
echodebug() {
|
||||
if [ "$_ECHO_DEBUG" -eq "$BS_TRUE" ]; then
|
||||
if [ $_ECHO_DEBUG -eq $BS_TRUE ]; then
|
||||
printf "${BC} * DEBUG${EC}: %s\n" "$@";
|
||||
fi
|
||||
}
|
||||
|
|
@ -342,7 +342,7 @@ __check_end_of_life_versions() {
|
|||
;;
|
||||
|
||||
centos)
|
||||
# CentOS versions lower than 5 are no longer supported
|
||||
# CentOS versions lower than 6 are no longer supported
|
||||
if { [ "$DISTRO_MAJOR_VERSION" -eq 6 ] && [ "$DISTRO_MINOR_VERSION" -lt 3 ]; } || [ "$DISTRO_MAJOR_VERSION" -lt 5 ]; then
|
||||
echoerror "End of life distributions are not supported."
|
||||
echoerror "Please consider upgrading to the next stable. See:"
|
||||
|
|
@ -374,26 +374,32 @@ __check_end_of_life_versions
|
|||
# CentOS Install Functions
|
||||
#
|
||||
install_centos() {
|
||||
if [ "$DISTRO_MAJOR_VERSION" -ge 6 ]; then
|
||||
yum -y install qemu-kvm libvirt bridge-utils python-libguestfs libguestfs-tools supervisor cyrus-sasl-md5 epel-release || return 1
|
||||
yum -y install epel-release || return 1
|
||||
|
||||
if [ "$DISTRO_MAJOR_VERSION" -lt 8 ]; then
|
||||
yum -y install qemu-kvm libvirt bridge-utils python-libguestfs libguestfs-tools supervisor cyrus-sasl-md5 || return 1
|
||||
else
|
||||
yum -y install qemu-kvm libvirt python3-libguestfs libguestfs-tools cyrus-sasl-md5 supervisor || return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
install_centos_post() {
|
||||
if [ -f /etc/sysconfig/libvirtd ]; then
|
||||
sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd
|
||||
else
|
||||
echoerror "/etc/sysconfig/libvirtd not found. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
if [ -f /etc/libvirt/libvirtd.conf ]; then
|
||||
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
|
||||
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
|
||||
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
|
||||
else
|
||||
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
|
||||
exit 1
|
||||
if [ "$DISTRO_MAJOR_VERSION" -lt 8 ]; then
|
||||
if [ -f /etc/sysconfig/libvirtd ]; then
|
||||
sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd
|
||||
else
|
||||
echoerror "/etc/sysconfig/libvirtd not found. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
if [ -f /etc/libvirt/libvirtd.conf ]; then
|
||||
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
|
||||
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
|
||||
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
|
||||
else
|
||||
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ -f /etc/libvirt/qemu.conf ]; then
|
||||
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
|
||||
|
|
@ -440,14 +446,24 @@ daemons_running_centos() {
|
|||
service libvirt-guests stop > /dev/null 2>&1
|
||||
service libvirt-guests start
|
||||
fi
|
||||
if [ -f /usr/lib/systemd/system/libvirtd.service ]; then
|
||||
systemctl stop libvirtd.service > /dev/null 2>&1
|
||||
systemctl start libvirtd.service
|
||||
|
||||
if [ "$DISTRO_MAJOR_VERSION" -lt 8 ]; then
|
||||
if [ -f /usr/lib/systemd/system/libvirtd.service ]; then
|
||||
systemctl stop libvirtd.service > /dev/null 2>&1
|
||||
systemctl start libvirtd.service
|
||||
fi
|
||||
else
|
||||
if [ -f /usr/lib/systemd/system/libvirtd-tcp.socket ]; then
|
||||
systemctl stop libvirtd-tcp.socket > /dev/null 2>&1
|
||||
systemctl start libvirtd-tcp.socket
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f /usr/lib/systemd/system/libvirt-guests.service ]; then
|
||||
systemctl stop libvirt-guests.service > /dev/null 2>&1
|
||||
systemctl start libvirt-guests.service
|
||||
fi
|
||||
|
||||
if [ -f /etc/init.d/supervisord ]; then
|
||||
service supervisord stop > /dev/null 2>&1
|
||||
service supervisord start
|
||||
|
|
@ -599,7 +615,6 @@ install_ubuntu() {
|
|||
apt install -y qemu-kvm libvirt-bin bridge-utils virt-manager sasl2-bin python3-guestfs supervisor || return 1
|
||||
fi
|
||||
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
-r ../conf/requirements.txt
|
||||
coverage==5.3
|
||||
django-debug-toolbar==3.1.1
|
||||
pycodestyle==2.6.0
|
||||
pyflakes==2.2.0
|
||||
pylint==2.6.0
|
||||
yapf==0.30.0
|
||||
coverage==5.5
|
||||
django-debug-toolbar==3.2
|
||||
pycodestyle==2.7.0
|
||||
pyflakes==2.3.1
|
||||
pylint==2.7.2
|
||||
yapf==0.31.0
|
||||
|
|
|
|||
|
|
@ -10,14 +10,12 @@
|
|||
}
|
||||
|
||||
.breadcrumb-item {
|
||||
display: flex;
|
||||
|
||||
// The separator between breadcrumbs (by default, a forward-slash: "/")
|
||||
+ .breadcrumb-item {
|
||||
padding-left: $breadcrumb-item-padding;
|
||||
|
||||
&::before {
|
||||
display: inline-block; // Suppress underlining of the separator in modern browsers
|
||||
float: left; // Suppress inline spacings and underlining of the separator
|
||||
padding-right: $breadcrumb-item-padding;
|
||||
color: $breadcrumb-divider-color;
|
||||
content: escape-svg($breadcrumb-divider);
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@
|
|||
display: inline-block;
|
||||
width: $carousel-control-icon-width;
|
||||
height: $carousel-control-icon-width;
|
||||
background: no-repeat 50% / 100% 100%;
|
||||
background: 50% / 100% 100% no-repeat;
|
||||
}
|
||||
.carousel-control-prev-icon {
|
||||
background-image: escape-svg($carousel-control-prev-icon-bg);
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
width: $custom-control-indicator-size;
|
||||
height: $custom-control-indicator-size;
|
||||
content: "";
|
||||
background: no-repeat 50% / #{$custom-control-indicator-bg-size};
|
||||
background: 50% / #{$custom-control-indicator-bg-size} no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -315,6 +315,7 @@
|
|||
width: 100%;
|
||||
height: $custom-file-height;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
opacity: 0;
|
||||
|
||||
&:focus ~ .custom-file-label {
|
||||
|
|
@ -347,6 +348,7 @@
|
|||
z-index: 1;
|
||||
height: $custom-file-height;
|
||||
padding: $custom-file-padding-y $custom-file-padding-x;
|
||||
overflow: hidden;
|
||||
font-family: $custom-file-font-family;
|
||||
font-weight: $custom-file-font-weight;
|
||||
line-height: $custom-file-line-height;
|
||||
|
|
@ -388,7 +390,7 @@
|
|||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
outline: 0;
|
||||
|
||||
// Pseudo-elements must be split across multiple rulesets to have an effect.
|
||||
// No box-shadow() mixin for focus accessibility.
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// When enabled Popper.js, reset basic dropdown position
|
||||
// When Popper is enabled, reset the basic dropdown position
|
||||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
.dropdown-menu {
|
||||
&[x-placement^="top"],
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
> .form-control,
|
||||
> .custom-select {
|
||||
&:not(:last-child) { @include border-right-radius(0); }
|
||||
&:not(:first-child) { @include border-left-radius(0); }
|
||||
}
|
||||
|
||||
|
|
@ -53,9 +52,24 @@
|
|||
align-items: center;
|
||||
|
||||
&:not(:last-child) .custom-file-label,
|
||||
&:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }
|
||||
&:not(:first-child) .custom-file-label { @include border-left-radius(0); }
|
||||
}
|
||||
|
||||
&:not(.has-validation) {
|
||||
> .form-control:not(:last-child),
|
||||
> .custom-select:not(:last-child),
|
||||
> .custom-file:not(:last-child) .custom-file-label::after {
|
||||
@include border-right-radius(0);
|
||||
}
|
||||
}
|
||||
|
||||
&.has-validation {
|
||||
> .form-control:nth-last-child(n + 3),
|
||||
> .custom-select:nth-last-child(n + 3),
|
||||
> .custom-file:nth-last-child(n + 3) .custom-file-label::after {
|
||||
@include border-right-radius(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -175,8 +189,10 @@
|
|||
|
||||
.input-group > .input-group-prepend > .btn,
|
||||
.input-group > .input-group-prepend > .input-group-text,
|
||||
.input-group > .input-group-append:not(:last-child) > .btn,
|
||||
.input-group > .input-group-append:not(:last-child) > .input-group-text,
|
||||
.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn,
|
||||
.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text,
|
||||
.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn,
|
||||
.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text,
|
||||
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
|
||||
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
|
||||
@include border-right-radius(0);
|
||||
|
|
|
|||
|
|
@ -35,11 +35,8 @@
|
|||
.nav-tabs {
|
||||
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
|
||||
|
||||
.nav-item {
|
||||
margin-bottom: -$nav-tabs-border-width;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
margin-bottom: -$nav-tabs-border-width;
|
||||
border: $nav-tabs-border-width solid transparent;
|
||||
@include border-top-radius($nav-tabs-border-radius);
|
||||
|
||||
|
|
|
|||
|
|
@ -136,8 +136,12 @@
|
|||
height: 1.5em;
|
||||
vertical-align: middle;
|
||||
content: "";
|
||||
background: no-repeat center center;
|
||||
background-size: 100% 100%;
|
||||
background: 50% / 100% 100% no-repeat;
|
||||
}
|
||||
|
||||
.navbar-nav-scroll {
|
||||
max-height: $navbar-nav-scroll-max-height;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
// Generate series of `.navbar-expand-*` responsive classes for configuring
|
||||
|
|
@ -199,6 +203,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.navbar-nav-scroll {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
display: flex !important; // stylelint-disable-line declaration-no-important
|
||||
|
||||
|
|
|
|||
|
|
@ -66,9 +66,9 @@
|
|||
//
|
||||
|
||||
.pagination-lg {
|
||||
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);
|
||||
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $pagination-border-radius-lg);
|
||||
}
|
||||
|
||||
.pagination-sm {
|
||||
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);
|
||||
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $pagination-border-radius-sm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
@if $enable-transitions {
|
||||
.progress-bar-animated {
|
||||
animation: progress-bar-stripes $progress-bar-animation-timing;
|
||||
animation: $progress-bar-animation-timing progress-bar-stripes;
|
||||
|
||||
@if $enable-prefers-reduced-motion-media-query {
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
|
||||
// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
|
||||
|
||||
// Reboot
|
||||
//
|
||||
|
|
@ -307,13 +307,13 @@ button {
|
|||
border-radius: 0;
|
||||
}
|
||||
|
||||
// Work around a Firefox/IE bug where the transparent `button` background
|
||||
// results in a loss of the default `button` focus styles.
|
||||
//
|
||||
// Credit: https://github.com/suitcss/base/
|
||||
button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
// Explicitly remove focus outline in Chromium when it shouldn't be
|
||||
// visible (e.g. as result of mouse click or touch tap). It already
|
||||
// should be doing this automatically, but seems to currently be
|
||||
// confused and applies its very visible two-tone outline anyway.
|
||||
|
||||
button:focus:not(:focus-visible) {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
input,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
// Do not forget to update getting-started/theming.md!
|
||||
:root {
|
||||
// Custom variable values only support SassScript inside `#{}`.
|
||||
@each $color, $value in $colors {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
border-right-color: transparent;
|
||||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-radius: 50%;
|
||||
animation: spinner-border .75s linear infinite;
|
||||
animation: .75s linear infinite spinner-border;
|
||||
}
|
||||
|
||||
.spinner-border-sm {
|
||||
|
|
@ -47,10 +47,19 @@
|
|||
// stylelint-disable-next-line property-disallowed-list
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
animation: spinner-grow .75s linear infinite;
|
||||
animation: .75s linear infinite spinner-grow;
|
||||
}
|
||||
|
||||
.spinner-grow-sm {
|
||||
width: $spinner-width-sm;
|
||||
height: $spinner-height-sm;
|
||||
}
|
||||
|
||||
@if $enable-prefers-reduced-motion-media-query {
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.spinner-border,
|
||||
.spinner-grow {
|
||||
animation-duration: 1.5s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// stylelint-disable declaration-no-important, selector-list-comma-newline-after
|
||||
// stylelint-disable selector-list-comma-newline-after
|
||||
|
||||
//
|
||||
// Headings
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ $embed-responsive-aspect-ratios: join(
|
|||
// Font, line-height, and color for body text, headings, and more.
|
||||
|
||||
// stylelint-disable value-keyword-case
|
||||
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;
|
||||
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;
|
||||
$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
|
||||
$font-family-base: $font-family-sans-serif !default;
|
||||
// stylelint-enable value-keyword-case
|
||||
|
|
@ -583,7 +583,7 @@ $custom-select-disabled-bg: $gray-200 !default;
|
|||
$custom-select-bg-size: 8px 10px !default; // In pixels because image dimensions
|
||||
$custom-select-indicator-color: $gray-800 !default;
|
||||
$custom-select-indicator: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'><path fill='#{$custom-select-indicator-color}' d='M2 0L0 2h4zm0 5L0 3h4z'/></svg>") !default;
|
||||
$custom-select-background: escape-svg($custom-select-indicator) no-repeat right $custom-select-padding-x center / $custom-select-bg-size !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)
|
||||
$custom-select-background: escape-svg($custom-select-indicator) right $custom-select-padding-x center / $custom-select-bg-size no-repeat !default; // Used so we can have multiple background elements (e.g., arrow and feedback icon)
|
||||
|
||||
$custom-select-feedback-icon-padding-right: add(1em * .75, (2 * $custom-select-padding-y * .75) + $custom-select-padding-x + $custom-select-indicator-padding) !default;
|
||||
$custom-select-feedback-icon-position: center right ($custom-select-padding-x + $custom-select-indicator-padding) !default;
|
||||
|
|
@ -694,7 +694,7 @@ $zindex-tooltip: 1070 !default;
|
|||
// Navs
|
||||
|
||||
$nav-link-padding-y: .5rem !default;
|
||||
$nav-link-padding-x: 1rem !default;
|
||||
$nav-link-padding-x: 1.25rem !default;
|
||||
$nav-link-disabled-color: $gray-600 !default;
|
||||
|
||||
$nav-tabs-border-color: $gray-300 !default;
|
||||
|
|
@ -731,6 +731,8 @@ $navbar-toggler-padding-x: .75rem !default;
|
|||
$navbar-toggler-font-size: $font-size-lg !default;
|
||||
$navbar-toggler-border-radius: $btn-border-radius !default;
|
||||
|
||||
$navbar-nav-scroll-max-height: 75vh !default;
|
||||
|
||||
$navbar-dark-color: rgba($white, .5) !default;
|
||||
$navbar-dark-hover-color: rgba($white, .75) !default;
|
||||
$navbar-dark-active-color: $white !default;
|
||||
|
|
@ -772,12 +774,12 @@ $dropdown-box-shadow: 0 .5rem 1rem rgba($black, .175) !default;
|
|||
|
||||
$dropdown-link-color: $gray-900 !default;
|
||||
$dropdown-link-hover-color: darken($gray-900, 5%) !default;
|
||||
$dropdown-link-hover-bg: $gray-100 !default;
|
||||
$dropdown-link-hover-bg: $gray-200 !default;
|
||||
|
||||
$dropdown-link-active-color: $component-active-color !default;
|
||||
$dropdown-link-active-bg: $component-active-bg !default;
|
||||
|
||||
$dropdown-link-disabled-color: $gray-600 !default;
|
||||
$dropdown-link-disabled-color: $gray-500 !default;
|
||||
|
||||
$dropdown-item-padding-y: .25rem !default;
|
||||
$dropdown-item-padding-x: 1.5rem !default;
|
||||
|
|
@ -816,6 +818,8 @@ $pagination-disabled-color: $gray-600 !default;
|
|||
$pagination-disabled-bg: $white !default;
|
||||
$pagination-disabled-border-color: $gray-300 !default;
|
||||
|
||||
$pagination-border-radius-sm: $border-radius-sm !default;
|
||||
$pagination-border-radius-lg: $border-radius-lg !default;
|
||||
|
||||
// Jumbotron
|
||||
|
||||
|
|
@ -1054,7 +1058,7 @@ $figure-caption-color: $gray-600 !default;
|
|||
$breadcrumb-font-size: null !default;
|
||||
|
||||
$breadcrumb-padding-y: .75rem !default;
|
||||
$breadcrumb-padding-x: 1rem !default;
|
||||
$breadcrumb-padding-x: .5rem !default;
|
||||
$breadcrumb-item-padding: .5rem !default;
|
||||
|
||||
$breadcrumb-margin-bottom: 1rem !default;
|
||||
|
|
|
|||
7
dev/scss/bootstrap/bootstrap-grid.scss
vendored
7
dev/scss/bootstrap/bootstrap-grid.scss
vendored
|
|
@ -1,7 +1,7 @@
|
|||
/*!
|
||||
* Bootstrap Grid v4.5.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2020 The Bootstrap Authors
|
||||
* Copyright 2011-2020 Twitter, Inc.
|
||||
* Bootstrap Grid v4.6.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
|
|
@ -19,6 +19,7 @@ html {
|
|||
@import "functions";
|
||||
@import "variables";
|
||||
|
||||
@import "mixins/deprecate";
|
||||
@import "mixins/breakpoints";
|
||||
@import "mixins/grid-framework";
|
||||
@import "mixins/grid";
|
||||
|
|
|
|||
6
dev/scss/bootstrap/bootstrap-reboot.scss
vendored
6
dev/scss/bootstrap/bootstrap-reboot.scss
vendored
|
|
@ -1,7 +1,7 @@
|
|||
/*!
|
||||
* Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2020 The Bootstrap Authors
|
||||
* Copyright 2011-2020 Twitter, Inc.
|
||||
* Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
|
|
|
|||
6
dev/scss/bootstrap/bootstrap.scss
vendored
6
dev/scss/bootstrap/bootstrap.scss
vendored
|
|
@ -1,7 +1,7 @@
|
|||
/*!
|
||||
* Bootstrap v4.5.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2020 The Bootstrap Authors
|
||||
* Copyright 2011-2020 Twitter, Inc.
|
||||
* Bootstrap v4.6.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@
|
|||
color: color-yiq($color);
|
||||
background-color: rgba($color, $form-feedback-tooltip-opacity);
|
||||
@include border-radius($form-feedback-tooltip-border-radius);
|
||||
|
||||
// See https://github.com/twbs/bootstrap/pull/31557
|
||||
// Align tooltip to form elements
|
||||
.form-row > .col > &,
|
||||
.form-row > [class*="col-"] > & {
|
||||
left: $form-grid-gutter-width / 2;
|
||||
}
|
||||
}
|
||||
|
||||
@include form-validation-state-selector($state) {
|
||||
|
|
@ -108,7 +115,7 @@
|
|||
|
||||
@if $enable-validation-icons {
|
||||
padding-right: $custom-select-feedback-icon-padding-right;
|
||||
background: $custom-select-background, escape-svg($icon) $custom-select-bg no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size;
|
||||
background: $custom-select-background, $custom-select-bg escape-svg($icon) $custom-select-feedback-icon-position / $custom-select-feedback-icon-size no-repeat;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
// Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,
|
||||
// but doesn't convert dppx=>dpi.
|
||||
// There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.
|
||||
// Compatibility info: https://caniuse.com/#feat=css-media-resolution
|
||||
// Compatibility info: https://caniuse.com/css-media-resolution
|
||||
@media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx
|
||||
only screen and (min-resolution: 2dppx) { // Standardized
|
||||
background-image: url($file-2x);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
@import 'dev/scss/wvc-theme/flatly/variables';
|
||||
@import 'dev/scss/bootstrap-overrides.scss';
|
||||
@import 'dev/scss/wvc-theme/flatly/bootswatch';
|
||||
@import 'dev/scss//wvc-theme/flatly/variables';
|
||||
@import 'dev/scss//bootstrap-overrides.scss';
|
||||
@import 'dev/scss//wvc-theme/flatly/bootswatch';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Cerulean 4.5.3
|
||||
// Cerulean 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Cerulean 4.5.3
|
||||
// Cerulean 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Cosmo 4.5.3
|
||||
// Cosmo 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Cosmo 4.5.3
|
||||
// Cosmo 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Cyborg 4.5.3
|
||||
// Cyborg 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Cyborg 4.5.3
|
||||
// Cyborg 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Darkly 4.5.3
|
||||
// Darkly 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Darkly 4.5.3
|
||||
// Darkly 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -83,7 +83,7 @@ $dropdown-link-hover-bg: $primary !default;
|
|||
|
||||
// Navs
|
||||
|
||||
$nav-link-padding-x: 1.5rem !default;
|
||||
$nav-link-padding-x: 1.25rem !default;
|
||||
$nav-link-disabled-color: $gray-500 !default;
|
||||
$nav-tabs-border-color: $gray-700 !default;
|
||||
$nav-tabs-link-hover-border-color: $nav-tabs-border-color $nav-tabs-border-color transparent !default;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Flatly 4.5.3
|
||||
// Flatly 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Flatly 4.5.3
|
||||
// Flatly 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -66,7 +66,7 @@ $dropdown-link-hover-bg: $primary !default;
|
|||
// Navs
|
||||
|
||||
$nav-link-padding-y: .5rem !default !default;
|
||||
$nav-link-padding-x: 1.5rem !default;
|
||||
$nav-link-padding-x: 1.25rem !default;
|
||||
$nav-link-disabled-color: $gray-600 !default !default;
|
||||
$nav-tabs-border-color: $gray-200 !default;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Journal 4.5.3
|
||||
// Journal 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Journal 4.5.3
|
||||
// Journal 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Litera 4.5.3
|
||||
// Litera 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
// Navbar ======================================================================
|
||||
|
|
@ -24,20 +24,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Buttons =====================================================================
|
||||
|
||||
.btn {
|
||||
border-radius: 1.078em;
|
||||
|
||||
&-lg {
|
||||
border-radius: 2.688em;
|
||||
}
|
||||
|
||||
&-sm {
|
||||
border-radius: .844em;
|
||||
}
|
||||
}
|
||||
|
||||
// Typography ==================================================================
|
||||
|
||||
p {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Litera 4.5.3
|
||||
// Litera 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -65,15 +65,17 @@ $btn-font-family: $font-family-sans-serif !default;
|
|||
$btn-font-size: .875rem !default;
|
||||
$btn-font-size-sm: .688rem !default;
|
||||
|
||||
$btn-border-radius: 1.078em !default;
|
||||
$btn-border-radius-lg: 2.688em !default;
|
||||
$btn-border-radius-sm: .844em !default;
|
||||
|
||||
// Forms
|
||||
|
||||
$input-border-color: rgba(0, 0, 0, .1) !default;
|
||||
$input-group-addon-bg: $gray-200 !default !default;
|
||||
$input-border-color: rgba(0, 0, 0, .1) !default;
|
||||
$input-group-addon-bg: $gray-200 !default !default;
|
||||
|
||||
// Navbar
|
||||
|
||||
$navbar-padding-y: .7rem !default;
|
||||
|
||||
$navbar-dark-color: rgba($white, .6) !default;
|
||||
$navbar-dark-hover-color: $white !default;
|
||||
$navbar-light-hover-color: $body-color !default;
|
||||
|
|
@ -86,8 +88,8 @@ $tooltip-font-size: 11px !default;
|
|||
// Badges
|
||||
|
||||
$badge-font-weight: 400 !default;
|
||||
$badge-padding-y: .3em !default;
|
||||
$badge-padding-x: .6em !default;
|
||||
$badge-padding-y: .6em !default;
|
||||
$badge-padding-x: 1.2em !default;
|
||||
|
||||
// Alerts
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Lumen 4.5.3
|
||||
// Lumen 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Lumen 4.5.3
|
||||
// Lumen 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Lux 4.5.3
|
||||
// Lux 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ $web-font-path: "https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@400;6
|
|||
}
|
||||
|
||||
&-brand {
|
||||
margin-right: 1rem;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ $web-font-path: "https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@400;6
|
|||
}
|
||||
|
||||
.nav-item {
|
||||
margin-right: 1rem;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
// Buttons =====================================================================
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Lux 4.5.3
|
||||
// Lux 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -72,12 +72,12 @@ $input-btn-border-width: 0 !default;
|
|||
// Buttons
|
||||
|
||||
$btn-line-height: 1.5rem !default;
|
||||
$input-btn-padding-y: .6rem !default;
|
||||
$input-btn-padding-x: 1.2rem !default;
|
||||
$input-btn-padding-y-sm: .4rem !default;
|
||||
$input-btn-padding-x-sm: .8rem !default;
|
||||
$input-btn-padding-y-lg: 2rem !default;
|
||||
$input-btn-padding-x-lg: 2rem !default;
|
||||
$input-btn-padding-y: .5rem !default;
|
||||
$input-btn-padding-x: 1rem !default;
|
||||
$input-btn-padding-y-sm: .25rem !default;
|
||||
$input-btn-padding-x-sm: .75rem !default;
|
||||
$input-btn-padding-y-lg: 1rem !default;
|
||||
$input-btn-padding-x-lg: 1rem !default;
|
||||
$btn-font-weight: 600 !default;
|
||||
|
||||
// Forms
|
||||
|
|
@ -95,6 +95,7 @@ $navbar-light-color: rgba($black, .3) !default;
|
|||
$navbar-light-hover-color: $gray-900 !default;
|
||||
$navbar-light-active-color: $gray-900 !default;
|
||||
|
||||
|
||||
// Pagination
|
||||
|
||||
$pagination-border-color: transparent !default;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Materia 4.5.3
|
||||
// Materia 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
@ -287,7 +287,7 @@ select,
|
|||
select.form-control {
|
||||
appearance: none;
|
||||
padding: .5rem 0;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='4' viewBox='0 0 8 4'%3E%3Cpolygon fill='%23666' points='8 0 4 4 0 0'/%3E%3C/svg%3E%0A");
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='4' viewBox='0 0 8 4'%3e%3cpolygon fill='%23666' points='8 0 4 4 0 0'/%3e%3c/svg%3e%0a");
|
||||
background-size: 8px 4px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right center;
|
||||
|
|
@ -309,7 +309,7 @@ select.form-control {
|
|||
|
||||
&:focus {
|
||||
box-shadow: inset 0 -2px 0 $primary;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='4' viewBox='0 0 8 4'%3E%3Cpolygon fill='%23212121' points='8 0 4 4 0 0'/%3E%3C/svg%3E%0A");
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='4' viewBox='0 0 8 4'%3e%3cpolygon fill='%23212121' points='8 0 4 4 0 0'/%3e%3c/svg%3e%0a");
|
||||
}
|
||||
|
||||
&[multiple] {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Materia 4.5.3
|
||||
// Materia 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -54,12 +54,12 @@ $font-weight-base: 400 !default;
|
|||
|
||||
// Buttons
|
||||
|
||||
$input-btn-padding-y: .8rem !default;
|
||||
$input-btn-padding-y: .5rem !default;
|
||||
$input-btn-padding-x: 1rem !default;
|
||||
|
||||
// Forms
|
||||
|
||||
$input-padding-y: 1rem !default;
|
||||
$input-padding-y: .5rem !default;
|
||||
$input-padding-x: 0 !default;
|
||||
$input-padding-y-sm: 0 !default;
|
||||
$input-padding-x-sm: 0 !default;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Minty 4.5.3
|
||||
// Minty 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ $web-font-path: "https://fonts.googleapis.com/css2?family=Montserrat:wght@400;50
|
|||
|
||||
&-light,
|
||||
&-light:hover {
|
||||
color: $gray-700;
|
||||
color: $gray-900;
|
||||
}
|
||||
|
||||
&-link,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Minty 4.5.3
|
||||
// Minty 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -34,7 +34,7 @@ $success: $green !default;
|
|||
$info: $cyan !default;
|
||||
$warning: $yellow !default;
|
||||
$danger: $red !default;
|
||||
$light: $gray-100 !default;
|
||||
$light: $primary !default;
|
||||
$dark: $gray-800 !default;
|
||||
|
||||
$yiq-contrasted-threshold: 250 !default;
|
||||
|
|
@ -54,7 +54,6 @@ $border-radius-sm: .3rem !default;
|
|||
// stylelint-disable-next-line value-keyword-case
|
||||
$headings-font-family: Montserrat, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !default;
|
||||
$headings-color: $gray-700 !default;
|
||||
$font-size-base: .875rem !default;
|
||||
|
||||
// Tables
|
||||
|
||||
|
|
@ -67,8 +66,6 @@ $dropdown-link-hover-bg: $secondary !default;
|
|||
|
||||
// Navbar
|
||||
|
||||
$navbar-padding-y: .7rem !default;
|
||||
|
||||
$navbar-dark-color: rgba($white, .6) !default;
|
||||
$navbar-dark-hover-color: $white !default;
|
||||
$navbar-light-color: rgba($black, .3) !default;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Pulse 4.5.3
|
||||
// Pulse 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
// Buttons =====================================================================
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Pulse 4.5.3
|
||||
// Pulse 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Sandstone 4.5.3
|
||||
// Sandstone 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ $web-font-path: "https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;70
|
|||
}
|
||||
|
||||
.sandstone {
|
||||
font-size: 11px;
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Sandstone 4.5.3
|
||||
// Sandstone 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -51,7 +51,7 @@ $link-color: $success !default;
|
|||
|
||||
// stylelint-disable-next-line value-keyword-case
|
||||
$font-family-sans-serif: Roboto, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default;
|
||||
$font-size-base: .875rem !default;
|
||||
$font-size-base: .975rem !default;
|
||||
$headings-font-weight: 400 !default;
|
||||
|
||||
// Dropdowns
|
||||
|
|
@ -64,7 +64,7 @@ $dropdown-link-active-bg: $dropdown-link-hover-bg !default;
|
|||
|
||||
// Navs
|
||||
|
||||
$nav-link-padding-x: .9rem !default;
|
||||
$nav-link-padding-x: 1.25rem !default;
|
||||
$nav-link-disabled-color: $gray-300 !default;
|
||||
$nav-tabs-border-color: $gray-300 !default;
|
||||
$nav-tabs-link-hover-border-color: $gray-300 !default;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Simplex 4.5.3
|
||||
// Simplex 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Simplex 4.5.3
|
||||
// Simplex 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -54,7 +54,7 @@ $dropdown-link-hover-bg: $primary !default;
|
|||
|
||||
// Navs
|
||||
|
||||
$nav-link-padding-y: .7rem !default;
|
||||
$nav-link-padding-y: .9rem !default;
|
||||
$nav-link-disabled-color: $gray-400 !default;
|
||||
$nav-tabs-border-color: darken(#fff, 6.5%) !default;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Sketchy 4.5.3
|
||||
// Sketchy 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Sketchy 4.5.3
|
||||
// Sketchy 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Slate 4.5.3
|
||||
// Slate 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
@ -525,7 +525,7 @@ legend {
|
|||
}
|
||||
|
||||
.list-group {
|
||||
&-item:hover {
|
||||
&-item-action:hover {
|
||||
background-color: darken($gray-900, 5%);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Slate 4.5.3
|
||||
// Slate 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Solar 4.5.3
|
||||
// Solar 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Solar 4.5.3
|
||||
// Solar 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Spacelab 4.5.3
|
||||
// Spacelab 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Spacelab 4.5.3
|
||||
// Spacelab 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -51,14 +51,16 @@ $link-color: $info !default;
|
|||
|
||||
// stylelint-disable-next-line value-keyword-case
|
||||
$font-family-sans-serif: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default;
|
||||
$font-size-base: .9375rem !default;
|
||||
$font-size-sm: $font-size-base * .88 !default;
|
||||
$headings-font-weight: 300 !default;
|
||||
$headings-color: $gray-900 !default;
|
||||
|
||||
// Navbar
|
||||
|
||||
$navbar-padding-y: .7rem !default;
|
||||
$navbar-dark-color: rgba($white, .75) !default;
|
||||
$navbar-dark-hover-color: $white !default;
|
||||
$navbar-light-color: rgba($black, .4) !default;
|
||||
$navbar-light-hover-color: $info !default;
|
||||
$navbar-light-active-color: $info !default;
|
||||
|
||||
$navbar-padding-y: .7rem !default;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Superhero 4.5.3
|
||||
// Superhero 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Superhero 4.5.3
|
||||
// Superhero 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// United 4.5.3
|
||||
// United 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// United 4.5.3
|
||||
// United 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
@ -34,7 +34,7 @@ $success: $green !default;
|
|||
$info: $cyan !default;
|
||||
$warning: $yellow !default;
|
||||
$danger: $red !default;
|
||||
$light: $gray-200 !default;
|
||||
$light: $gray-100 !default;
|
||||
$dark: $purple !default;
|
||||
|
||||
$yiq-contrasted-threshold: 200 !default;
|
||||
|
|
@ -53,6 +53,13 @@ $font-family-sans-serif: Ubuntu, -apple-system, BlinkMacSystemFont, "Segoe
|
|||
$table-dark-bg: $dark !default;
|
||||
$table-dark-border-color: darken($dark, 5%) !default;
|
||||
|
||||
|
||||
// Navbar
|
||||
|
||||
$navbar-padding-y: .7rem !default;
|
||||
$navbar-padding-y: .7rem !default;
|
||||
|
||||
// Breadcrumb
|
||||
|
||||
$breadcrumb-padding-y: .75rem !default;
|
||||
$breadcrumb-padding-x: .25rem !default;
|
||||
$breadcrumb-item-padding: .25rem !default;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Yeti 4.5.3
|
||||
// Yeti 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Yeti 4.5.3
|
||||
// Yeti 4.6.0
|
||||
// Bootswatch
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -204,10 +204,6 @@ class Instance(models.Model):
|
|||
def formats(self):
|
||||
return self.proxy.get_image_formats()
|
||||
|
||||
@cached_property
|
||||
def interfaces(self):
|
||||
return self.proxy.get_ifaces()
|
||||
|
||||
|
||||
class PermissionSet(models.Model):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
{% for c_net in networks_host %}
|
||||
<option value="net:{{ c_net }}">Network {{ c_net }}</option>
|
||||
{% endfor %}
|
||||
{% for c_iface in instance.interfaces %}
|
||||
{% for c_iface in interfaces_host %}
|
||||
<option value="iface:{{ c_iface }}">Interface {{ c_iface }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
|
|
|||
|
|
@ -54,7 +54,14 @@
|
|||
{{ ipv4 }} |
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
<a class="text-secondary" href="{% url 'instances:instance' instance.id %}" title="{% trans 'Refresh instance info' %}"><span class="fa fa-refresh"></span></a>
|
||||
{% if instance.guest_agent_ready %}
|
||||
<a class="text-secondary" title="{% trans 'Show Instance OS details' %}" onclick="get_osinfo()">
|
||||
<span class="fa fa-info-circle"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
<a class="text-secondary" href="{% url 'instances:instance' instance.id %}" title="{% trans 'Refresh instance info' %}">
|
||||
<span class="fa fa-refresh"></span>
|
||||
</a>
|
||||
</div>
|
||||
{% if user_quota_msg %}
|
||||
<div class="alert alert-warning fade show">
|
||||
|
|
@ -71,13 +78,13 @@
|
|||
<ul class="nav nav-pills" id="navbtn" aria-label="Instance actions">
|
||||
<li class="nav-item">
|
||||
<a href="#power" class="nav-link action-button active" aria-controls="power" role="tab" data-toggle="tab">
|
||||
<i id="action-block" class="fa fa-power-off fa-2x" aria-hidden="true"></i>
|
||||
<span id="action-block" class="fa fa-power-off fa-2x" aria-hidden="true"></span>
|
||||
{% trans "Power" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#access" class="nav-link action-button" aria-controls="access" role="tab" data-toggle="tab">
|
||||
<i id="action-block" class="fa fa-lock" aria-hidden="true"></i>
|
||||
<span id="action-block" class="fa fa-lock" aria-hidden="true"></span>
|
||||
{% trans "Access" %}
|
||||
</a>
|
||||
</li>
|
||||
|
|
@ -684,7 +691,7 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
if (~$.inArray(hash, ['#boot_opt', "#disks", '#network', '#clone', '#xmledit', '#vncsettings', '#migrate', '#options', '#users'])) {
|
||||
if (~$.inArray(hash, ['#osinfo', '#boot_opt', "#disks", '#network', '#clone', '#xmledit', '#vncsettings', '#migrate', '#options', '#users'])) {
|
||||
var btnsect = $('#navbtn>li>a');
|
||||
$(btnsect).each(function () {
|
||||
if ($(this).attr('href') === '#settings') {
|
||||
|
|
@ -715,4 +722,22 @@
|
|||
});
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
function get_osinfo() {
|
||||
$('#navbtn a[href="#settings"]').tab('show');
|
||||
$('#settings a[href="#osinfo"]').tab('show');
|
||||
|
||||
$.getJSON('{% url 'instances:osinfo' instance.id %}', function (data) {
|
||||
$.each(data, function() {
|
||||
$('#oshostname').text(data['host-name']);
|
||||
$('#osname').text(data.id);
|
||||
$('#osprettyname').text(data['pretty-name']);
|
||||
$('#oskernelrelease').text(data['kernel-release']);
|
||||
$('#oskernelversion').text(data['kernel-version']);
|
||||
$('#osversion').text(data.version);
|
||||
$('#ostimezone').text(data.zone + " / " + data.offset);
|
||||
})
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -1,168 +1,166 @@
|
|||
{% load i18n %}
|
||||
<div role="tabpanel" class="tab-pane" id="access" aria-label="Instance access options">
|
||||
<div role="tabpanel">
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#vnconsole" aria-controls="vnconsole" role="tab"
|
||||
data-toggle="tab">
|
||||
{% trans "Console" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if app_settings.SHOW_ACCESS_ROOT_PASSWORD == 'True' %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#rootpasswd" aria-controls="rootpasswd" role="tab"
|
||||
data-toggle="tab">
|
||||
{% trans "Root Password" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if app_settings.SHOW_ACCESS_SSH_KEYS == 'True' %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#sshkeys" aria-controls="sshkeys" role="tab" data-toggle="tab">
|
||||
{% trans "SSH Keys" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if instance.status == 1 %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#vdiconsole" aria-controls="vdiconsole" role="tab"
|
||||
data-toggle="tab">
|
||||
{% trans "VDI" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="vnconsole">
|
||||
<p>{% blocktrans with type=instance.console_type|upper %} This action opens a new window with a {{ type }} connection to the console of the instance.{% endblocktrans %}
|
||||
</p>
|
||||
{% if instance.console_type == 'vnc' %}
|
||||
<div class="ml-3 form-row">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" type="checkbox" name="scale"
|
||||
{% if app_settings.CONSOLE_SCALE == 'True' %} checked {% endif %}
|
||||
id="scale">
|
||||
<label class="custom-control-label font-weight-bold" for="scale">{% trans "Scale" %}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-3 form-row">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" type="checkbox" name="view_only"
|
||||
{% if app_settings.CONSOLE_VIEW_ONLY == 'True' %} checked {% endif %}
|
||||
id="view_only">
|
||||
<label class="custom-control-label font-weight-bold" for="view_only">{% trans "View Only" %}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-3 form-row">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" type="checkbox" name="resize_session"
|
||||
{% if app_settings.CONSOLE_RESIZE_SESSION == 'True' %} checked {% endif %}
|
||||
id="resize_session">
|
||||
<label class="custom-control-label font-weight-bold" for="resize_session">{% trans "Resize Session" %}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-3 form-row">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" type="checkbox" name="clip_viewport"
|
||||
{% if app_settings.CONSOLE_CLIP_VIEWPORT == 'True' %} checked {% endif %}
|
||||
id="clip_viewport">
|
||||
<label class="custom-control-label font-weight-bold" for="clip_viewport">{% trans "View Clipboard" %}</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if instance.status == 1 %}
|
||||
<!-- Split button -->
|
||||
<div class="btn-group float-right">
|
||||
<button type="button" id="consoleBtnGroup" class="btn btn-lg btn-success"
|
||||
onclick="open_console('lite')">{% trans 'Console' %}</button>
|
||||
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="sr-only">{% trans 'Toggle Dropdown' %}</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#"
|
||||
title="{% trans "Console port" %}: {{ instance.console_port }}"
|
||||
onclick="open_console('lite')">{% trans "Console" %} - {% trans "Lite" %}</a>
|
||||
<a class="dropdown-item" href="#"
|
||||
title="{% trans "Console port" %}: {{ instance.console_port }}"
|
||||
onclick="open_console('full')">{% trans "Console" %} - {% trans "Full" %}</a>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#vnconsole" aria-controls="vnconsole" role="tab"
|
||||
data-toggle="tab">
|
||||
{% trans "Console" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if app_settings.SHOW_ACCESS_ROOT_PASSWORD == 'True' %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#rootpasswd" aria-controls="rootpasswd" role="tab"
|
||||
data-toggle="tab">
|
||||
{% trans "Root Password" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if app_settings.SHOW_ACCESS_SSH_KEYS == 'True' %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#sshkeys" aria-controls="sshkeys" role="tab" data-toggle="tab">
|
||||
{% trans "SSH Keys" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if instance.status == 1 %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#vdiconsole" aria-controls="vdiconsole" role="tab"
|
||||
data-toggle="tab">
|
||||
{% trans "VDI" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="vnconsole">
|
||||
<p>{% blocktrans with type=instance.console_type|upper %} This action opens a new window with a {{ type }} connection to the console of the instance.{% endblocktrans %}
|
||||
</p>
|
||||
{% if instance.console_type == 'vnc' %}
|
||||
<div class="ml-3 form-row">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" type="checkbox" name="scale"
|
||||
{% if app_settings.CONSOLE_SCALE == 'True' %} checked {% endif %}
|
||||
id="scale">
|
||||
<label class="custom-control-label font-weight-bold" for="scale">{% trans "Scale" %}</label>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Console" %}</button>
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% if app_settings.SHOW_ACCESS_ROOT_PASSWORD == 'True' %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="rootpasswd">
|
||||
<p>{% trans "You need shut down your instance and enter a new root password." %}</p>
|
||||
<form action="{% url 'instances:rootpasswd' instance.id %}" class="form-inline" method="post"
|
||||
role="form" aria-label="Add root password to instance form">
|
||||
{% csrf_token %}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<input type="text" class="form-control-lg" name="passwd"
|
||||
placeholder="{% trans "Enter Password" %}" maxlength="24">
|
||||
</div>
|
||||
<div class="ml-3 form-row">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" type="checkbox" name="view_only"
|
||||
{% if app_settings.CONSOLE_VIEW_ONLY == 'True' %} checked {% endif %}
|
||||
id="view_only">
|
||||
<label class="custom-control-label font-weight-bold" for="view_only">{% trans "View Only" %}</label>
|
||||
</div>
|
||||
{% if instance.status == 5 %}
|
||||
<input type="submit" class="btn btn-lg btn-success float-right" name="rootpasswd"
|
||||
value="{% trans "Reset Root Password" %}">
|
||||
{% else %}
|
||||
<button
|
||||
class="btn btn-lg btn-success float-right disabled">{% trans "Reset Root Password" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if app_settings.SHOW_ACCESS_SSH_KEYS == 'True' %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="sshkeys">
|
||||
<p>{% trans "You need shut down your instance and choose your public key." %}</p>
|
||||
<form action="{% url 'instances:add_public_key' instance.id %}" class="form-inline" method="post"
|
||||
role="form" aria-label="Add public key to instance form">
|
||||
{% csrf_token %}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<select name="sshkeyid" class="form-control-lg keyselect">
|
||||
{% if publickeys %}
|
||||
{% for key in publickeys %}
|
||||
<option value="{{ key.id }}">{{ key.keyname }}</option>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<option value="None">{% trans "None" %}</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-3 form-row">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" type="checkbox" name="resize_session"
|
||||
{% if app_settings.CONSOLE_RESIZE_SESSION == 'True' %} checked {% endif %}
|
||||
id="resize_session">
|
||||
<label class="custom-control-label font-weight-bold" for="resize_session">{% trans "Resize Session" %}</label>
|
||||
</div>
|
||||
{% if instance.status == 5 %}
|
||||
<input type="submit" class="btn btn-lg btn-success float-right" name="addpublickey"
|
||||
value="{% trans "Add Public Key" %}">
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Add Public Key" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-3 form-row">
|
||||
<div class="custom-control custom-switch">
|
||||
<input class="custom-control-input" type="checkbox" name="clip_viewport"
|
||||
{% if app_settings.CONSOLE_CLIP_VIEWPORT == 'True' %} checked {% endif %}
|
||||
id="clip_viewport">
|
||||
<label class="custom-control-label font-weight-bold" for="clip_viewport">{% trans "View Clipboard" %}</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if instance.status == 1 %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="vdiconsole">
|
||||
<p>{% trans "This action opens a remote viewer with a connection to the console of the instance." %}</p>
|
||||
<div class="input-group">
|
||||
<input type="text" class="input-lg disabled form-control" disabled id="vdi_url_input" />
|
||||
<span class="input-group-append">
|
||||
<a href="#" class="btn btn-success" id="vdi_url">{% trans "VDI" %}</a>
|
||||
</span>
|
||||
<!-- Split button -->
|
||||
<div class="btn-group float-right">
|
||||
<button type="button" id="consoleBtnGroup" class="btn btn-lg btn-success"
|
||||
onclick="open_console('lite')">{% trans 'Console' %}</button>
|
||||
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="sr-only">{% trans 'Toggle Dropdown' %}</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#"
|
||||
title="{% trans "Console port" %}: {{ instance.console_port }}"
|
||||
onclick="open_console('lite')">{% trans "Console" %} - {% trans "Lite" %}</a>
|
||||
<a class="dropdown-item" href="#"
|
||||
title="{% trans "Console port" %}: {{ instance.console_port }}"
|
||||
onclick="open_console('full')">{% trans "Console" %} - {% trans "Full" %}</a>
|
||||
</div>
|
||||
<p>{% trans "To download console.vv file for virt-viewer." %}</p>
|
||||
<a href="{% url 'instances:getvvfile' instance.id %}" class="btn btn-lg btn-success float-right">{% trans "Get console.vv" %}</a>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Console" %}</button>
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% if app_settings.SHOW_ACCESS_ROOT_PASSWORD == 'True' %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="rootpasswd">
|
||||
<p>{% trans "You need shut down your instance and enter a new root password." %}</p>
|
||||
<form action="{% url 'instances:rootpasswd' instance.id %}" class="form-inline" method="post"
|
||||
role="form" aria-label="Add root password to instance form">
|
||||
{% csrf_token %}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<input type="text" class="form-control-lg" name="passwd"
|
||||
placeholder="{% trans "Enter Password" %}" maxlength="24">
|
||||
</div>
|
||||
</div>
|
||||
{% if instance.status == 5 %}
|
||||
<input type="submit" class="btn btn-lg btn-success float-right" name="rootpasswd"
|
||||
value="{% trans "Reset Root Password" %}">
|
||||
{% else %}
|
||||
<button
|
||||
class="btn btn-lg btn-success float-right disabled">{% trans "Reset Root Password" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if app_settings.SHOW_ACCESS_SSH_KEYS == 'True' %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="sshkeys">
|
||||
<p>{% trans "You need shut down your instance and choose your public key." %}</p>
|
||||
<form action="{% url 'instances:add_public_key' instance.id %}" class="form-inline" method="post"
|
||||
role="form" aria-label="Add public key to instance form">
|
||||
{% csrf_token %}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<select name="sshkeyid" class="form-control-lg keyselect">
|
||||
{% if publickeys %}
|
||||
{% for key in publickeys %}
|
||||
<option value="{{ key.id }}">{{ key.keyname }}</option>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<option value="None">{% trans "None" %}</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% if instance.status == 5 %}
|
||||
<input type="submit" class="btn btn-lg btn-success float-right" name="addpublickey"
|
||||
value="{% trans "Add Public Key" %}">
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Add Public Key" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if instance.status == 1 %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="vdiconsole">
|
||||
<p>{% trans "This action opens a remote viewer with a connection to the console of the instance." %}</p>
|
||||
<div class="input-group">
|
||||
<input type="text" class="input-lg disabled form-control" disabled id="vdi_url_input" />
|
||||
<span class="input-group-append">
|
||||
<a href="#" class="btn btn-success" id="vdi_url">{% trans "VDI" %}</a>
|
||||
</span>
|
||||
</div>
|
||||
<p>{% trans "To download console.vv file for virt-viewer." %}</p>
|
||||
<a href="{% url 'instances:getvvfile' instance.id %}" class="btn btn-lg btn-success float-right">{% trans "Get console.vv" %}</a>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% block script %}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,27 @@
|
|||
{% load i18n %}
|
||||
<div role="tabpanel" class="tab-pane" id="undefine">
|
||||
<div role="tabpanel">
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance destroy menu">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#destroy" aria-controls="destroy" role="tab" data-toggle="tab">
|
||||
{% trans "Destroy Instance" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="destroy">
|
||||
<p>{% trans 'This action starts remove instance process' %}</p>
|
||||
{% if request.user.is_superuser or userinstance.is_delete %}
|
||||
{% if instance.status == 3 %}
|
||||
<a class="btn btn-lg btn-success disabled float-right">{% trans "Destroy" %}</a>
|
||||
{% else %}
|
||||
<a href="{% url 'instances:destroy' instance.id %}" class="btn btn-lg btn-success float-right">{% trans "Destroy" %}</a>
|
||||
{% endif %}
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance destroy menu">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#destroy" aria-controls="destroy" role="tab" data-toggle="tab">
|
||||
{% trans "Destroy Instance" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="destroy">
|
||||
<p>{% trans 'This action starts remove instance process' %}</p>
|
||||
{% if request.user.is_superuser or userinstance.is_delete %}
|
||||
{% if instance.status == 3 %}
|
||||
<a class="btn btn-lg btn-success disabled float-right">{% trans "Destroy" %}</a>
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success disabled float-right" name="delete">{% trans "Destroy" %}</button>
|
||||
<a href="{% url 'instances:destroy' instance.id %}" class="btn btn-lg btn-success float-right">{% trans "Destroy" %}</a>
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success disabled float-right" name="delete">{% trans "Destroy" %}</button>
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
20
instances/templates/instances/info_tab.html
Normal file
20
instances/templates/instances/info_tab.html
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{% load i18n %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="osinfo">
|
||||
<h3 class="page-header">{% trans "Guest Info" %}</h3>
|
||||
<dl class="mx-3 row">
|
||||
<dt class="col-3">{% trans "Hostname" %}</dt>
|
||||
<dd class="col-9" id="oshostname"></dd>
|
||||
<dt class="col-3">{% trans "OS Name" %}</dt>
|
||||
<dd class="col-9" id="osname"></dd>
|
||||
<dt class="col-3">{% trans "OS Pretty-Name" %}</dt>
|
||||
<dd class="col-9" id="osprettyname"></dd>
|
||||
<dt class="col-3">{% trans "Version" %}</dt>
|
||||
<dd class="col-9" id="osversion"></dd>
|
||||
<dt class="col-3">{% trans "Kernel Release" %}</dt>
|
||||
<dd class="col-9" id="oskernelrelease"></dd>
|
||||
<dt class="col-3">{% trans "Kernel Version" %}</dt>
|
||||
<dd class="col-9" id="oskernelversion"></dd>
|
||||
<dt class="col-3">{% trans "Timezone / Offset" %}</dt>
|
||||
<dd class="col-9" id="ostimezone"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
|
@ -1,131 +1,129 @@
|
|||
{% load i18n %}
|
||||
<div role="tabpanel" class="tab-pane active" id="power">
|
||||
<div role="tabpanel">
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance power actions">
|
||||
{% if instance.status == 1 %}
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance power actions">
|
||||
{% if instance.status == 1 %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#poweroff" aria-controls="poweroff" role="tab" data-toggle="tab">
|
||||
{% trans "Power Off" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#powercycle" aria-controls="powercycle" role="tab" data-toggle="tab">
|
||||
{% trans "Power Cycle" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#powerforce" aria-controls="powerforce" role="tab" data-toggle="tab">
|
||||
{% trans "Force Off" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if request.user.is_superuser %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#poweroff" aria-controls="poweroff" role="tab" data-toggle="tab">
|
||||
{% trans "Power Off" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#powercycle" aria-controls="powercycle" role="tab" data-toggle="tab">
|
||||
{% trans "Power Cycle" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#powerforce" aria-controls="powerforce" role="tab" data-toggle="tab">
|
||||
{% trans "Force Off" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if request.user.is_superuser %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#suspend" aria-controls="suspend" role="tab" data-toggle="tab">
|
||||
{% trans "Suspend" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if instance.status == 3 %}
|
||||
{% if request.user.is_superuser %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#resume" aria-controls="resume" role="tab" data-toggle="tab">
|
||||
{% trans "Resume" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#powerforce" aria-controls="powerforce" role="tab" data-toggle="tab">
|
||||
{% trans "Force Off" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if instance.status == 5 %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#boot" aria-controls="boot" role="tab" data-toggle="tab">
|
||||
{% trans "Power On" %}
|
||||
<a class="nav-link text-secondary" href="#suspend" aria-controls="suspend" role="tab" data-toggle="tab">
|
||||
{% trans "Suspend" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
{% if instance.status == 1 %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="poweroff">
|
||||
<p>{% trans "This action sends an ACPI shutdown signal to the instance." %}</p>
|
||||
<form action="{% url 'instances:poweroff' instance.id %}" method="post" role="form" aria-label0="Power off instance form">
|
||||
{% csrf_token %}
|
||||
<input type="submit" name="poweroff" class="btn btn-lg btn-success float-right" value="{% trans "Power Off" %}">
|
||||
{% endif %}
|
||||
{% if instance.status == 3 %}
|
||||
{% if request.user.is_superuser %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#resume" aria-controls="resume" role="tab" data-toggle="tab">
|
||||
{% trans "Resume" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#powerforce" aria-controls="powerforce" role="tab" data-toggle="tab">
|
||||
{% trans "Force Off" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if instance.status == 5 %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#boot" aria-controls="boot" role="tab" data-toggle="tab">
|
||||
{% trans "Power On" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
{% if instance.status == 1 %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="poweroff">
|
||||
<p>{% trans "This action sends an ACPI shutdown signal to the instance." %}</p>
|
||||
<form action="{% url 'instances:poweroff' instance.id %}" method="post" role="form" aria-label0="Power off instance form">
|
||||
{% csrf_token %}
|
||||
<input type="submit" name="poweroff" class="btn btn-lg btn-success float-right" value="{% trans "Power Off" %}">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="powercycle">
|
||||
<p>{% trans "This action forcibly powers off and start the instance and may cause data corruption." %}</p>
|
||||
<form action="{% url 'instances:powercycle' instance.id %}" method="post" role="form" aria-label="Power cycle instance form">{% csrf_token %}
|
||||
<input type="submit" name="powercycle" class="btn btn-lg btn-success float-right" value="{% trans "Power Cycle" %}">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="powerforce">
|
||||
<p>{% trans "This action forcibly powers off the instance and may cause data corruption." %}</p>
|
||||
<form action="{% url 'instances:force_off' instance.id %}" method="post" role="form" aria-label="Force to shotdown instance form">
|
||||
{% csrf_token %}
|
||||
<input type="submit" name="powerforce" class="btn btn-lg btn-success float-right" value="{% trans "Force Off" %}">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
{% if request.user.is_superuser %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="suspend">
|
||||
<p>{% trans "This action suspends the instance." %}</p>
|
||||
<form action="{% url 'instances:suspend' instance.id %}" method="post" role="form" aria-label="Suspend instance form">{% csrf_token %}
|
||||
<input type="submit" name="suspend" class="btn btn-lg btn-success float-right" value="{% trans "Suspend" %}">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="powercycle">
|
||||
<p>{% trans "This action forcibly powers off and start the instance and may cause data corruption." %}</p>
|
||||
<form action="{% url 'instances:powercycle' instance.id %}" method="post" role="form" aria-label="Power cycle instance form">{% csrf_token %}
|
||||
<input type="submit" name="powercycle" class="btn btn-lg btn-success float-right" value="{% trans "Power Cycle" %}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if instance.status == 3 %}
|
||||
{% if request.user.is_superuser %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
|
||||
<p>{% trans "This action restore the instance after suspend." %}</p>
|
||||
<form action="{% url 'instances:resume' instance.id %}" method="post" role="form" aria-label="Resume instance from suspension form">{% csrf_token %}
|
||||
<input type="submit" name="resume" class="btn btn-lg btn-success float-right" value="{% trans "Resume" %}">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="powerforce">
|
||||
<p>{% trans "This action forcibly powers off the instance and may cause data corruption." %}</p>
|
||||
<form action="{% url 'instances:force_off' instance.id %}" method="post" role="form" aria-label="Force to shotdown instance form">
|
||||
{% csrf_token %}
|
||||
<form action="{% url 'instances:force_off' instance.id %}" method="post" role="form" aria-label="Force to shutdown form">{% csrf_token %}
|
||||
<input type="submit" name="powerforce" class="btn btn-lg btn-success float-right" value="{% trans "Force Off" %}">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
{% if request.user.is_superuser %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="suspend">
|
||||
<p>{% trans "This action suspends the instance." %}</p>
|
||||
<form action="{% url 'instances:suspend' instance.id %}" method="post" role="form" aria-label="Suspend instance form">{% csrf_token %}
|
||||
<input type="submit" name="suspend" class="btn btn-lg btn-success float-right" value="{% trans "Suspend" %}">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if instance.status == 3 %}
|
||||
{% if request.user.is_superuser %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
|
||||
<p>{% trans "This action restore the instance after suspend." %}</p>
|
||||
<form action="{% url 'instances:resume' instance.id %}" method="post" role="form" aria-label="Resume instance from suspension form">{% csrf_token %}
|
||||
<input type="submit" name="resume" class="btn btn-lg btn-success float-right" value="{% trans "Resume" %}">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="powerforce">
|
||||
<p>{% trans "This action forcibly powers off the instance and may cause data corruption." %}</p>
|
||||
<form action="{% url 'instances:force_off' instance.id %}" method="post" role="form" aria-label="Force to shutdown form">{% csrf_token %}
|
||||
<input type="submit" name="powerforce" class="btn btn-lg btn-success float-right" value="{% trans "Force Off" %}">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
{% else %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
|
||||
<p>{% trans "Administrator blocked your instance." %}</p>
|
||||
<form action="{% url 'instances:resume' instance.id %}" method="post" role="form" aria-label="Resume instance form">{% csrf_token %}
|
||||
<button class="btn btn-lg btn-success disabled float-right">{% trans "Resume" %}</button>
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if instance.status == 5 %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="boot">
|
||||
<p>{% trans "Click on Power On button to start this instance." %}</p>
|
||||
<form action="{% url 'instances:poweron' instance.id %}" method="post" role="form" aria-label="Start instance form">
|
||||
{% csrf_token %}
|
||||
{% if instance.is_template %}
|
||||
<p>{% trans "Template instance cannot be started." %}</p>
|
||||
<input type="submit" name="poweron" class="btn btn-lg btn-success float-right disabled" value="{% trans "Power On" %}">
|
||||
{% else %}
|
||||
<input type="submit" name="poweron" class="btn btn-lg btn-success float-right" value="{% trans "Power On" %}">
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
|
||||
<p>{% trans "Administrator blocked your instance." %}</p>
|
||||
<form action="{% url 'instances:resume' instance.id %}" method="post" role="form" aria-label="Resume instance form">{% csrf_token %}
|
||||
<button class="btn btn-lg btn-success disabled float-right">{% trans "Resume" %}</button>
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if instance.status == 5 %}
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="boot">
|
||||
<p>{% trans "Click on Power On button to start this instance." %}</p>
|
||||
<form action="{% url 'instances:poweron' instance.id %}" method="post" role="form" aria-label="Start instance form">
|
||||
{% csrf_token %}
|
||||
{% if instance.is_template %}
|
||||
<p>{% trans "Template instance cannot be started." %}</p>
|
||||
<input type="submit" name="poweron" class="btn btn-lg btn-success float-right disabled" value="{% trans "Power On" %}">
|
||||
{% else %}
|
||||
<input type="submit" name="poweron" class="btn btn-lg btn-success float-right" value="{% trans "Power On" %}">
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,164 +1,162 @@
|
|||
{% load i18n %}
|
||||
<div role="tabpanel" class="tab-pane" id="resize">
|
||||
<div role="tabpanel">
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance resize options">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#resizevm_cpu" aria-controls="resizevm_cpu" role="tab" data-toggle="tab">
|
||||
{% trans "CPU" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#resizevm_mem" aria-controls="resizevm_mem" role="tab" data-toggle="tab">
|
||||
{% trans "Memory" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#resizevm_disk" aria-controls="resizevm_disk" role="tab" data-toggle="tab">
|
||||
{% trans "Disk" %}
|
||||
</a>
|
||||
</li>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resizevm_cpu">
|
||||
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
|
||||
{% if instance.status == 5 or not instance.vcpus %}
|
||||
<form action="{% url 'instances:resizevm_cpu' instance.id %}" method="post" role="form" aria-label="Resize instance cpu form">{% csrf_token %}
|
||||
<p class="font-weight-bold">{% trans "Logical host CPUs" %} : {{ vcpu_host }}</p>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label"> {% trans "Current Allocation" %}</label>
|
||||
<div class="col-sm-4">
|
||||
<select name="cur_vcpu" class="custom-select">
|
||||
{% for cpu in instance.vcpu_range %}
|
||||
{% if instance.cur_vcpu %}
|
||||
<option value="{{ cpu }}" {% if cpu == instance.cur_vcpu %}selected{% endif %}>{{ cpu }}</option>
|
||||
{% else %}
|
||||
<option value="{{ cpu }}" {% if cpu == instance.vcpu %}selected{% endif %}>{{ cpu }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">{% trans "Maximum Allocation" %}</label>
|
||||
<div class="col-sm-4">
|
||||
<select name="vcpu" class="custom-select">
|
||||
{% for cpu in instance.vcpu_range %}
|
||||
<option value="{{ cpu }}" {% if cpu == instance.vcpu %}selected{% endif %}>{{ cpu }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if instance.status == 5 %}
|
||||
<button type="submit" class="btn btn-lg btn-success float-right" name="resizevm_cpu">{% trans "Resize" %}</button>
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
{% else %}
|
||||
<p class="font-weight-bold">{% trans "Logical Instance Active/Maximum CPUs" %} : {{ instance.cur_vcpu }} / {{ instance.vcpu }} </p>
|
||||
<div class="col-sm-3"></div>
|
||||
<div class="col-sm-6">
|
||||
{% for id, vcpu in instance.vcpus.items %}
|
||||
<form action="{% url 'instances:set_vcpu' instance.id %}" method="post" role="form" aria-label="Resize instance cpu form">{% csrf_token %}
|
||||
<div class="col-sm-3">
|
||||
<input name="id" value="{{ id }}" hidden/>
|
||||
{% if vcpu.enabled == 'yes' and vcpu.hotpluggable == "yes" %}
|
||||
<button type="submit" class="btn btn-block btn-success" value="False" name="set_vcpu" title="{% trans "Disable" %}">{{ id }}</button>
|
||||
{% elif vcpu.enabled == 'yes' and vcpu.hotpluggable == "no" %}
|
||||
<button type="button" class="btn btn btn-block btn-info" title="{% trans "Constant" %}">{{ id }}</button>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance resize options">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#resizevm_cpu" aria-controls="resizevm_cpu" role="tab" data-toggle="tab">
|
||||
{% trans "CPU" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#resizevm_mem" aria-controls="resizevm_mem" role="tab" data-toggle="tab">
|
||||
{% trans "Memory" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#resizevm_disk" aria-controls="resizevm_disk" role="tab" data-toggle="tab">
|
||||
{% trans "Disk" %}
|
||||
</a>
|
||||
</li>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resizevm_cpu">
|
||||
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
|
||||
{% if instance.status == 5 or not instance.vcpus %}
|
||||
<form action="{% url 'instances:resizevm_cpu' instance.id %}" method="post" role="form" aria-label="Resize instance cpu form">{% csrf_token %}
|
||||
<p class="font-weight-bold">{% trans "Logical host CPUs" %} : {{ vcpu_host }}</p>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label"> {% trans "Current Allocation" %}</label>
|
||||
<div class="col-sm-4">
|
||||
<select name="cur_vcpu" class="custom-select">
|
||||
{% for cpu in instance.vcpu_range %}
|
||||
{% if instance.cur_vcpu %}
|
||||
<option value="{{ cpu }}" {% if cpu == instance.cur_vcpu %}selected{% endif %}>{{ cpu }}</option>
|
||||
{% else %}
|
||||
<button type="submit" class="btn btn btn-block btn-secondary" value="True" name="set_vcpu" title="{% trans "Enable" %}">{{ id }}</button>
|
||||
<option value="{{ cpu }}" {% if cpu == instance.vcpu %}selected{% endif %}>{{ cpu }}</option>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-3"></div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">{% trans "Maximum Allocation" %}</label>
|
||||
<div class="col-sm-4">
|
||||
<select name="vcpu" class="custom-select">
|
||||
{% for cpu in instance.vcpu_range %}
|
||||
<option value="{{ cpu }}" {% if cpu == instance.vcpu %}selected{% endif %}>{{ cpu }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if instance.status == 5 %}
|
||||
<button type="submit" class="btn btn-lg btn-success float-right" name="resizevm_cpu">{% trans "Resize" %}</button>
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% trans "You don't have permission for resizing instance" %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="resizevm_mem">
|
||||
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
|
||||
<form action="{% url 'instances:resize_memory' instance.id %}" method="post" role="form" aria-label="Resize instance memory form">
|
||||
{% csrf_token %}
|
||||
<p class="font-weight-bold">{% trans "Total host memory" %}: {{ memory_host|filesizeformat }}</p>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">{% trans "Current Allocation" %} ({% trans "MB" %})</label>
|
||||
<div class="col-sm-4 js-custom__container">
|
||||
<select name="cur_memory" class="custom-select js-custom__toggle">
|
||||
{% for mem in memory_range %}
|
||||
<option value="{{ mem }}" {% if mem == instance.cur_memory %}selected{% endif %}>{{ mem }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="text" name="cur_memory_custom" class="custom-select js-custom__toggle" style="display: none" />
|
||||
<small><input type="checkbox" class="js-custom__checkbox" /> {% trans "Custom value" %}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">
|
||||
{% trans "Maximum Allocation" %} ({% trans "MB" %})
|
||||
</label>
|
||||
<div class="col-sm-4 js-custom__container">
|
||||
<select name="memory" class="form-control js-custom__toggle">
|
||||
{% for mem in memory_range %}
|
||||
<option value="{{ mem }}"
|
||||
{% if mem == instance.memory %}selected{% endif %}>{{ mem }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="text" name="memory_custom" class="form-control js-custom__toggle" style="display: none" />
|
||||
<small><input type="checkbox" class="js-custom__checkbox" /> {% trans "Custom value" %}</small>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-lg btn-success float-right" name="resizevm_mem">{% trans "Resize" %}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
{% trans "You don't have permission for resizing instance" %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="resizevm_disk">
|
||||
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
|
||||
<form action="{% url 'instances:resize_disk' instance.id %}" method="post" role="form" aria-label="Resize instance disk form">
|
||||
{% csrf_token %}
|
||||
<p class="font-weight-bold">{% trans "Disk allocation (GB)" %}:</p>
|
||||
{% for disk in instance.disks %}
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">{% trans "Current Allocation" %} ({{ disk.dev }})</label>
|
||||
{% if disk.storage is None %}
|
||||
<div class="col-sm-4 js-custom__container">
|
||||
<div class="alert alert-danger">
|
||||
{% trans "Error getting disk info" %}
|
||||
</div>
|
||||
<p class="font-weight-bold">{% trans "Logical Instance Active/Maximum CPUs" %} : {{ instance.cur_vcpu }} / {{ instance.vcpu }} </p>
|
||||
<div class="col-sm-3"></div>
|
||||
<div class="col-sm-6">
|
||||
{% for id, vcpu in instance.vcpus.items %}
|
||||
<form action="{% url 'instances:set_vcpu' instance.id %}" method="post" role="form" aria-label="Resize instance cpu form">{% csrf_token %}
|
||||
<div class="col-sm-3">
|
||||
<input name="id" value="{{ id }}" hidden/>
|
||||
{% if vcpu.enabled == 'yes' and vcpu.hotpluggable == "yes" %}
|
||||
<button type="submit" class="btn btn-block btn-success" value="False" name="set_vcpu" title="{% trans "Disable" %}">{{ id }}</button>
|
||||
{% elif vcpu.enabled == 'yes' and vcpu.hotpluggable == "no" %}
|
||||
<button type="button" class="btn btn btn-block btn-info" title="{% trans "Constant" %}">{{ id }}</button>
|
||||
{% else %}
|
||||
<button type="submit" class="btn btn btn-block btn-secondary" value="True" name="set_vcpu" title="{% trans "Enable" %}">{{ id }}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-sm-4 js-custom__container">
|
||||
<input type="number" name="disk_size_{{ disk.dev }}" class="form-control" value="{% widthratio disk.size 1073741824 1 %}" />
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
{% endfor %}
|
||||
{% if instance.status == 5 %}
|
||||
<button type="submit" class="btn btn-lg btn-success float-right" name="resizevm_disk">{% trans "Resize" %}</button>
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% else %}
|
||||
{% trans "You don't have permission for resizing instance" %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
</div>
|
||||
<div class="col-sm-3"></div>
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% else %}
|
||||
{% trans "You don't have permission for resizing instance" %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="resizevm_mem">
|
||||
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
|
||||
<form action="{% url 'instances:resize_memory' instance.id %}" method="post" role="form" aria-label="Resize instance memory form">
|
||||
{% csrf_token %}
|
||||
<p class="font-weight-bold">{% trans "Total host memory" %}: {{ memory_host|filesizeformat }}</p>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">{% trans "Current Allocation" %} ({% trans "MB" %})</label>
|
||||
<div class="col-sm-4 js-custom__container">
|
||||
<select name="cur_memory" class="custom-select js-custom__toggle">
|
||||
{% for mem in memory_range %}
|
||||
<option value="{{ mem }}" {% if mem == instance.cur_memory %}selected{% endif %}>{{ mem }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="text" name="cur_memory_custom" class="custom-select js-custom__toggle" style="display: none" />
|
||||
<small><input type="checkbox" class="js-custom__checkbox" /> {% trans "Custom value" %}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">
|
||||
{% trans "Maximum Allocation" %} ({% trans "MB" %})
|
||||
</label>
|
||||
<div class="col-sm-4 js-custom__container">
|
||||
<select name="memory" class="form-control js-custom__toggle">
|
||||
{% for mem in memory_range %}
|
||||
<option value="{{ mem }}"
|
||||
{% if mem == instance.memory %}selected{% endif %}>{{ mem }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="text" name="memory_custom" class="form-control js-custom__toggle" style="display: none" />
|
||||
<small><input type="checkbox" class="js-custom__checkbox" /> {% trans "Custom value" %}</small>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-lg btn-success float-right" name="resizevm_mem">{% trans "Resize" %}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
{% trans "You don't have permission for resizing instance" %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="resizevm_disk">
|
||||
{% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
|
||||
<form action="{% url 'instances:resize_disk' instance.id %}" method="post" role="form" aria-label="Resize instance disk form">
|
||||
{% csrf_token %}
|
||||
<p class="font-weight-bold">{% trans "Disk allocation (GB)" %}:</p>
|
||||
{% for disk in instance.disks %}
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-4 col-form-label">{% trans "Current Allocation" %} ({{ disk.dev }})</label>
|
||||
{% if disk.storage is None %}
|
||||
<div class="col-sm-4 js-custom__container">
|
||||
<div class="alert alert-danger">
|
||||
{% trans "Error getting disk info" %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-sm-4 js-custom__container">
|
||||
<input type="number" name="disk_size_{{ disk.dev }}" class="form-control" value="{% widthratio disk.size 1073741824 1 %}" />
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if instance.status == 5 %}
|
||||
<button type="submit" class="btn btn-lg btn-success float-right" name="resizevm_disk">{% trans "Resize" %}</button>
|
||||
{% else %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% else %}
|
||||
{% trans "You don't have permission for resizing instance" %}
|
||||
<button class="btn btn-lg btn-success float-right disabled">{% trans "Resize" %}</button>
|
||||
{% endif %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,83 +1,81 @@
|
|||
{% load i18n %}
|
||||
{% load icons %}
|
||||
<div role="tabpanel" class="tab-pane" id="snapshots">
|
||||
<div role="tabpanel">
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance snapshot menu">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#takesnapshot" aria-controls="takesnapshot" role="tab" data-toggle="tab">
|
||||
{% trans "Take Snapshot" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#managesnapshot" aria-controls="managesnapshot" role="tab" data-toggle="tab">
|
||||
{% trans "Manage Snapshots" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="takesnapshot">
|
||||
<p>{% trans "This may take more than an hour, depending on how much content is on your instance and how large the disk is. It could cause web server timeout.." %}</p>
|
||||
<form action="{% url 'instances:snapshot' instance.id %}" class="form-inline" method="post" role="form" aria-label="Create snapshot form">
|
||||
{% csrf_token %}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<input type="text" class="form-control form-control-lg" name="name" placeholder="{% trans "Enter Snapshot Name" %}" maxlength="14">
|
||||
</div>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance snapshot menu">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#takesnapshot" aria-controls="takesnapshot" role="tab" data-toggle="tab">
|
||||
{% trans "Take Snapshot" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#managesnapshot" aria-controls="managesnapshot" role="tab" data-toggle="tab">
|
||||
{% trans "Manage Snapshots" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="takesnapshot">
|
||||
<p>{% trans "This may take more than an hour, depending on how much content is on your instance and how large the disk is. It could cause web server timeout.." %}</p>
|
||||
<form action="{% url 'instances:snapshot' instance.id %}" class="form-inline" method="post" role="form" aria-label="Create snapshot form">
|
||||
{% csrf_token %}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-12">
|
||||
<input type="text" class="form-control form-control-lg" name="name" placeholder="{% trans "Enter Snapshot Name" %}" maxlength="14">
|
||||
</div>
|
||||
<input type="submit" class="btn btn-lg btn-success float-right" name="snapshot" value="{% trans "Take Snapshot" %}" onclick="showPleaseWaitDialog();">
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="managesnapshot">
|
||||
{% if instance.snapshots %}
|
||||
<p>{% trans "Choose a snapshot for restore/delete" %}</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th scope="col">{% trans "Name" %}</th>
|
||||
<th scope="col">{% trans "Date" %}</th>
|
||||
<th scope="colgroup" colspan="2">{% trans "Action" %}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for snap in instance.snapshots %}
|
||||
<tr>
|
||||
<td><strong>{{ snap.name }}</strong></td>
|
||||
<td>{{ snap.date|date:"M d H:i:s" }}</td>
|
||||
<td style="width:30px;">
|
||||
<form action="{% url 'instances:revert_snapshot' instance.id %}" method="post" role="form" aria-label="Restore snapshot form">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="name" value="{{ snap.name }}">
|
||||
{% if instance.status == 5 %}
|
||||
<button type="submit" class="btn btn-sm btn-secondary" name="revert_snapshot" title="{% trans 'Revert to this Snapshot' %}" onclick="return confirm('Are you sure?')">
|
||||
<span class="fa fa-download"></span>
|
||||
</button>
|
||||
{% else %}
|
||||
<button type="button" class="btn btn-sm btn-secondary disabled"
|
||||
title="{% trans "To restore snapshots you need Power Off the instance." %}">
|
||||
<span class="fa fa-download"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
</td>
|
||||
<td style="width:30px;">
|
||||
<form action="{% url 'instances:delete_snapshot' instance.id %}" method="post" role="form" aria-label="Delete snapshot form">{% csrf_token %}
|
||||
<input type="hidden" name="name" value="{{ snap.name }}">
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="{% trans 'Delete Snapshot' %}" onclick="return confirm('{% trans "Are you sure?" %}')">
|
||||
{% icon 'trash' %}
|
||||
</div>
|
||||
<input type="submit" class="btn btn-lg btn-success float-right" name="snapshot" value="{% trans "Take Snapshot" %}" onclick="showPleaseWaitDialog();">
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="managesnapshot">
|
||||
{% if instance.snapshots %}
|
||||
<p>{% trans "Choose a snapshot for restore/delete" %}</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th scope="col">{% trans "Name" %}</th>
|
||||
<th scope="col">{% trans "Date" %}</th>
|
||||
<th scope="colgroup" colspan="2">{% trans "Action" %}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for snap in instance.snapshots %}
|
||||
<tr>
|
||||
<td><strong>{{ snap.name }}</strong></td>
|
||||
<td>{{ snap.date|date:"M d H:i:s" }}</td>
|
||||
<td style="width:30px;">
|
||||
<form action="{% url 'instances:revert_snapshot' instance.id %}" method="post" role="form" aria-label="Restore snapshot form">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="name" value="{{ snap.name }}">
|
||||
{% if instance.status == 5 %}
|
||||
<button type="submit" class="btn btn-sm btn-secondary" name="revert_snapshot" title="{% trans 'Revert to this Snapshot' %}" onclick="return confirm('Are you sure?')">
|
||||
<span class="fa fa-download"></span>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{% trans "You do not have any snapshots" %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<button type="button" class="btn btn-sm btn-secondary disabled"
|
||||
title="{% trans "To restore snapshots you need Power Off the instance." %}">
|
||||
<span class="fa fa-download"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
</form>
|
||||
</td>
|
||||
<td style="width:30px;">
|
||||
<form action="{% url 'instances:delete_snapshot' instance.id %}" method="post" role="form" aria-label="Delete snapshot form">{% csrf_token %}
|
||||
<input type="hidden" name="name" value="{{ snap.name }}">
|
||||
<button type="submit" class="btn btn-sm btn-danger" title="{% trans 'Delete Snapshot' %}" onclick="return confirm('{% trans "Are you sure?" %}')">
|
||||
{% icon 'trash' %}
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{% trans "You do not have any snapshots" %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,99 +1,97 @@
|
|||
{% load i18n %}
|
||||
<div role="tabpanel" class="tab-pane" id="graphics">
|
||||
<div role="tabpanel">
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance graphs and logs menu">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#graphs" id="graphtab" aria-controls="graphs" role="tab" data-toggle="tab" aria-controls="graphs" aria-selected="true">
|
||||
{% trans "Real Time" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#logs" id="logtab" aria-controls="logs" role="tab" data-toggle="tab" aria-controls="logs" onclick='update_logs_table("{{ instance.name }}");'>
|
||||
{% trans "Logs" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="graphs">
|
||||
<div class="mb-1 card border-success">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fa fa-long-arrow-right"></i>
|
||||
{% trans "CPU Usage" %}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="flot-chart">
|
||||
<div class="flot-chart-content" id="flot-moving-line-chart">
|
||||
<canvas id="cpuChart" width="735" height="160"></canvas>
|
||||
</div>
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-tabs" role="tablist" aria-label="Instance graphs and logs menu">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary active" href="#graphs" id="graphtab" aria-controls="graphs" role="tab" data-toggle="tab" aria-controls="graphs" aria-selected="true">
|
||||
{% trans "Real Time" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link text-secondary" href="#logs" id="logtab" aria-controls="logs" role="tab" data-toggle="tab" aria-controls="logs" onclick='update_logs_table("{{ instance.name }}");'>
|
||||
{% trans "Logs" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="graphs">
|
||||
<div class="mb-1 card border-success">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fa fa-long-arrow-right"></i>
|
||||
{% trans "CPU Usage" %}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="flot-chart">
|
||||
<div class="flot-chart-content" id="flot-moving-line-chart">
|
||||
<canvas id="cpuChart" width="735" height="160"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-1 card border-danger">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fa fa-long-arrow-right"></i>
|
||||
{% trans "Memory Usage" %}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="flot-chart">
|
||||
<div class="flot-chart-content" id="flot-moving-line-chart">
|
||||
<canvas id="memChart" width="735" height="160"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% for net in instance.networks %}
|
||||
<div class="mb-1 card border-info">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fa fa-long-arrow-right"></i>
|
||||
{% trans "Bandwidth Device" %}: eth{{ forloop.counter0 }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="flot-chart">
|
||||
<div class="flot-chart-content" id="flot-moving-line-chart">
|
||||
<canvas id="netEth{{ forloop.counter0 }}Chart" width="735" height="160"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for disk in instance.disks %}
|
||||
<div class="mb-1 card border-warning">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fa fa-long-arrow-right"></i>
|
||||
{% trans "Disk I/O device" %}: {{ disk.dev }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="flot-chart">
|
||||
<div class="flot-chart-content" id="flot-moving-line-chart">
|
||||
<canvas id="blk{{ disk.dev }}Chart" width="735" height="160"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="logs">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped sortable-theme-bootstrap" id="logs_table" data-sortable>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans "Date" %}</th>
|
||||
<th scope="col">{% trans "User" %}</th>
|
||||
<th scope="col">{% trans "Message" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="searchable">
|
||||
<tr>
|
||||
<td colspan="3"><i>{% trans 'None' %}...</i></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="mb-1 card border-danger">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fa fa-long-arrow-right"></i>
|
||||
{% trans "Memory Usage" %}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="flot-chart">
|
||||
<div class="flot-chart-content" id="flot-moving-line-chart">
|
||||
<canvas id="memChart" width="735" height="160"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% for net in instance.networks %}
|
||||
<div class="mb-1 card border-info">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fa fa-long-arrow-right"></i>
|
||||
{% trans "Bandwidth Device" %}: eth{{ forloop.counter0 }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="flot-chart">
|
||||
<div class="flot-chart-content" id="flot-moving-line-chart">
|
||||
<canvas id="netEth{{ forloop.counter0 }}Chart" width="735" height="160"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% for disk in instance.disks %}
|
||||
<div class="mb-1 card border-warning">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title"><i class="fa fa-long-arrow-right"></i>
|
||||
{% trans "Disk I/O device" %}: {{ disk.dev }}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="flot-chart">
|
||||
<div class="flot-chart-content" id="flot-moving-line-chart">
|
||||
<canvas id="blk{{ disk.dev }}Chart" width="735" height="160"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="logs">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped sortable-theme-bootstrap" id="logs_table" data-sortable>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans "Date" %}</th>
|
||||
<th scope="col">{% trans "User" %}</th>
|
||||
<th scope="col">{% trans "Message" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="searchable">
|
||||
<tr>
|
||||
<td colspan="3"><i>{% trans 'None' %}...</i></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ urlpatterns = [
|
|||
path('<int:pk>/migrate/', views.migrate, name='migrate'),
|
||||
path('<int:pk>/status/', views.status, name='status'),
|
||||
path('<int:pk>/stats/', views.stats, name='stats'),
|
||||
path('<int:pk>/osinfo/', views.osinfo, name='osinfo'),
|
||||
path('<int:pk>/rootpasswd/', views.set_root_pass, name='rootpasswd'),
|
||||
path('<int:pk>/add_public_key/', views.add_public_key, name='add_public_key'),
|
||||
path('<int:pk>/resizevm_cpu/', views.resizevm_cpu, name='resizevm_cpu'),
|
||||
|
|
|
|||
|
|
@ -169,17 +169,15 @@ def refr(compute):
|
|||
if compute.status is True:
|
||||
domains = compute.proxy.wvm.listAllDomains()
|
||||
domain_names = [d.name() for d in domains]
|
||||
domain_uuids = [d.UUIDString() for d in domains]
|
||||
# Delete instances that're not on host
|
||||
Instance.objects.filter(compute=compute).exclude(name__in=domain_names).delete()
|
||||
Instance.objects.filter(compute=compute).exclude(uuid__in=domain_uuids).delete()
|
||||
# Create instances that're not in DB
|
||||
names = Instance.objects.filter(compute=compute).values_list('name', flat=True)
|
||||
uuids = Instance.objects.filter(compute=compute).values_list('uuid', flat=True)
|
||||
for domain in domains:
|
||||
if domain.name() not in names:
|
||||
Instance(compute=compute, name=domain.name(), uuid=domain.UUIDString()).save()
|
||||
continue
|
||||
if domain.UUIDString() not in uuids:
|
||||
Instance(compute=compute, name=domain.name(), uuid=domain.UUIDString()).save()
|
||||
|
||||
|
||||
def get_dhcp_mac_address(vname):
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ from logs.views import addlogmsg
|
|||
from vrtManager import util
|
||||
from vrtManager.create import wvmCreate
|
||||
from vrtManager.instance import wvmInstances
|
||||
from vrtManager.interface import wvmInterface
|
||||
from vrtManager.storage import wvmStorage
|
||||
from vrtManager.util import randomPasswd
|
||||
|
||||
|
|
@ -121,6 +122,7 @@ def instance(request, pk):
|
|||
memory_host = instance.proxy.get_max_memory()
|
||||
bus_host = instance.proxy.get_disk_bus_types(instance.arch, instance.machine)
|
||||
networks_host = sorted(instance.proxy.get_networks())
|
||||
interfaces_host = sorted(instance.proxy.get_ifaces())
|
||||
nwfilters_host = instance.proxy.get_nwfilters()
|
||||
storages_host = sorted(instance.proxy.get_storages(True))
|
||||
net_models_host = instance.proxy.get_network_models()
|
||||
|
|
@ -161,6 +163,11 @@ def stats(request, pk):
|
|||
}
|
||||
)
|
||||
|
||||
def osinfo(request, pk):
|
||||
instance = get_instance(request.user, pk)
|
||||
results = instance.proxy.osinfo()
|
||||
|
||||
return JsonResponse(results)
|
||||
|
||||
def guess_mac_address(request, vname):
|
||||
data = {"vname": vname}
|
||||
|
|
@ -764,7 +771,7 @@ def revert_snapshot(request, pk):
|
|||
msg = _("Successful revert snapshot: ")
|
||||
msg += snap_name
|
||||
messages.success(request, msg)
|
||||
msg = _("Revert snapshot: %(snap)") % {"snap": snap_name}
|
||||
msg = _("Revert snapshot: %(snap)s") % {"snap": snap_name}
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
return redirect(request.META.get("HTTP_REFERER") + "#managesnapshot")
|
||||
|
||||
|
|
@ -882,7 +889,7 @@ def set_video_model(request, pk):
|
|||
instance = get_instance(request.user, pk)
|
||||
video_model = request.POST.get("video_model", "vga")
|
||||
instance.proxy.set_video_model(video_model)
|
||||
msg = _("Set Video Model: %(model)") % {"model": video_model}
|
||||
msg = _("Set Video Model: %(model)s") % {"model": video_model}
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
return redirect(request.META.get("HTTP_REFERER") + "#options")
|
||||
|
||||
|
|
@ -899,6 +906,16 @@ def change_network(request, pk):
|
|||
(source, source_type) = utils.get_network_tuple(request.POST.get(post))
|
||||
network_data[post] = source
|
||||
network_data[post + "-type"] = source_type
|
||||
|
||||
if source_type == 'iface':
|
||||
iface = wvmInterface(
|
||||
instance.compute.hostname,
|
||||
instance.compute.login,
|
||||
instance.compute.password,
|
||||
instance.compute.type,
|
||||
source,
|
||||
)
|
||||
network_data[post + "-type"] = iface.get_type()
|
||||
elif post.startswith("net-"):
|
||||
network_data[post] = request.POST.get(post, "")
|
||||
|
||||
|
|
@ -918,6 +935,16 @@ def add_network(request, pk):
|
|||
nwfilter = request.POST.get("add-net-nwfilter")
|
||||
(source, source_type) = utils.get_network_tuple(request.POST.get("add-net-network"))
|
||||
|
||||
if source_type == 'iface':
|
||||
iface = wvmInterface(
|
||||
instance.compute.hostname,
|
||||
instance.compute.login,
|
||||
instance.compute.password,
|
||||
instance.compute.type,
|
||||
source,
|
||||
)
|
||||
source_type = iface.get_type()
|
||||
|
||||
instance.proxy.add_network(mac, source, source_type, nwfilter=nwfilter)
|
||||
msg = _("Add network: %(mac)s") % {"mac": mac}
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ def interfaces(request, compute_id):
|
|||
netdevs = ["eth0", "eth1"]
|
||||
|
||||
for iface in ifaces:
|
||||
ifaces_all.append(conn.get_iface_info(iface))
|
||||
interf = wvmInterface(compute.hostname, compute.login, compute.password, compute.type, iface)
|
||||
ifaces_all.append(interf.get_details())
|
||||
|
||||
if request.method == "POST":
|
||||
if "create" in request.POST:
|
||||
|
|
|
|||
|
|
@ -296,12 +296,12 @@
|
|||
<button type="submit" class="btn btn-sm btn-primary"
|
||||
name="modify_fixed_address"
|
||||
title="{% trans "Edit entry" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
|
||||
<i class="fa fa-save"></i>
|
||||
<span class="fa fa-save"></span>
|
||||
</button>
|
||||
<button type="submit" class="btn btn-sm btn-danger"
|
||||
name="delete_fixed_address"
|
||||
title="{% trans "Delete entry" %}" onclick="return confirm('{% trans "Are you sure?" %}')">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span class="fa fa-trash"></span>
|
||||
</button>
|
||||
</td>
|
||||
</form>
|
||||
|
|
|
|||
2
static/css/wvc-main.min.css
vendored
2
static/css/wvc-main.min.css
vendored
File diff suppressed because one or more lines are too long
6
static/js/Chart.bundle.min.js
vendored
6
static/js/Chart.bundle.min.js
vendored
File diff suppressed because one or more lines are too long
8
static/js/bootstrap.bundle.min.js
vendored
8
static/js/bootstrap.bundle.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
static/js/jquery.js
vendored
4
static/js/jquery.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -1,3 +1,3 @@
|
|||
/*! js-cookie v2.2.0 | MIT */
|
||||
/*! js-cookie v2.2.1 | MIT */
|
||||
|
||||
!function(e){var n=!1;if("function"==typeof define&&define.amd&&(define(e),n=!0),"object"==typeof exports&&(module.exports=e(),n=!0),!n){var o=window.Cookies,t=window.Cookies=e();t.noConflict=function(){return window.Cookies=o,t}}}(function(){function e(){for(var e=0,n={};e<arguments.length;e++){var o=arguments[e];for(var t in o)n[t]=o[t]}return n}function n(o){function t(n,r,i){var c;if("undefined"!=typeof document){if(arguments.length>1){if("number"==typeof(i=e({path:"/"},t.defaults,i)).expires){var a=new Date;a.setMilliseconds(a.getMilliseconds()+864e5*i.expires),i.expires=a}i.expires=i.expires?i.expires.toUTCString():"";try{c=JSON.stringify(r),/^[\{\[]/.test(c)&&(r=c)}catch(e){}r=o.write?o.write(r,n):encodeURIComponent(r+"").replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),n=(n=(n=encodeURIComponent(n+"")).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent)).replace(/[\(\)]/g,escape);var s="";for(var f in i)i[f]&&(s+="; "+f,!0!==i[f]&&(s+="="+i[f]));return document.cookie=n+"="+r+s}n||(c={});for(var p=document.cookie?document.cookie.split("; "):[],d=/(%[0-9A-Z]{2})+/g,u=0;u<p.length;u++){var l=p[u].split("="),C=l.slice(1).join("=");this.json||'"'!==C.charAt(0)||(C=C.slice(1,-1));try{var m=l[0].replace(d,decodeURIComponent);if(C=o.read?o.read(C,m):o(C,m)||C.replace(d,decodeURIComponent),this.json)try{C=JSON.parse(C)}catch(e){}if(n===m){c=C;break}n||(c[m]=C)}catch(e){}}return c}}return t.set=t,t.get=function(e){return t.call(t,e)},t.getJSON=function(){return t.apply({json:!0},[].slice.call(arguments))},t.defaults={},t.remove=function(n,o){t(n,"",e(o,{expires:-1}))},t.withConverter=n,t}return n(function(){})});
|
||||
!function(a){var b;if("function"==typeof define&&define.amd&&(define(a),b=!0),"object"==typeof exports&&(module.exports=a(),b=!0),!b){var c=window.Cookies,d=window.Cookies=a();d.noConflict=function(){return window.Cookies=c,d}}}(function(){function a(){for(var a=0,b={};a<arguments.length;a++){var c=arguments[a];for(var d in c)b[d]=c[d]}return b}function b(a){return a.replace(/(%[0-9A-Z]{2})+/g,decodeURIComponent)}function c(d){function e(){}function f(b,c,f){if("undefined"!=typeof document){f=a({path:"/"},e.defaults,f),"number"==typeof f.expires&&(f.expires=new Date(1*new Date+864e5*f.expires)),f.expires=f.expires?f.expires.toUTCString():"";try{var g=JSON.stringify(c);/^[\{\[]/.test(g)&&(c=g)}catch(j){}c=d.write?d.write(c,b):encodeURIComponent(c+"").replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),b=encodeURIComponent(b+"").replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent).replace(/[\(\)]/g,escape);var h="";for(var i in f)f[i]&&(h+="; "+i,!0!==f[i]&&(h+="="+f[i].split(";")[0]));return document.cookie=b+"="+c+h}}function g(a,c){if("undefined"!=typeof document){for(var e={},f=document.cookie?document.cookie.split("; "):[],g=0;g<f.length;g++){var h=f[g].split("="),i=h.slice(1).join("=");c||'"'!==i.charAt(0)||(i=i.slice(1,-1));try{var j=b(h[0]);if(i=(d.read||d)(i,j)||b(i),c)try{i=JSON.parse(i)}catch(k){}if(e[j]=i,a===j)break}catch(k){}}return a?e[a]:e}}return e.set=f,e.get=function(a){return g(a,!1)},e.getJSON=function(a){return g(a,!0)},e.remove=function(b,c){f(b,"",a(c,{expires:-1}))},e.defaults={},e.withConverter=c,e}return c(function(){})});
|
||||
|
|
@ -482,7 +482,7 @@ class wvmConnect(object):
|
|||
|
||||
def get_networks(self):
|
||||
"""
|
||||
:return: list of networks
|
||||
:return: list of host networks
|
||||
"""
|
||||
virtnet = []
|
||||
for net in self.wvm.listNetworks():
|
||||
|
|
@ -493,7 +493,7 @@ class wvmConnect(object):
|
|||
|
||||
def get_ifaces(self):
|
||||
"""
|
||||
:return: list of network interfaces
|
||||
:return: list of host interfaces
|
||||
"""
|
||||
interface = []
|
||||
for inface in self.wvm.listInterfaces():
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import json
|
||||
import os.path
|
||||
import time
|
||||
|
||||
|
|
@ -20,6 +21,10 @@ try:
|
|||
VIR_MIGRATE_POSTCOPY,
|
||||
)
|
||||
from libvirt import VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT
|
||||
from libvirt_qemu import (
|
||||
qemuAgentCommand,
|
||||
VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT
|
||||
)
|
||||
except:
|
||||
from libvirt import libvirtError, VIR_DOMAIN_XML_SECURE, VIR_MIGRATE_LIVE
|
||||
|
||||
|
|
@ -160,6 +165,35 @@ class wvmInstance(wvmConnect):
|
|||
self._ip_cache = None
|
||||
self.instance = self.get_instance(vname)
|
||||
|
||||
def osinfo(self):
|
||||
info_results = qemuAgentCommand(
|
||||
self.instance,
|
||||
'{"execute":"guest-get-osinfo"}',
|
||||
VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT, 0
|
||||
)
|
||||
|
||||
timezone_results = qemuAgentCommand(
|
||||
self.instance,
|
||||
'{"execute":"guest-get-timezone"}',
|
||||
VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT, 0
|
||||
)
|
||||
|
||||
hostname_results = qemuAgentCommand(
|
||||
self.instance,
|
||||
'{"execute":"guest-get-host-name"}',
|
||||
VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT, 0
|
||||
)
|
||||
|
||||
info_results = json.loads(info_results).get('return')
|
||||
|
||||
timezone_results = json.loads(timezone_results).get('return')
|
||||
hostname_results = json.loads(hostname_results).get('return')
|
||||
|
||||
info_results.update(timezone_results)
|
||||
info_results.update(hostname_results)
|
||||
|
||||
return info_results
|
||||
|
||||
def start(self):
|
||||
self.instance.create()
|
||||
|
||||
|
|
@ -1332,19 +1366,15 @@ class wvmInstance(wvmConnect):
|
|||
return bridge_name
|
||||
|
||||
def add_network(self, mac_address, source, source_type="net", model="virtio", nwfilter=None):
|
||||
forward_mode = ""
|
||||
if source_type != "iface":
|
||||
forward_mode = self.get_network_forward(source)
|
||||
|
||||
if forward_mode in ["nat", "isolated", "routed"]:
|
||||
|
||||
if source_type == "net":
|
||||
interface_type = "network"
|
||||
elif forward_mode == "":
|
||||
interface_type = "direct"
|
||||
elif source_type == "bridge":
|
||||
interface_type = "bridge"
|
||||
else:
|
||||
if self.get_bridge_name(source, source_type) is None:
|
||||
interface_type = "network"
|
||||
else:
|
||||
interface_type = "bridge"
|
||||
interface_type = "direct"
|
||||
|
||||
# network modes not handled: default is bridge
|
||||
|
||||
xml_iface = f"""
|
||||
<interface type='{interface_type}'>
|
||||
|
|
@ -1352,13 +1382,11 @@ class wvmInstance(wvmConnect):
|
|||
if interface_type == "network":
|
||||
xml_iface += f"""<source network='{source}'/>"""
|
||||
elif interface_type == "direct":
|
||||
if source_type == "net":
|
||||
xml_iface += f"""<source network='{source}' mode='bridge'/>"""
|
||||
else:
|
||||
xml_iface += f"""<source dev='{source}' mode='bridge'/>"""
|
||||
xml_iface += f"""<source dev='{source}' mode='bridge'/>"""
|
||||
elif interface_type == "bridge":
|
||||
xml_iface += f"""<source bridge='{source}'/>"""
|
||||
else:
|
||||
bridge_name = self.get_bridge_name(source, source_type)
|
||||
xml_iface += f"""<source bridge='{bridge_name}'/>"""
|
||||
raise libvirtError(f"'{interface_type}' is an unexpected interface type.")
|
||||
xml_iface += f"""<model type='{model}'/>"""
|
||||
if nwfilter:
|
||||
xml_iface += f"""<filterref filter='{nwfilter}'/>"""
|
||||
|
|
@ -1382,8 +1410,35 @@ class wvmInstance(wvmConnect):
|
|||
self.instance.detachDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||
if self.get_status() == 5:
|
||||
self.instance.detachDeviceFlags(new_xml, VIR_DOMAIN_AFFECT_CONFIG)
|
||||
return new_xml
|
||||
return None
|
||||
|
||||
def change_network(self, network_data):
|
||||
net_mac = network_data.get("net-mac-0")
|
||||
net_source = network_data.get("net-source-0")
|
||||
net_source_type = network_data.get("net-source-0-type")
|
||||
net_filter = network_data.get("net-nwfilter-0")
|
||||
net_model = network_data.get("net-model-0")
|
||||
|
||||
# Remove interface first, but keep network interface XML definition
|
||||
# If there is an error happened while adding changed one, then add removed one to back.
|
||||
status = self.delete_network(net_mac)
|
||||
try:
|
||||
self.add_network(net_mac, net_source, net_source_type, net_model, net_filter)
|
||||
except libvirtError:
|
||||
if status is not None:
|
||||
if self.get_status() == 1:
|
||||
self.instance.attachDeviceFlags(status, VIR_DOMAIN_AFFECT_LIVE)
|
||||
self.instance.attachDeviceFlags(status, VIR_DOMAIN_AFFECT_CONFIG)
|
||||
if self.get_status() == 5:
|
||||
self.instance.attachDeviceFlags(status, VIR_DOMAIN_AFFECT_CONFIG)
|
||||
|
||||
|
||||
def change_network_oldway(self, network_data):
|
||||
'''
|
||||
change network firsh version...
|
||||
will be removed if new one works as expected for all scenarios
|
||||
'''
|
||||
xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE)
|
||||
tree = ElementTree.fromstring(xml)
|
||||
for num, interface in enumerate(tree.findall("devices/interface")):
|
||||
|
|
|
|||
|
|
@ -6,13 +6,6 @@ from vrtManager.connection import wvmConnect
|
|||
|
||||
|
||||
class wvmInterfaces(wvmConnect):
|
||||
def get_iface_info(self, name):
|
||||
iface = self.get_iface(name)
|
||||
xml = iface.XMLDesc(0)
|
||||
mac = iface.MACString()
|
||||
itype = util.get_xml_path(xml, "/interface/@type")
|
||||
state = iface.isActive()
|
||||
return {"name": name, "type": itype, "state": state, "mac": mac}
|
||||
|
||||
def define_iface(self, xml, flag=0):
|
||||
self.wvm.interfaceDefineXML(xml, flag)
|
||||
|
|
@ -153,6 +146,12 @@ class wvmInterface(wvmConnect):
|
|||
else:
|
||||
return None
|
||||
|
||||
def get_details(self):
|
||||
mac = self.get_mac()
|
||||
itype = self.get_type()
|
||||
state = self.is_active()
|
||||
return {"name": self.iface.name(), "type": itype, "state": state, "mac": mac}
|
||||
|
||||
def stop_iface(self):
|
||||
self.iface.destroy()
|
||||
|
||||
|
|
|
|||
|
|
@ -146,10 +146,12 @@ configure_nginx () {
|
|||
cp "$APP_PATH"/conf/nginx/webvirtcloud.conf /etc/nginx/conf.d/
|
||||
|
||||
if [ -n "$fqdn" ]; then
|
||||
sed -i "s|\\(#server_name\\).*|server_name = $fqdn|" "$nginxfile"
|
||||
fqdn_escape="$(echo -n "$fqdn"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
|
||||
sed -i "s|\\(#server_name\\).*|server_name $fqdn_escape;|" "$nginxfile"
|
||||
fi
|
||||
|
||||
sed -i "s|\\(server 127.0.0.1:\\).*|\\1$novncd_port;|" "$nginxfile"
|
||||
novncd_port_escape="$(echo -n "$novncd_port"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
|
||||
sed -i "s|\\(server 127.0.0.1:\\).*|\\1$novncd_port_escape;|" "$nginxfile"
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +159,8 @@ configure_supervisor () {
|
|||
# Copy template supervisor service for gunicorn and novnc
|
||||
echo " * Copying supervisor configuration"
|
||||
cp "$APP_PATH"/conf/supervisor/webvirtcloud.conf "$supervisor_conf_path"/"$supervisor_file_name"
|
||||
sed -i "s|^\\(user=\\).*|\\1$nginx_group|" "$supervisor_conf_path/$supervisor_file_name"
|
||||
nginx_group_escape="$(echo -n "$nginx_group"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
|
||||
sed -i "s|^\\(user=\\).*|\\1$nginx_group_escape|" "$supervisor_conf_path/$supervisor_file_name"
|
||||
}
|
||||
|
||||
create_user () {
|
||||
|
|
@ -206,13 +209,18 @@ install_webvirtcloud () {
|
|||
|
||||
secret_key=$(generate_secret_key)
|
||||
echo "* Secret for Django generated: $secret_key"
|
||||
tzone_escape="$(echo -n "$tzone"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
|
||||
secret_key_escape="$(echo -n "$secret_key"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
|
||||
novncd_port_escape="$(echo -n "$novncd_port"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
|
||||
novncd_public_port_escape="$(echo -n "$novncd_public_port"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
|
||||
novncd_host_escape="$(echo -n "$novncd_host"|sed -e 's/[](){}<>=:\!\?\+\|\/\&$*.^[]/\\&/g')"
|
||||
|
||||
#TODO escape SED delimiter in variables
|
||||
sed -i "s|^\\(TIME_ZONE = \\).*|\\1$tzone|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
sed -i "s|^\\(SECRET_KEY = \\).*|\\1\'$secret_key\'|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
sed -i "s|^\\(WS_PORT = \\).*|\\1$novncd_port|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
sed -i "s|^\\(WS_PUBLIC_PORT = \\).*|\\1$novncd_public_port|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
sed -i "s|^\\(WS_HOST = \\).*|\\1\'$novncd_host\'|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
sed -i "s|^\\(TIME_ZONE = \\).*|\\1$tzone_escape|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
sed -i "s|^\\(SECRET_KEY = \\).*|\\1\'$secret_key_escape\'|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
sed -i "s|^\\(WS_PORT = \\).*|\\1$novncd_port_escape|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
sed -i "s|^\\(WS_PUBLIC_PORT = \\).*|\\1$novncd_public_port_escape|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
sed -i "s|^\\(WS_HOST = \\).*|\\1\'$novncd_host_escape\'|" "$APP_PATH/webvirtcloud/settings.py"
|
||||
|
||||
echo "* Activate virtual environment."
|
||||
activate_python_environment
|
||||
|
|
@ -455,7 +463,7 @@ case $distro in
|
|||
log "yum -y install wget epel-release"
|
||||
|
||||
echo "* Installing OS requirements."
|
||||
PACKAGES="git python3-virtualenv python3-devel libvirt-devel glibc gcc nginx supervisor python3-lxml python3-libguestfs iproute-tc cyrus-sasl-md5 python3-libguestfs"
|
||||
PACKAGES="git python3-virtualenv python3-devel libvirt-devel glibc gcc nginx supervisor python3-lxml python3-libguestfs iproute-tc cyrus-sasl-md5"
|
||||
install_packages
|
||||
|
||||
set_hosts
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue