mirror of
https://github.com/unraid/webgui.git
synced 2026-01-02 23:50:21 -06:00
Merge branch 'master' into refactor/web-component-updates
This commit is contained in:
77
.vscode/settings.json
vendored
77
.vscode/settings.json
vendored
@@ -4,5 +4,80 @@
|
||||
},
|
||||
"prettier.tabWidth": 4,
|
||||
"editor.tabSize": 4,
|
||||
"editor.indentSize": "tabSize"
|
||||
"editor.indentSize": "tabSize",
|
||||
"intelephense.stubs": [
|
||||
"apache",
|
||||
"bcmath",
|
||||
"bz2",
|
||||
"calendar",
|
||||
"com_dotnet",
|
||||
"Core",
|
||||
"ctype",
|
||||
"curl",
|
||||
"date",
|
||||
"dba",
|
||||
"dom",
|
||||
"enchant",
|
||||
"exif",
|
||||
"FFI",
|
||||
"fileinfo",
|
||||
"filter",
|
||||
"fpm",
|
||||
"ftp",
|
||||
"gd",
|
||||
"gettext",
|
||||
"gmp",
|
||||
"hash",
|
||||
"iconv",
|
||||
"imap",
|
||||
"intl",
|
||||
"json",
|
||||
"ldap",
|
||||
"libxml",
|
||||
"mbstring",
|
||||
"meta",
|
||||
"mysqli",
|
||||
"oci8",
|
||||
"odbc",
|
||||
"openssl",
|
||||
"pcntl",
|
||||
"pcre",
|
||||
"PDO",
|
||||
"pdo_ibm",
|
||||
"pdo_mysql",
|
||||
"pdo_pgsql",
|
||||
"pdo_sqlite",
|
||||
"pgsql",
|
||||
"Phar",
|
||||
"posix",
|
||||
"pspell",
|
||||
"random",
|
||||
"readline",
|
||||
"Reflection",
|
||||
"session",
|
||||
"shmop",
|
||||
"SimpleXML",
|
||||
"snmp",
|
||||
"soap",
|
||||
"sockets",
|
||||
"sodium",
|
||||
"SPL",
|
||||
"sqlite3",
|
||||
"standard",
|
||||
"superglobals",
|
||||
"sysvmsg",
|
||||
"sysvsem",
|
||||
"sysvshm",
|
||||
"tidy",
|
||||
"tokenizer",
|
||||
"xml",
|
||||
"xmlreader",
|
||||
"xmlrpc",
|
||||
"xmlwriter",
|
||||
"xsl",
|
||||
"Zend OPcache",
|
||||
"zip",
|
||||
"zlib",
|
||||
"libvirt-php"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1527,6 +1527,12 @@ The display settings below determine how items are displayed on screen. Use thes
|
||||
You can experiment with these settings as desired, they only affect visual properties.
|
||||
:end
|
||||
|
||||
:display_width_help:
|
||||
**Boxed** is the legacy setting which constrains the content width to maximum 1920 pixels
|
||||
|
||||
**Unlimited** allows content to use all available width, which maybe useful on wide screens
|
||||
:end
|
||||
|
||||
:display_font_size_help:
|
||||
Changes the font size in the GUI. This is a per device setting.
|
||||
:end
|
||||
@@ -1581,6 +1587,10 @@ Make sure any newly entered values represent the selected temperature unit.
|
||||
Stopping the VM Manager will first attempt to shutdown all running VMs. After 60 seconds, any remaining VM instances will be terminated.
|
||||
:end
|
||||
|
||||
:vms_disable_help:
|
||||
Stop VMs from Autostarting\Starting when VM Manager starts or open is run from the gui to start, error message will be seen.
|
||||
:end
|
||||
|
||||
:vms_libvirt_volume_help:
|
||||
This is the libvirt volume.
|
||||
:end
|
||||
|
||||
@@ -3,8 +3,8 @@ Title="UPS Details"
|
||||
Tag="battery-3"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015, Dan Landon.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
||||
@@ -5,8 +5,8 @@ Icon="icon-ups"
|
||||
Tag="battery-3"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015, Dan Landon.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -22,13 +22,6 @@ Tag="battery-3"
|
||||
$sName = "dynamix.apcupsd";
|
||||
$cfg = parse_plugin_cfg($sName);
|
||||
?>
|
||||
|
||||
<style>
|
||||
table.ups thead tr th{width:16.6%;padding-left:10px}
|
||||
table.ups tbody tr td{padding-left:10px;font-weight:bold}
|
||||
tr.ups{height:3rem;line-height:3rem}
|
||||
i.ups{margin-right:8px}
|
||||
</style>
|
||||
<script>
|
||||
function toggleCustomCable(form) {
|
||||
var readonly = form.UPSCABLE.value != 'custom';
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'settings';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015, Dan Landon.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
||||
4
emhttp/plugins/dynamix.apcupsd/sheets/UPSsettings.css
Normal file
4
emhttp/plugins/dynamix.apcupsd/sheets/UPSsettings.css
Normal file
@@ -0,0 +1,4 @@
|
||||
table.ups thead tr th{width:16.6%;padding-left:10px}
|
||||
table.ups tbody tr td{padding-left:10px;font-weight:bold}
|
||||
tr.ups{height:3rem;line-height:3rem}
|
||||
i.ups{margin-right:8px}
|
||||
@@ -3,9 +3,9 @@ Cond="(pgrep('dockerd')!==false)"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2014-2020, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -5,7 +5,8 @@ Lock="true"
|
||||
Cond="exec(\"grep -o '^DOCKER_ENABLED=.yes' /boot/config/docker.cfg 2>/dev/null\")"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
||||
@@ -7,8 +7,8 @@ Nchan="docker_load:stop"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2014-2023, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -29,20 +29,7 @@ $cpus = cpu_list();
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.ui.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/plugins/dynamix.docker.manager/styles/style-$theme.css")?>">
|
||||
<style>
|
||||
.basic{display:block}
|
||||
.advanced{display:none;white-space:nowrap}
|
||||
.log{cursor:zoom-in}
|
||||
.exec{cursor:pointer}
|
||||
table#docker_containers{text-align:left}
|
||||
th.five{width:5%}
|
||||
th.nine{width:9%}
|
||||
th.load{width:140px}
|
||||
input.wait{width:24px;margin:0 4px;padding:0 5px;border:none;box-shadow:none;background-color:transparent}
|
||||
table tbody td{line-height:normal}
|
||||
i.mover{margin-right:8px;display:none}
|
||||
#resetsort{margin-left:12px;display:inline-block;width:32px}
|
||||
</style>
|
||||
|
||||
<table id="docker_containers" class="tablesorter shift">
|
||||
<thead><tr><th><a id="resetsort" class="nohand" onclick="resetSorting()" title="_(Reset sorting)_"><i class="fa fa-th-list"></i></a>_(Application)_</th><th>_(Version)_</th><th>_(Network)_</th><th>_(Port Mappings)_ <small>(_(App to Host)_)</small></th><th>_(Volume Mappings)_ <small>(_(App to Host)_)</small></th><th class="load advanced">_(CPU & Memory load)_</th><th class="nine">_(Autostart)_</th><th class="five">_(Uptime)_</th></tr></thead>
|
||||
<tbody id="docker_list"><tr><td colspan='8'></td></tr></tbody>
|
||||
|
||||
@@ -5,8 +5,8 @@ Tag="icon-docker"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2014-2023, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -106,31 +106,6 @@ $bgcolor = strstr('white,azure',$display['theme']) ? '#f2f2f2' : '#1c1c1c';
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.filetree.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<style>
|
||||
.errortext{color:#EF3D47;display:none;margin-left:20px}
|
||||
.fileTree{background:<?=$bgcolor?>;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:absolute;z-index:100;display:none}
|
||||
.basic{display:inline-block}
|
||||
.advanced{display:none}
|
||||
select.mask{min-width:0;margin:0 10px 0 4px}
|
||||
select.net{min-width:0;margin:0 4px 0 2px}
|
||||
select option.hide{display:none}
|
||||
input.ip4{width:100px;margin:0 4px 0 1px}
|
||||
input.ip6{width:140px;margin:0 4px}
|
||||
input.gw4{width:100px;margin:0 4px 0 1px}
|
||||
input.gw6{width:160px;margin:0 4px}
|
||||
input.pool6{width:40px;margin:0 4px 0 1px}
|
||||
span.net{margin-left:4px;margin-right:2px}
|
||||
span.ip4{display:inline-block;width:260px}
|
||||
span.ip6{display:inline-block;width:310px}
|
||||
span.gw4{display:inline-block;width:200px}
|
||||
span.gw6{display:inline-block;width:270px}
|
||||
span.nonexist{margin-left:20px}
|
||||
<?if (strstr('white,azure',$display['theme'])):?>
|
||||
span.disabled{color:#B0B0B0}
|
||||
<?else:?>
|
||||
span.disabled{color:#404040}
|
||||
<?endif;?>
|
||||
</style>
|
||||
<span class="status vhshift"><input type="checkbox" class="advancedview"></span>
|
||||
|
||||
<form markdown="1" id="settingsForm" name="settingsForm" method="POST" action="/update.php" target="progressFrame" onsubmit="return prepareDocker(this)">
|
||||
@@ -257,16 +232,14 @@ _(Template Authoring Mode)_:
|
||||
|
||||
:docker_authoring_mode_help:
|
||||
|
||||
<?if ($bridge):?>
|
||||
_(Docker custom network type)_:
|
||||
: <select name="DOCKER_NETWORK_TYPE">
|
||||
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '1', _('ipvlan'))?>
|
||||
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '', _('macvlan'))?>
|
||||
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '1', _('ipvlan'), $bridge?'':'disabled')?>
|
||||
<?=mk_option(_var($dockercfg,'DOCKER_NETWORK_TYPE'), '', _('macvlan'), $bridge?'':'selected')?>
|
||||
</select> _(Please read the Help carefully)_. _(Misconfiguration can cause problems)_.
|
||||
|
||||
:docker_custom_network_type_help:
|
||||
|
||||
<?endif;?>
|
||||
_(Host access to custom networks)_:
|
||||
: <select name="DOCKER_ALLOW_ACCESS">
|
||||
<?=mk_option(_var($dockercfg,'DOCKER_ALLOW_ACCESS'), '', _('Disabled'))?>
|
||||
@@ -465,13 +438,11 @@ _(Docker LOG rotation)_:
|
||||
|
||||
:docker_log_rotation_active_help:
|
||||
|
||||
<?if ($bridge):?>
|
||||
_(Docker custom network type)_:
|
||||
: <?=_var($dockercfg,'DOCKER_NETWORK_TYPE')=='1' ? _('ipvlan') : _('macvlan')?>
|
||||
: <?=_var($dockercfg,'DOCKER_NETWORK_TYPE')!='1' || !$bridge ? _('macvlan') : _('ipvlan')?>
|
||||
|
||||
:docker_custom_network_type_help:
|
||||
|
||||
<?endif;?>
|
||||
_(Host access to custom networks)_:
|
||||
: <?=_var($dockercfg,'DOCKER_ALLOW_ACCESS')=='yes' ? _('Enabled') : _('Disabled')?>
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ Cond="(pgrep('dockerd')!==false)"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2014-2020, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2014-2022, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2022, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
$user_prefs = $dockerManPaths['user-prefs'];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2015-2023, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,10 +12,8 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
libxml_use_internal_errors(true);
|
||||
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
|
||||
@@ -277,18 +275,6 @@ $bgcolor = strstr('white,azure',$display['theme']) ? '#f2f2f2' : '#1c1c1c';
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.filetree.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/plugins/dynamix.docker.manager/styles/style-{$display['theme']}.css")?>">
|
||||
|
||||
<style>
|
||||
.noshow,.advanced{display:none}
|
||||
.fileTree{width:240px;max-height:200px;overflow-y:scroll;overflow-x:hidden;position:absolute;display:none;background:<?=$bgcolor?>}
|
||||
.required:after{content:" *";color:#E80000}
|
||||
span.boxed{display:inline-block;line-height:normal;white-space:normal;width:56%}
|
||||
span.cpu,label.checkbox{display:inline-block;width:32px}
|
||||
span.ct{display:inline-block;width:230px}
|
||||
span.net{display:inline-block;width:120px}
|
||||
span.ip{display:inline-block;width:160px}
|
||||
dl,dt,dd{line-height:normal!important}
|
||||
</style>
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
||||
<script src="<?autov('/webGui/javascript/jquery.filetree.js')?>" charset="utf-8"></script>
|
||||
<script src="<?autov('/plugins/dynamix.vm.manager/javascript/dynamix.vm.manager.js')?>"></script>
|
||||
@@ -386,6 +372,13 @@ function getVal(el, name) {
|
||||
}
|
||||
}
|
||||
|
||||
function dialogStyle() {
|
||||
$('.ui-dialog-titlebar-close').css({'display':'none'});
|
||||
$('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'});
|
||||
$('.ui-dialog-content').css({'padding-top':'15px','vertical-align':'bottom'});
|
||||
$('.ui-button-text').css({'padding':'0px 5px'});
|
||||
}
|
||||
|
||||
function addConfigPopup() {
|
||||
var title = "_(Add Configuration)_";
|
||||
var popup = $("#dialogAddConfig");
|
||||
@@ -403,11 +396,10 @@ function addConfigPopup() {
|
||||
// Start Dialog section
|
||||
popup.dialog({
|
||||
title: title,
|
||||
height: 'auto',
|
||||
width: 900,
|
||||
resizable: false,
|
||||
width: 800,
|
||||
modal: true,
|
||||
show : {effect: 'fade' , duration: 250},
|
||||
hide : {effect: 'fade' , duration: 250},
|
||||
buttons: {
|
||||
"_(Add)_": function() {
|
||||
$(this).dialog("close");
|
||||
@@ -439,11 +431,7 @@ function addConfigPopup() {
|
||||
}
|
||||
}
|
||||
});
|
||||
$(".ui-dialog .ui-dialog-titlebar").addClass('menu');
|
||||
$('.ui-dialog .ui-dialog-titlebar-close').css({'display':'none'});
|
||||
$(".ui-dialog .ui-dialog-title").css({'text-align':'center','width':'100%'});
|
||||
$(".ui-dialog .ui-dialog-content").css({'padding-top':'15px','vertical-align':'bottom'});
|
||||
$(".ui-button-text").css({'padding':'0px 5px'});
|
||||
dialogStyle();
|
||||
}
|
||||
|
||||
function editConfigPopup(num,disabled) {
|
||||
@@ -477,11 +465,10 @@ function editConfigPopup(num,disabled) {
|
||||
popup.find(".switch-button-background").css("margin-top", "6px");
|
||||
popup.dialog({
|
||||
title: title,
|
||||
height: 'auto',
|
||||
width: 900,
|
||||
resizable: false,
|
||||
width: 800,
|
||||
modal: true,
|
||||
show: {effect:'fade', duration: 250},
|
||||
hide: {effect:'fade', duration: 250},
|
||||
buttons: {
|
||||
"_(Save)_": function() {
|
||||
$(this).dialog("close");
|
||||
@@ -522,11 +509,7 @@ function editConfigPopup(num,disabled) {
|
||||
}
|
||||
}
|
||||
});
|
||||
$(".ui-dialog .ui-dialog-titlebar").addClass('menu');
|
||||
$('.ui-dialog .ui-dialog-titlebar-close').css({'display':'none'});
|
||||
$(".ui-dialog .ui-dialog-title").css({'text-align':'center','width':'100%'});
|
||||
$(".ui-dialog .ui-dialog-content").css({'padding-top':'15px','vertical-align':'bottom'});
|
||||
$(".ui-button-text").css({'padding':'0px 5px'});
|
||||
dialogStyle();
|
||||
$('.desc_readmore').readmore({maxHeight:10});
|
||||
}
|
||||
|
||||
@@ -1009,7 +992,7 @@ _(Password Mask)_:
|
||||
<input type="hidden" name="confRequired[]" value="{7}">
|
||||
<input type="hidden" name="confMask[]" value="{8}">
|
||||
<span class="{11}">{0}:</span>
|
||||
: <span class="boxed"><input type="text" name="confValue[]" default="{2}" value="{9}" autocomplete="off" spellcheck="false" {11}>{10}<br><span class='orange-text'>{12}: {1}</span><br><span class="orange-text">{4}</span><br>
|
||||
: <span class="boxed"><input type="text" class="setting_input" name="confValue[]" default="{2}" value="{9}" autocomplete="off" spellcheck="false" {11}>{10}<br><span class='orange-text'>{12}: {1}</span><br><span class="orange-text">{4}</span><br></span>
|
||||
</div>
|
||||
|
||||
<div markdown="1" id="templateAllocations" style="display:none">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2014-2023, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,10 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
libxml_use_internal_errors(true); # Suppress any warnings from xml errors.
|
||||
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
|
||||
@@ -56,8 +53,8 @@ if (file_exists($docker_cfgfile) && exec("grep -Pom1 '_{$port}(_[0-9]+)?=' $dock
|
||||
exec("sed -ri 's/_(BR0|BOND0|ETH0)(_[0-9]+)?=/_{$port}\\2=/' $docker_cfgfile");
|
||||
}
|
||||
|
||||
$defaults = @parse_ini_file("$docroot/plugins/dynamix.docker.manager/default.cfg") ?: [];
|
||||
$dockercfg = array_replace_recursive($defaults, @parse_ini_file($docker_cfgfile) ?: []);
|
||||
$defaults = (array)@parse_ini_file("$docroot/plugins/dynamix.docker.manager/default.cfg");
|
||||
$dockercfg = array_replace_recursive($defaults, (array)@parse_ini_file($docker_cfgfile));
|
||||
|
||||
function var_split($item, $i=0) {
|
||||
return array_pad(explode(' ',$item),$i+1,'')[$i];
|
||||
@@ -353,7 +350,6 @@ class DockerTemplates {
|
||||
if (!$imgUrl) $imgUrl = $tmpIconUrl;
|
||||
if (!$imgUrl || trim($imgUrl) == "/plugins/dynamix.docker.manager/images/question.png") return '';
|
||||
|
||||
$imageName = $contName ?: $name;
|
||||
$iconRAM = sprintf('%s/%s-%s.png', $dockerManPaths['images-ram'], $contName, 'icon');
|
||||
$icon = sprintf('%s/%s-%s.png', $dockerManPaths['images'], $contName, 'icon');
|
||||
|
||||
@@ -367,8 +363,8 @@ class DockerTemplates {
|
||||
if (!is_file($icon) && is_file($iconRAM)) {
|
||||
@copy($iconRAM,$icon);
|
||||
}
|
||||
if ( !is_file($iconRAM) ) {
|
||||
exec("logger -t webGUI -- \"$imageName: Could not download icon $imgUrl\"");
|
||||
if (!is_file($iconRAM)) {
|
||||
exec("logger -t webGUI -- \"$contName: Could not download icon $imgUrl\"");
|
||||
}
|
||||
|
||||
return (is_file($iconRAM)) ? str_replace($docroot, '', $iconRAM) : '';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2014-2023, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,8 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
@@ -34,7 +33,7 @@ if (!$containers && !$images) {
|
||||
}
|
||||
|
||||
if (file_exists($user_prefs)) {
|
||||
$prefs = @parse_ini_file($user_prefs) ?: [];
|
||||
$prefs = (array)@parse_ini_file($user_prefs);
|
||||
$sort = [];
|
||||
foreach ($containers as $ct) $sort[] = array_search($ct['Name'],$prefs);
|
||||
array_multisort($sort,SORT_NUMERIC,$containers);
|
||||
@@ -46,7 +45,7 @@ $allInfo = $DockerTemplates->getAllInfo();
|
||||
$docker = [];
|
||||
$null = '0.0.0.0';
|
||||
|
||||
$autostart = @file($autostart_file,FILE_IGNORE_NEW_LINES) ?: [];
|
||||
$autostart = (array)@file($autostart_file,FILE_IGNORE_NEW_LINES);
|
||||
$names = array_map('var_split',$autostart);
|
||||
|
||||
function my_lang_time($text) {
|
||||
@@ -108,7 +107,7 @@ foreach ($containers as $ct) {
|
||||
}
|
||||
echo "<span class='outer'><span id='$id' $menu class='hand'>$image</span><span class='inner'><span class='appname $update'>$appname</span><br><i id='load-$id' class='fa fa-$shape $status $color'></i><span class='state'>"._($status)."</span></span></span>";
|
||||
echo "<div class='advanced' style='margin-top:8px'>"._('Container ID').": $id<br>";
|
||||
if ($ct['BaseImage']) echo "<i class='fa fa-cubes' style='margin-right:5px'></i>".htmlspecialchars(${ct['BaseImage']})."<br>";
|
||||
if ($ct['BaseImage']) echo "<i class='fa fa-cubes' style='margin-right:5px'></i>".htmlspecialchars($ct['BaseImage'])."<br>";
|
||||
echo _('By').": ";
|
||||
$registry = $info['registry'];
|
||||
[$author,$version] = my_explode(':',$ct['Image']);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2014-2022, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2022, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
$ncsi = exec("wget --spider --no-check-certificate -nv -T10 -t1 https://www.msftncsi.com/ncsi.txt 2>&1|grep -o 'OK'")=='OK';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2014-2023, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,8 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Secure.php";
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2014-2023, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2021, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
$autostart_file = $dockerManPaths['autostart-file'];
|
||||
@@ -25,7 +25,7 @@ case 'autostart':
|
||||
$container = urldecode(($_POST['container']));
|
||||
$wait = $_POST['wait'];
|
||||
$item = rtrim("$container $wait");
|
||||
$autostart = @file($autostart_file, FILE_IGNORE_NEW_LINES) ?: [];
|
||||
$autostart = (array)@file($autostart_file, FILE_IGNORE_NEW_LINES);
|
||||
$key = array_search($item, $autostart);
|
||||
if ($_POST['auto']=='true') {
|
||||
if ($key===false) $autostart[] = $item;
|
||||
@@ -48,7 +48,7 @@ case 'wait':
|
||||
$container = urldecode(($_POST['container']));
|
||||
$wait = $_POST['wait'];
|
||||
$item = rtrim("$container $wait");
|
||||
$autostart = file($autostart_file, FILE_IGNORE_NEW_LINES) ?: [];
|
||||
$autostart = (array)@file($autostart_file, FILE_IGNORE_NEW_LINES);
|
||||
$names = array_map('var_split', $autostart);
|
||||
$autostart[array_search($container,$names)] = $item;
|
||||
file_put_contents($autostart_file, implode("\n", $autostart)."\n");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2015-2018, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
$autostart_file = $dockerManPaths['autostart-file'];
|
||||
|
||||
@@ -61,17 +61,15 @@ function popupWithIframe(title, cmd, reload, func) {
|
||||
$('#iframe-popup').dialog({
|
||||
autoOpen:true,
|
||||
title:title,
|
||||
height: 600,
|
||||
width: 900,
|
||||
draggable:true,
|
||||
width: Math.min(Math.max(window.innerWidth/2,900),1600),
|
||||
height: Math.max(window.innerHeight*3/5,600),
|
||||
resizable:true,
|
||||
modal:true,
|
||||
show:{effect:'fade', duration:250},
|
||||
hide:{effect:'fade', duration:250},
|
||||
open:function(ev, ui) {
|
||||
open:function(ev, ui){
|
||||
$('#myIframe').attr('src', cmd);
|
||||
},
|
||||
close:function(event, ui) {
|
||||
close:function(event, ui){
|
||||
if (reload && !$('#myIframe').contents().find('#canvas').length) {
|
||||
if (func) setTimeout(func+'()',0); else location = window.location.href;
|
||||
} else {
|
||||
@@ -79,13 +77,13 @@ function popupWithIframe(title, cmd, reload, func) {
|
||||
}
|
||||
}
|
||||
});
|
||||
$(".ui-dialog .ui-dialog-titlebar").addClass('menu');
|
||||
$('.ui-dialog .ui-dialog-titlebar-close').text('X').prop('title',_('Close'));
|
||||
$(".ui-dialog .ui-dialog-title").css({'text-align':'center','width':'100%'});
|
||||
$(".ui-dialog .ui-dialog-content").css({'padding-top':'15px','vertical-align':'bottom'});
|
||||
$('.ui-dialog-titlebar-close').css({'display':'none'});
|
||||
$('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'});
|
||||
$('.ui-dialog-content').css({'padding-top':'15px','vertical-align':'bottom'});
|
||||
$('.ui-button-text').css({'padding':'0px 5px'});
|
||||
}
|
||||
function execUpContainer(container) {
|
||||
var title = _('Updating the container')+': '+container;
|
||||
var title = _('Updating the container TEST')+': '+container;
|
||||
var cmd = '/plugins/dynamix.docker.manager/include/CreateDocker.php?updateContainer=true&ct[]='+encodeURIComponent(container);
|
||||
popupWithIframe(title, cmd, true, 'loadlist');
|
||||
}
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
|
||||
@@ -22,7 +21,7 @@ $_SERVER['REQUEST_URI'] = 'docker';
|
||||
$login_locale = _var($display,'locale');
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
|
||||
$unit = ['B','kB','MB','GB','TB','PB','EB','ZB','YB'];
|
||||
$units = ['B','kB','MB','GB','TB','PB','EB','ZB','YB'];
|
||||
$list = [];
|
||||
|
||||
function write(...$messages){
|
||||
@@ -40,13 +39,13 @@ function write(...$messages){
|
||||
curl_close($com);
|
||||
}
|
||||
function autoscale($value) {
|
||||
global $unit;
|
||||
$size = count($unit);
|
||||
global $units;
|
||||
$size = count($units);
|
||||
$base = $value ? floor(log($value, 1000)) : 0;
|
||||
if ($base>=$size) $base = $size-1;
|
||||
$value /= pow(1000, $base);
|
||||
$decimals = $base ? ($value>=100 ? 0 : ($value>=10 ? 1 : (round($value*100)%100===0 ? 0 : 2))) : 0;
|
||||
return number_format($value, $decimals, '.', $value>9999 ? ',' : '').' '.$unit[$base];
|
||||
return number_format($value, $decimals, '.', $value>9999 ? ',' : '').' '.$units[$base];
|
||||
}
|
||||
function align($text, $w=25) {
|
||||
return $text.str_repeat(' ',$w-min(strlen($text),$w-1));
|
||||
@@ -55,9 +54,9 @@ function gap($text) {
|
||||
return preg_replace('/([kMGTPEZY]?B)$/'," $1",$text);
|
||||
}
|
||||
function byteval($data) {
|
||||
global $unit;
|
||||
global $units;
|
||||
[$value,$base] = explode(' ',gap($data));
|
||||
return $value*pow(1000,array_search($base,$unit));
|
||||
return $value*pow(1000,array_search($base,$units));
|
||||
}
|
||||
|
||||
exec("docker ps -sa --format='{{.Names}}|{{.Size}}'",$container);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/php -q
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2014-2023, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2014-2021, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -13,8 +13,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
extract(parse_plugin_cfg('dynamix', true));
|
||||
@@ -45,7 +44,7 @@ if (!isset($check)) {
|
||||
echo " Done.";
|
||||
} else {
|
||||
$notify = "$docroot/webGui/scripts/notify";
|
||||
$var = @parse_ini_file("/var/local/emhttp/var.ini") ?: [];
|
||||
$var = (array)@parse_ini_file("/var/local/emhttp/var.ini");
|
||||
$server = strtoupper(_var($var,'NAME','tower'));
|
||||
$output = _var($notify,'docker_notify');
|
||||
$info = $DockerTemplates->getAllInfo(true);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
$DockerClient = new DockerClient();
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
.fileTree{width:240px;max-height:200px;overflow-y:scroll;overflow-x:hidden;position:absolute;display:none;background:#f2f2f2}
|
||||
@@ -0,0 +1 @@
|
||||
.fileTree{width:240px;max-height:200px;overflow-y:scroll;overflow-x:hidden;position:absolute;display:none;background:#1c1c1c}
|
||||
@@ -0,0 +1 @@
|
||||
.fileTree{width:240px;max-height:200px;overflow-y:scroll;overflow-x:hidden;position:absolute;display:none;background:#1c1c1c}
|
||||
@@ -0,0 +1 @@
|
||||
.fileTree{width:240px;max-height:200px;overflow-y:scroll;overflow-x:hidden;position:absolute;display:none;background:#f2f2f2}
|
||||
@@ -0,0 +1,9 @@
|
||||
.noshow,.advanced{display:none}
|
||||
.required:after{content:" *";color:#E80000}
|
||||
span.boxed{display:inline-block;line-height:normal;white-space:normal;width:60%}
|
||||
span.cpu,label.checkbox{display:inline-block;width:32px}
|
||||
span.ct{display:inline-block;width:230px}
|
||||
span.net{display:inline-block;width:120px}
|
||||
span.ip{display:inline-block;width:160px}
|
||||
dl,dt,dd{line-height:normal!important}
|
||||
input.setting_input{margin-right:50px}
|
||||
@@ -0,0 +1,12 @@
|
||||
.basic{display:block}
|
||||
.advanced{display:none;white-space:nowrap}
|
||||
.log{cursor:zoom-in}
|
||||
.exec{cursor:pointer}
|
||||
table#docker_containers{text-align:left}
|
||||
th.five{width:5%}
|
||||
th.nine{width:9%}
|
||||
th.load{width:140px}
|
||||
input.wait{width:24px;margin:0 4px;padding:0 5px;border:none;box-shadow:none;background-color:transparent}
|
||||
table tbody td{line-height:normal}
|
||||
i.mover{margin-right:8px;display:none}
|
||||
#resetsort{margin-left:12px;display:inline-block;width:32px}
|
||||
@@ -0,0 +1,2 @@
|
||||
.fileTree{background:#f2f2f2;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:absolute;z-index:100;display:none}
|
||||
span.disabled{color:#B0B0B0}
|
||||
@@ -0,0 +1,2 @@
|
||||
.fileTree{background:#1c1c1c;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:absolute;z-index:100;display:none}
|
||||
span.disabled{color:#404040}
|
||||
@@ -0,0 +1,2 @@
|
||||
.fileTree{background:#1c1c1c;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:absolute;z-index:100;display:none}
|
||||
span.disabled{color:#404040}
|
||||
@@ -0,0 +1,2 @@
|
||||
.fileTree{background:#f2f2f2;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:absolute;z-index:100;display:none}
|
||||
span.disabled{color:#B0B0B0}
|
||||
@@ -0,0 +1,17 @@
|
||||
.errortext{color:#EF3D47;display:none;margin-left:20px}
|
||||
.basic{display:inline-block}
|
||||
.advanced{display:none}
|
||||
select.mask{min-width:0;margin:0 10px 0 4px}
|
||||
select.net{min-width:0;margin:0 4px 0 2px}
|
||||
select option.hide{display:none}
|
||||
input.ip4{width:100px;margin:0 4px 0 1px}
|
||||
input.ip6{width:140px;margin:0 4px}
|
||||
input.gw4{width:100px;margin:0 4px 0 1px}
|
||||
input.gw6{width:160px;margin:0 4px}
|
||||
input.pool6{width:40px;margin:0 4px 0 1px}
|
||||
span.net{margin-left:4px;margin-right:2px}
|
||||
span.ip4{display:inline-block;width:260px}
|
||||
span.ip6{display:inline-block;width:310px}
|
||||
span.gw4{display:inline-block;width:200px}
|
||||
span.gw6{display:inline-block;width:270px}
|
||||
span.nonexist{margin-left:20px}
|
||||
@@ -0,0 +1 @@
|
||||
.fileTree{width:240px;max-height:200px;overflow-y:scroll;overflow-x:hidden;position:absolute;display:none;background:#f2f2f2}
|
||||
@@ -0,0 +1 @@
|
||||
.fileTree{width:240px;max-height:200px;overflow-y:scroll;overflow-x:hidden;position:absolute;display:none;background:#1c1c1c}
|
||||
@@ -0,0 +1 @@
|
||||
.fileTree{width:240px;max-height:200px;overflow-y:scroll;overflow-x:hidden;position:absolute;display:none;background:#1c1c1c}
|
||||
@@ -0,0 +1 @@
|
||||
.fileTree{width:240px;max-height:200px;overflow-y:scroll;overflow-x:hidden;position:absolute;display:none;background:#f2f2f2}
|
||||
@@ -0,0 +1,9 @@
|
||||
.noshow,.advanced{display:none}
|
||||
.required:after{content:" *";color:#E80000}
|
||||
span.boxed{display:inline-block;line-height:normal;white-space:normal;width:60%}
|
||||
span.cpu,label.checkbox{display:inline-block;width:32px}
|
||||
span.ct{display:inline-block;width:230px}
|
||||
span.net{display:inline-block;width:120px}
|
||||
span.ip{display:inline-block;width:160px}
|
||||
dl,dt,dd{line-height:normal!important}
|
||||
input.setting_input{margin-right:50px}
|
||||
@@ -1,62 +1,14 @@
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button{
|
||||
font-family:clear-sans;font-size:1.1rem;font-weight:bold;letter-spacing:2px;text-transform:uppercase;margin:10px 12px 10px 0;padding:9px 18px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;border-radius:4px;border:0;color:#ff8c2f;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#e22828),to(#e22828)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#ff8c2f),to(#ff8c2f)) 100% 100% no-repeat;background:linear-gradient(90deg,#e22828 0,#ff8c2f) 0 0 no-repeat,linear-gradient(90deg,#e22828 0,#ff8c2f) 0 100% no-repeat,linear-gradient(0deg,#e22828 0,#e22828) 0 100% no-repeat,linear-gradient(0deg,#ff8c2f 0,#ff8c2f) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button:hover{
|
||||
color:#f2f2f2;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f));background:linear-gradient(90deg,#e22828 0,#ff8c2f)
|
||||
}
|
||||
.ui-dropdownchecklist .ui-state-default{
|
||||
background:#f2f2f2;
|
||||
border:none;
|
||||
box-shadow:none;
|
||||
outline:none;
|
||||
cursor:pointer;
|
||||
height:2.2rem;
|
||||
line-height:2.2rem;
|
||||
}
|
||||
.ui-dropdownchecklist-group{
|
||||
font-weight:normal;
|
||||
font-style:italic;
|
||||
padding:1px 9px 1px 8px;
|
||||
}
|
||||
.ui-dropdownchecklist-selector{
|
||||
border:1px solid #1c1c1c;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
padding:1px 9px 1px 8px;
|
||||
}
|
||||
.ui-dropdownchecklist-selector-wrapper{
|
||||
vertical-align:middle;
|
||||
font-size:0;
|
||||
}
|
||||
.ui-widget-header{
|
||||
border:none;
|
||||
background:#e3e3e3;
|
||||
color:#1c1c1c;
|
||||
font-weight:bold;
|
||||
}
|
||||
.ui-widget-content{
|
||||
border:1px solid #1c1c1c;
|
||||
background:#f2f2f2;
|
||||
color:#1c1c1c;
|
||||
|
||||
.ui-state-active{
|
||||
background:#e8e8e8;
|
||||
}
|
||||
.ui-dropdownchecklist-dropcontainer{
|
||||
background:#f2f2f2;
|
||||
border:1px solid #1c1c1c;
|
||||
}
|
||||
.ui-state-disabled{
|
||||
color:#1c1c1c;border-color:#a2a2a2;background:#e8e8e8;opacity:0.5;
|
||||
}
|
||||
.ui-dropdownchecklist-indent{
|
||||
padding-left:7px;
|
||||
}
|
||||
.ui-dropdownchecklist-text{
|
||||
color:#1c1c1c;
|
||||
font-size:1.3rem;
|
||||
}
|
||||
.ui-dropdownchecklist .ui-widget-content .ui-state-default{
|
||||
background:#f2f2f2;
|
||||
border:0px;
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button{font-family:clear-sans;font-size:1.1rem;font-weight:bold;letter-spacing:2px;text-transform:uppercase;margin:10px 12px 10px 0;padding:9px 18px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;border-radius:4px;border:0;color:#ff8c2f;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#e22828),to(#e22828)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#ff8c2f),to(#ff8c2f)) 100% 100% no-repeat;background:linear-gradient(90deg,#e22828 0,#ff8c2f) 0 0 no-repeat,linear-gradient(90deg,#e22828 0,#ff8c2f) 0 100% no-repeat,linear-gradient(0deg,#e22828 0,#e22828) 0 100% no-repeat,linear-gradient(0deg,#ff8c2f 0,#ff8c2f) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button:hover{color:#f2f2f2;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f));background:linear-gradient(90deg,#e22828 0,#ff8c2f)}
|
||||
.ui-dropdownchecklist .ui-state-default{background:#f2f2f2;border:none;box-shadow:none;outline:none;cursor:pointer;height:2.2rem;line-height:2.2rem}
|
||||
.ui-dropdownchecklist-group{font-weight:normal;font-style:italic;padding:1px 9px 1px 8px}
|
||||
.ui-dropdownchecklist-selector{border:1px solid #1c1c1c;display:inline-block;cursor:pointer;padding:1px 9px 1px 8px}
|
||||
.ui-dropdownchecklist-selector-wrapper{vertical-align:middle;font-size:0}
|
||||
.ui-widget-header{border:none;background:#e3e3e3;color:#1c1c1c;font-weight:bold}
|
||||
.ui-widget-content{border:1px solid #1c1c1c;background:#f2f2f2;color:#1c1c1c}
|
||||
.ui-state-active{background:#e8e8e8}
|
||||
.ui-dropdownchecklist-dropcontainer{background:#f2f2f2;border:1px solid #1c1c1c}
|
||||
.ui-state-disabled{color:#1c1c1c;border-color:#a2a2a2;background:#e8e8e8;opacity:0.5}
|
||||
.ui-dropdownchecklist-indent{padding-left:7px}
|
||||
.ui-dropdownchecklist-text{color:#1c1c1c;font-size:1.3rem}
|
||||
.ui-dropdownchecklist .ui-widget-content .ui-state-default{background:#f2f2f2;border:0px}
|
||||
|
||||
@@ -1,62 +1,14 @@
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button{
|
||||
font-family:clear-sans;font-size:1.1rem;font-weight:bold;letter-spacing:2px;text-transform:uppercase;margin:10px 12px 10px 0;padding:9px 18px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;border-radius:4px;border:0;color:#ff8c2f;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#e22828),to(#e22828)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#ff8c2f),to(#ff8c2f)) 100% 100% no-repeat;background:linear-gradient(90deg,#e22828 0,#ff8c2f) 0 0 no-repeat,linear-gradient(90deg,#e22828 0,#ff8c2f) 0 100% no-repeat,linear-gradient(0deg,#e22828 0,#e22828) 0 100% no-repeat,linear-gradient(0deg,#ff8c2f 0,#ff8c2f) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button:hover{
|
||||
color:#f2f2f2;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f));background:linear-gradient(90deg,#e22828 0,#ff8c2f)
|
||||
}
|
||||
.ui-dropdownchecklist .ui-state-default{
|
||||
background:#1c1c1c;
|
||||
border:none;
|
||||
box-shadow:none;
|
||||
outline:none;
|
||||
cursor:pointer;
|
||||
height:2.2rem;
|
||||
line-height:2.2rem;
|
||||
}
|
||||
.ui-dropdownchecklist-group{
|
||||
font-weight:normal;
|
||||
font-style:italic;
|
||||
padding:1px 9px 1px 8px;
|
||||
}
|
||||
.ui-dropdownchecklist-selector{
|
||||
border:1px solid #e5e5e5;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
padding:1px 9px 1px 8px;
|
||||
}
|
||||
.ui-dropdownchecklist-selector-wrapper{
|
||||
vertical-align:middle;
|
||||
font-size:0;
|
||||
}
|
||||
.ui-widget-header{
|
||||
border:none;
|
||||
background:#2b2b2b;
|
||||
color:#f2f2f2;
|
||||
font-weight:bold;
|
||||
}
|
||||
.ui-widget-content{
|
||||
border:1px solid #e5e5e5;
|
||||
background:#1c1c1c;
|
||||
color:#f2f2f2;
|
||||
|
||||
.ui-state-active{
|
||||
background:#262626;
|
||||
}
|
||||
.ui-dropdownchecklist-dropcontainer{
|
||||
background:#1c1c1c;
|
||||
border:1px solid #e5e5e5;
|
||||
}
|
||||
.ui-state-disabled{
|
||||
color:#f2f2f2;border-color:#6c6c6c;background:#262626;opacity:0.5;
|
||||
}
|
||||
.ui-dropdownchecklist-indent{
|
||||
padding-left:7px;
|
||||
}
|
||||
.ui-dropdownchecklist-text{
|
||||
color:#f2f2f2;
|
||||
font-size:1.3rem;
|
||||
}
|
||||
.ui-dropdownchecklist .ui-widget-content .ui-state-default{
|
||||
background:#1c1c1c;
|
||||
border:0px;
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button{font-family:clear-sans;font-size:1.1rem;font-weight:bold;letter-spacing:2px;text-transform:uppercase;margin:10px 12px 10px 0;padding:9px 18px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;border-radius:4px;border:0;color:#ff8c2f;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#e22828),to(#e22828)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#ff8c2f),to(#ff8c2f)) 100% 100% no-repeat;background:linear-gradient(90deg,#e22828 0,#ff8c2f) 0 0 no-repeat,linear-gradient(90deg,#e22828 0,#ff8c2f) 0 100% no-repeat,linear-gradient(0deg,#e22828 0,#e22828) 0 100% no-repeat,linear-gradient(0deg,#ff8c2f 0,#ff8c2f) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button:hover{color:#f2f2f2;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f));background:linear-gradient(90deg,#e22828 0,#ff8c2f)}
|
||||
.ui-dropdownchecklist .ui-state-default{background:#1c1c1c;border:none;box-shadow:none;outline:none;cursor:pointer;height:2.2rem;line-height:2.2rem}
|
||||
.ui-dropdownchecklist-group{font-weight:normal;font-style:italic;padding:1px 9px 1px 8px}
|
||||
.ui-dropdownchecklist-selector{border:1px solid #e5e5e5;display:inline-block;cursor:pointer;padding:1px 9px 1px 8px}
|
||||
.ui-dropdownchecklist-selector-wrapper{vertical-align:middle;font-size:0}
|
||||
.ui-widget-header{border:none;background:#2b2b2b;color:#f2f2f2;font-weight:bold}
|
||||
.ui-widget-content{border:1px solid #e5e5e5;background:#1c1c1c;color:#f2f2f2}
|
||||
.ui-state-active{background:#262626}
|
||||
.ui-dropdownchecklist-dropcontainer{background:#1c1c1c;border:1px solid #e5e5e5}
|
||||
.ui-state-disabled{color:#f2f2f2;border-color:#6c6c6c;background:#262626;opacity:0.5}
|
||||
.ui-dropdownchecklist-indent{padding-left:7px}
|
||||
.ui-dropdownchecklist-text{color:#f2f2f2;font-size:1.3rem}
|
||||
.ui-dropdownchecklist .ui-widget-content .ui-state-default{background:#1c1c1c;border:0px}
|
||||
|
||||
@@ -1,62 +1,14 @@
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button{
|
||||
font-family:clear-sans;font-size:1.1rem;font-weight:bold;letter-spacing:2px;text-transform:uppercase;margin:10px 12px 10px 0;padding:9px 18px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;border-radius:4px;border:0;color:#ff8c2f;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#e22828),to(#e22828)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#ff8c2f),to(#ff8c2f)) 100% 100% no-repeat;background:linear-gradient(90deg,#e22828 0,#ff8c2f) 0 0 no-repeat,linear-gradient(90deg,#e22828 0,#ff8c2f) 0 100% no-repeat,linear-gradient(0deg,#e22828 0,#e22828) 0 100% no-repeat,linear-gradient(0deg,#ff8c2f 0,#ff8c2f) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button:hover{
|
||||
color:#f2f2f2;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f));background:linear-gradient(90deg,#e22828 0,#ff8c2f)
|
||||
}
|
||||
.ui-dropdownchecklist .ui-state-default{
|
||||
background:#1c1c1c;
|
||||
border:none;
|
||||
box-shadow:none;
|
||||
outline:none;
|
||||
cursor:pointer;
|
||||
height:2.2rem;
|
||||
line-height:2.2rem;
|
||||
}
|
||||
.ui-dropdownchecklist-group{
|
||||
font-weight:normal;
|
||||
font-style:italic;
|
||||
padding:1px 9px 1px 8px;
|
||||
}
|
||||
.ui-dropdownchecklist-selector{
|
||||
border:1px solid #e5e5e5;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
padding:1px 9px 1px 8px;
|
||||
}
|
||||
.ui-dropdownchecklist-selector-wrapper{
|
||||
vertical-align:middle;
|
||||
font-size:0;
|
||||
}
|
||||
.ui-widget-header{
|
||||
border:none;
|
||||
background:#2b2b2b;
|
||||
color:#f2f2f2;
|
||||
font-weight:bold;
|
||||
}
|
||||
.ui-widget-content{
|
||||
border:1px solid #e5e5e5;
|
||||
background:#1c1c1c;
|
||||
color:#f2f2f2;
|
||||
|
||||
.ui-state-active{
|
||||
background:#262626;
|
||||
}
|
||||
.ui-dropdownchecklist-dropcontainer{
|
||||
background:#1c1c1c;
|
||||
border:1px solid #e5e5e5;
|
||||
}
|
||||
.ui-state-disabled{
|
||||
color:#f2f2f2;border-color:#6c6c6c;background:#262626;opacity:0.5;
|
||||
}
|
||||
.ui-dropdownchecklist-indent{
|
||||
padding-left:7px;
|
||||
}
|
||||
.ui-dropdownchecklist-text{
|
||||
color:#f2f2f2;
|
||||
font-size:1.3rem;
|
||||
}
|
||||
.ui-dropdownchecklist .ui-widget-content .ui-state-default{
|
||||
background:#1c1c1c;
|
||||
border:0px;
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button{font-family:clear-sans;font-size:1.1rem;font-weight:bold;letter-spacing:2px;text-transform:uppercase;margin:10px 12px 10px 0;padding:9px 18px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;border-radius:4px;border:0;color:#ff8c2f;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#e22828),to(#e22828)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#ff8c2f),to(#ff8c2f)) 100% 100% no-repeat;background:linear-gradient(90deg,#e22828 0,#ff8c2f) 0 0 no-repeat,linear-gradient(90deg,#e22828 0,#ff8c2f) 0 100% no-repeat,linear-gradient(0deg,#e22828 0,#e22828) 0 100% no-repeat,linear-gradient(0deg,#ff8c2f 0,#ff8c2f) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button:hover{color:#f2f2f2;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f));background:linear-gradient(90deg,#e22828 0,#ff8c2f)}
|
||||
.ui-dropdownchecklist .ui-state-default{background:#1c1c1c;border:none;box-shadow:none;outline:none;cursor:pointer;height:2.2rem;line-height:2.2rem}
|
||||
.ui-dropdownchecklist-group{font-weight:normal;font-style:italic;padding:1px 9px 1px 8px}
|
||||
.ui-dropdownchecklist-selector{border:1px solid #e5e5e5;display:inline-block;cursor:pointer;padding:1px 9px 1px 8px}
|
||||
.ui-dropdownchecklist-selector-wrapper{vertical-align:middle;font-size:0}
|
||||
.ui-widget-header{border:none;background:#2b2b2b;color:#f2f2f2;font-weight:bold}
|
||||
.ui-widget-content{border:1px solid #e5e5e5;background:#1c1c1c;color:#f2f2f2}
|
||||
.ui-state-active{background:#262626}
|
||||
.ui-dropdownchecklist-dropcontainer{background:#1c1c1c;border:1px solid #e5e5e5}
|
||||
.ui-state-disabled{color:#f2f2f2;border-color:#6c6c6c;background:#262626;opacity:0.5}
|
||||
.ui-dropdownchecklist-indent{padding-left:7px}
|
||||
.ui-dropdownchecklist-text{color:#f2f2f2;font-size:1.3rem}
|
||||
.ui-dropdownchecklist .ui-widget-content .ui-state-default{background:#1c1c1c;border:0px}
|
||||
|
||||
@@ -1,62 +1,14 @@
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button{
|
||||
font-family:clear-sans;font-size:1.1rem;font-weight:bold;letter-spacing:2px;text-transform:uppercase;margin:10px 12px 10px 0;padding:9px 18px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;border-radius:4px;border:0;color:#ff8c2f;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#e22828),to(#e22828)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#ff8c2f),to(#ff8c2f)) 100% 100% no-repeat;background:linear-gradient(90deg,#e22828 0,#ff8c2f) 0 0 no-repeat,linear-gradient(90deg,#e22828 0,#ff8c2f) 0 100% no-repeat,linear-gradient(0deg,#e22828 0,#e22828) 0 100% no-repeat,linear-gradient(0deg,#ff8c2f 0,#ff8c2f) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button:hover{
|
||||
color:#f2f2f2;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f));background:linear-gradient(90deg,#e22828 0,#ff8c2f)
|
||||
}
|
||||
.ui-dropdownchecklist .ui-state-default{
|
||||
background:#f2f2f2;
|
||||
border:none;
|
||||
box-shadow:none;
|
||||
outline:none;
|
||||
cursor:pointer;
|
||||
height:2.2rem;
|
||||
line-height:2.2rem;
|
||||
}
|
||||
.ui-dropdownchecklist-group{
|
||||
font-weight:normal;
|
||||
font-style:italic;
|
||||
padding:1px 9px 1px 8px;
|
||||
}
|
||||
.ui-dropdownchecklist-selector{
|
||||
border:1px solid #1c1c1c;
|
||||
display:inline-block;
|
||||
cursor:pointer;
|
||||
padding:1px 9px 1px 8px;
|
||||
}
|
||||
.ui-dropdownchecklist-selector-wrapper{
|
||||
vertical-align:middle;
|
||||
font-size:0;
|
||||
}
|
||||
.ui-widget-header{
|
||||
border:none;
|
||||
background:#e3e3e3;
|
||||
color:#1c1c1c;
|
||||
font-weight:bold;
|
||||
}
|
||||
.ui-widget-content{
|
||||
border:1px solid #1c1c1c;
|
||||
background:#f2f2f2;
|
||||
color:#1c1c1c;
|
||||
|
||||
.ui-state-active{
|
||||
background:#e8e8e8;
|
||||
}
|
||||
.ui-dropdownchecklist-dropcontainer{
|
||||
background:#f2f2f2;
|
||||
border:1px solid #1c1c1c;
|
||||
}
|
||||
.ui-state-disabled{
|
||||
color:#1c1c1c;border-color:#a2a2a2;background:#e8e8e8;opacity:0.5;
|
||||
}
|
||||
.ui-dropdownchecklist-indent{
|
||||
padding-left:7px;
|
||||
}
|
||||
.ui-dropdownchecklist-text{
|
||||
color:#1c1c1c;
|
||||
font-size:1.3rem;
|
||||
}
|
||||
.ui-dropdownchecklist .ui-widget-content .ui-state-default{
|
||||
background:#f2f2f2;
|
||||
border:0px;
|
||||
}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button{font-family:clear-sans;font-size:1.1rem;font-weight:bold;letter-spacing:2px;text-transform:uppercase;margin:10px 12px 10px 0;padding:9px 18px;text-decoration:none;white-space:nowrap;cursor:pointer;outline:none;border-radius:4px;border:0;color:#ff8c2f;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#e22828),to(#e22828)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#ff8c2f),to(#ff8c2f)) 100% 100% no-repeat;background:linear-gradient(90deg,#e22828 0,#ff8c2f) 0 0 no-repeat,linear-gradient(90deg,#e22828 0,#ff8c2f) 0 100% no-repeat,linear-gradient(0deg,#e22828 0,#e22828) 0 100% no-repeat,linear-gradient(0deg,#ff8c2f 0,#ff8c2f) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button:hover{color:#f2f2f2;background:-webkit-gradient(linear,left top,right top,from(#e22828),to(#ff8c2f));background:linear-gradient(90deg,#e22828 0,#ff8c2f)}
|
||||
.ui-dropdownchecklist .ui-state-default{background:#f2f2f2;border:none;box-shadow:none;outline:none;cursor:pointer;height:2.2rem;line-height:2.2rem}
|
||||
.ui-dropdownchecklist-group{font-weight:normal;font-style:italic;padding:1px 9px 1px 8px}
|
||||
.ui-dropdownchecklist-selector{border:1px solid #1c1c1c;display:inline-block;cursor:pointer;padding:1px 9px 1px 8px}
|
||||
.ui-dropdownchecklist-selector-wrapper{vertical-align:middle;font-size:0}
|
||||
.ui-widget-header{border:none;background:#e3e3e3;color:#1c1c1c;font-weight:bold}
|
||||
.ui-widget-content{border:1px solid #1c1c1c;background:#f2f2f2;color:#1c1c1c}
|
||||
.ui-state-active{background:#e8e8e8}
|
||||
.ui-dropdownchecklist-dropcontainer{background:#f2f2f2;border:1px solid #1c1c1c}
|
||||
.ui-state-disabled{color:#1c1c1c;border-color:#a2a2a2;background:#e8e8e8;opacity:0.5}
|
||||
.ui-dropdownchecklist-indent{padding-left:7px}
|
||||
.ui-dropdownchecklist-text{color:#1c1c1c;font-size:1.3rem}
|
||||
.ui-dropdownchecklist .ui-widget-content .ui-state-default{background:#f2f2f2;border:0px}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
<?PHP
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
$var = (array)parse_ini_file('state/var.ini');
|
||||
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
<?PHP
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once("$docroot/plugins/dynamix.my.servers/include/state.php");
|
||||
require_once("$docroot/plugins/dynamix.my.servers/include/translations.php");
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
#!/usr/bin/php
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
function update($url, $payload) {
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch,CURLOPT_POST, true);
|
||||
curl_setopt($ch,CURLOPT_POSTFIELDS, $payload);
|
||||
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
|
||||
$result = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
}
|
||||
|
||||
$dyn_cfg = '/boot/config/plugins/dynamix/dynamix.cfg';
|
||||
$mys_cfg = '/boot/config/plugins/dynamix.my.servers/myservers.cfg';
|
||||
|
||||
if (file_exists($dyn_cfg) && !file_exists($mys_cfg)) {
|
||||
$orig = @parse_ini_file($dyn_cfg,true);
|
||||
$var = @(array)parse_ini_file('/usr/local/emhttp/state/var.ini',true);
|
||||
$url = "http://localhost:".$var['PORT']."/update.php";
|
||||
|
||||
// write [remote] section to myservers.cfg
|
||||
if(!empty($orig['remote'])) {
|
||||
$fields_mys_remote = [
|
||||
'csrf_token' => $var['csrf_token'],
|
||||
'#file' => $mys_cfg,
|
||||
'#section' => 'remote'
|
||||
];
|
||||
foreach($orig['remote'] as $key => $value) {
|
||||
$fields_mys_remote[$key] = $value;
|
||||
}
|
||||
update($url, http_build_query($fields_mys_remote));
|
||||
}
|
||||
/*
|
||||
// write [wizard] section to myservers.cfg
|
||||
if(!empty($orig['wizard'])) {
|
||||
$fields_mys_wizard = [
|
||||
'csrf_token' => $var['csrf_token'],
|
||||
'#file' => $mys_cfg,
|
||||
'#section' => 'wizard'
|
||||
];
|
||||
foreach($orig['wizard'] as $key => $value) {
|
||||
$fields_mys_wizard[$key] = $value;
|
||||
}
|
||||
update($url, http_build_query($fields_mys_wizard));
|
||||
}
|
||||
*/
|
||||
// remove [remote] section from dynamix.cfg
|
||||
if(!empty($orig['remote'])) {
|
||||
$fields_dyn_remote = [
|
||||
'csrf_token' => $var['csrf_token'],
|
||||
'#file' => $dyn_cfg,
|
||||
'#section' => 'remote',
|
||||
'#cleanup' => 'true'
|
||||
];
|
||||
foreach($orig['remote'] as $key => $value) {
|
||||
$fields_dyn_remote[$key] = '';
|
||||
}
|
||||
update($url, http_build_query($fields_dyn_remote));
|
||||
}
|
||||
// remove [wizard] section from dynamix.cfg
|
||||
if(!empty($orig['wizard'])) {
|
||||
$fields_dyn_wizard = [
|
||||
'csrf_token' => $var['csrf_token'],
|
||||
'#file' => $dyn_cfg,
|
||||
'#section' => 'wizard',
|
||||
'#cleanup' => 'true'
|
||||
];
|
||||
foreach($orig['wizard'] as $key => $value) {
|
||||
$fields_dyn_wizard[$key] = '';
|
||||
}
|
||||
update($url, http_build_query($fields_dyn_wizard));
|
||||
}
|
||||
// remove [remote] and [wizard] section headings from dyn_cfg file
|
||||
$oldtext = file_get_contents($dyn_cfg);
|
||||
$newtext = preg_replace ('/\[(remote|wizard)\]\n/', '', $oldtext);
|
||||
if (strcmp($oldtext, $newtext) !== 0) {
|
||||
file_put_contents($dyn_cfg, $newtext);
|
||||
}
|
||||
}
|
||||
if (!file_exists($mys_cfg)) touch($mys_cfg);
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,4 @@
|
||||
span.thanks{padding-left:12px;color:#6FA239;font-weight:bold;}
|
||||
span.thanks.red{color:#F0000C;}
|
||||
div.device{padding:0 12px;font-weight:normal;font-style:italic;}
|
||||
div.remark{padding:0 12px;text-align:justify;}
|
||||
@@ -13,14 +13,6 @@ Link='nav-user'
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
?>
|
||||
<style>
|
||||
/* Additional CSS for when user supplies element */
|
||||
.ca_element_notice{padding-right:20px;width:100%;height:40px;line-height:40px;color:#e68a00;background:#feefb3;border-bottom:#e68a00 1px solid;text-align:center;font-size:1.4rem;z-index:900;}
|
||||
a.ca_PluginUpdateInstall{cursor:pointer;}
|
||||
span.ca_PluginUpdateDismiss{float:right;margin-right:20px;cursor:pointer;}
|
||||
span.bannerInfo {cursor:pointer;text-decoration:none;margin:0 12px 0 6px;}
|
||||
span.bannerInfo::before {content:"\f05a";font-family:fontAwesome;color:#e68a00;}
|
||||
</style>
|
||||
<script>
|
||||
const ca_args = {};
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ Title="Install Plugin"
|
||||
Tag="download"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -6,8 +6,8 @@ Tabs="true"
|
||||
Code="e944"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2022, Lime Technology
|
||||
* Copyright 2012-2022, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -25,10 +25,6 @@ if (!exec("pgrep -f $docroot/plugins/dynamix.plugin.manager/scripts/plugin")) {
|
||||
$check = $notify['version'] ? 0 : 1;
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.filetree.css')?>">
|
||||
<style>
|
||||
#plugin_tree{width:33%;height:200px;overflow-y:scroll}
|
||||
table tbody td{line-height:normal}
|
||||
</style>
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.filetree.js')?>" charset="utf-8"></script>
|
||||
<script>
|
||||
|
||||
@@ -4,8 +4,8 @@ Tag="puzzle-piece"
|
||||
Cond="glob('/boot/config/plugins-error/*.plg')"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -4,8 +4,8 @@ Tag="puzzle-piece"
|
||||
Cond="glob('/boot/config/plugins-stale/*.plg')"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
* Copyright 2012-2021, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
require_once "$docroot/webGui/include/Secure.php";
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: "/usr/local/emhttp";
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
|
||||
function readJson($file) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: "/usr/local/emhttp";
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
|
||||
$type = $argv[1]??''; // plugin or language
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
require_once "$docroot/plugins/dynamix/include/Secure.php";
|
||||
|
||||
//add translations
|
||||
$_SERVER['REQUEST_URI'] = "plugins";
|
||||
require_once "$docroot/plugins/dynamix/include/Translations.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
require_once "$docroot/plugins/dynamix/include/Secure.php";
|
||||
|
||||
function download_url($url, $path = "") {
|
||||
$ch = curl_init();
|
||||
@@ -39,21 +40,17 @@ switch ($_POST['action']) {
|
||||
case 'checkPlugin':
|
||||
$options = $_POST['options'] ?? '';
|
||||
$plugin = $options['plugin'] ?? '';
|
||||
|
||||
$name = unbundle($options['name'] ?? $plugin);
|
||||
$file = "/boot/config/plugins/$plugin";
|
||||
$file = realpath($file)==$file ? $file : "";
|
||||
|
||||
if ( ! $plugin || ! file_exists($file) ) {
|
||||
echo json_encode(["updateAvailable"=>false]);
|
||||
break;
|
||||
}
|
||||
|
||||
exec("mkdir -p /tmp/plugins");
|
||||
@unlink("/tmp/plugins/$plugin");
|
||||
$url = plugin("pluginURL","/boot/config/plugins/$plugin");
|
||||
download_url($url,"/tmp/plugins/$plugin");
|
||||
|
||||
$changes = plugin("changes","/tmp/plugins/$plugin");
|
||||
$alerts = plugin("alert","/tmp/plugins/$plugin");
|
||||
$version = plugin("version","/tmp/plugins/$plugin");
|
||||
@@ -69,7 +66,6 @@ switch ($_POST['action']) {
|
||||
} else {
|
||||
@unlink('/tmp/plugins/my_alerts.txt');
|
||||
}
|
||||
|
||||
$update = false;
|
||||
if ( strcmp($version,$installedVersion) > 0 ) {
|
||||
$unraid = parse_ini_file("/etc/unraid-version");
|
||||
@@ -77,17 +73,14 @@ switch ($_POST['action']) {
|
||||
}
|
||||
$updateMessage = sprintf(_("%s: An update is available."),$name);
|
||||
$linkMessage = sprintf(_("Click here to install version %s"),$version);
|
||||
|
||||
echo json_encode(["updateAvailable"=>$update, "version"=>$version, "min"=>$min, "alert"=>$alerts, "changes"=>$changes, "installedVersion"=>$installedVersion, "updateMessage"=>$updateMessage, "linkMessage"=>$linkMessage]);
|
||||
break;
|
||||
|
||||
case 'addRebootNotice':
|
||||
$message = htmlspecialchars(trim($_POST['message']));
|
||||
if ( ! $message ) break;
|
||||
|
||||
$existing = @file("/tmp/reboot_notifications",FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [];
|
||||
if (!$message) break;
|
||||
$existing = (array)@file("/tmp/reboot_notifications",FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$existing[] = $message;
|
||||
|
||||
file_put_contents("/tmp/reboot_notifications",implode("\n",array_unique($existing)));
|
||||
break;
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
extract(parse_plugin_cfg('dynamix', true));
|
||||
@@ -23,7 +22,7 @@ $_SERVER['REQUEST_URI'] = "scripts";
|
||||
$login_locale = _var($display,'locale');
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
|
||||
$var = @parse_ini_file('/var/local/emhttp/var.ini') ?: [];
|
||||
$var = (array)@parse_ini_file('/var/local/emhttp/var.ini');
|
||||
|
||||
function apos($text) {
|
||||
// So that "'" doesn't show up in email
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/php -q
|
||||
<?PHP
|
||||
// Copyright 2005-2022, Lime Technology
|
||||
// Copyright 2005-2023, Lime Technology
|
||||
// License: GPLv2 only
|
||||
//
|
||||
// Program updates made by Bergware International (April 2020)
|
||||
|
||||
@@ -12,11 +12,9 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
|
||||
// Multi-language support
|
||||
@@ -24,7 +22,7 @@ $_SERVER['REQUEST_URI'] = "scripts";
|
||||
$login_locale = _var($display,'locale');
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
|
||||
$var = @parse_ini_file('/var/local/emhttp/var.ini') ?: [];
|
||||
$var = (array)@parse_ini_file('/var/local/emhttp/var.ini');
|
||||
|
||||
function apos($text) {
|
||||
// So that "'" doesn't show up in email
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
extract(parse_plugin_cfg('dynamix',true));
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php";
|
||||
|
||||
@@ -24,7 +23,7 @@ if (!function_exists('_')) {
|
||||
|
||||
extract(parse_plugin_cfg('dynamix', true));
|
||||
|
||||
$var = @parse_ini_file('/var/local/emhttp/var.ini') ?: [];
|
||||
$var = (array)@parse_ini_file('/var/local/emhttp/var.ini');
|
||||
$script = "$docroot/webGui/scripts/notify";
|
||||
$server = strtoupper(_var($var,'NAME','server'));
|
||||
$output = _var($notify,'plugin');
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
.ca_element_notice{padding-right:20px;width:100%;height:40px;line-height:40px;color:#e68a00;background:#feefb3;border-bottom:#e68a00 1px solid;text-align:center;font-size:1.4rem;z-index:900}
|
||||
a.ca_PluginUpdateInstall{cursor:pointer}
|
||||
span.ca_PluginUpdateDismiss{float:right;margin-right:20px;cursor:pointer}
|
||||
span.bannerInfo {cursor:pointer;text-decoration:none;margin:0 12px 0 6px}
|
||||
span.bannerInfo::before {content:"\f05a";font-family:fontAwesome;color:#e68a00}
|
||||
2
emhttp/plugins/dynamix.plugin.manager/sheets/Plugins.css
Normal file
2
emhttp/plugins/dynamix.plugin.manager/sheets/Plugins.css
Normal file
@@ -0,0 +1,2 @@
|
||||
#plugin_tree{width:33%;height:200px;overflow-y:scroll}
|
||||
table tbody td{line-height:normal}
|
||||
@@ -0,0 +1 @@
|
||||
span.vhshift{margin-top:13px!important}
|
||||
@@ -0,0 +1 @@
|
||||
span.vhshift{margin-top:13px!important}
|
||||
9
emhttp/plugins/dynamix.plugin.manager/sheets/Update.css
Normal file
9
emhttp/plugins/dynamix.plugin.manager/sheets/Update.css
Normal file
@@ -0,0 +1,9 @@
|
||||
ul,li{margin:0;padding-top:0;padding-bottom:0}
|
||||
pre.pre{margin:30px 0}
|
||||
pre>p{margin:0;padding:0}
|
||||
pre#swaltext{height:600px!important}
|
||||
@media (max-width:960px){pre#swaltext{height:400px!important}}
|
||||
@media (max-width:960px){.sweet-alert.nchan{height:600px;width:900px;margin-left:-470px}}
|
||||
@media (max-height:768px){pre#swaltext{height:400px!important}}
|
||||
@media (max-height:768px){.sweet-alert.nchan{height:600px;width:900px;margin-left:-470px}}
|
||||
input[value="_(Install)_"],input[value="_(Update)_"],input[value="_(Restore)_"]{margin:0}
|
||||
@@ -4,9 +4,9 @@ Cond="(pgrep('libvirtd')!==false)"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -4,9 +4,9 @@ Cond="(pgrep('libvirtd')!==false)"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -6,8 +6,8 @@ Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2015-2023, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -18,7 +18,7 @@ Markdown="false"
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
$cpus = cpu_list();
|
||||
@@ -112,36 +112,6 @@ if (empty($vms)) {
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.filetree.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/jquery.ui.css")?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/plugins/dynamix.docker.manager/styles/style-$theme.css")?>">
|
||||
<style>
|
||||
th.th1{width:25%}
|
||||
th.th2{width:15%}
|
||||
th.th3{width:80px}
|
||||
div.four{font-size:1.1rem;width:260px}
|
||||
div.four label{float:left;display:table-cell;width:25%}
|
||||
div.four label:nth-child(4n+4){float:none;clear:both}
|
||||
div.four label.cpu1{width:32%}
|
||||
div.four label.cpu2{width:26%}
|
||||
div.template,div#dialogWindow,input#upload{display:none}
|
||||
div.template,div#dialogWindow2,input#upload{display:none}
|
||||
table.domdisk thead tr th:nth-child(1){width:56%!important}
|
||||
table.domdisk thead tr th:nth-child(n+2){width:8%!important}
|
||||
table.domdisk thead tr th:nth-child(1){padding-left:72px}
|
||||
table.domdisk tbody tr td:nth-child(1){padding-left:72px}
|
||||
table.domdisk tbody tr:nth-child(even){background-color:transparent!important}
|
||||
table.domdisk tbody tr:nth-child(4n-1){background-color:transparent!important}
|
||||
i.mover{margin-right:8px;display:none}
|
||||
#resetsort{margin-left:12px;display:inline-block;width:32px}
|
||||
.fileTree{background:<?=$bgcolor?>;width:500px;max-height:320px;overflow-y:scroll;overflow-x:hidden;position:absolute;z-index:100;display:none}
|
||||
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset button[disabled]{cursor:default;color:#808080;background:-webkit-gradient(linear,left top,right top,from(#404040),to(#808080)) 0 0 no-repeat,-webkit-gradient(linear,left top,right top,from(#404040),to(#808080)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#404040),to(#404040)) 0 100% no-repeat,-webkit-gradient(linear,left bottom,left top,from(#808080),to(#808080)) 100% 100% no-repeat;background:linear-gradient(90deg,#404040 0,#808080) 0 0 no-repeat,linear-gradient(90deg,#404040 0,#808080) 0 100% no-repeat,linear-gradient(0deg,#404040 0,#404040) 0 100% no-repeat,linear-gradient(0deg,#808080 0,#808080) 100% 100% no-repeat;background-size:100% 2px,100% 2px,2px 100%,2px 100%}
|
||||
.dropdown-menu{z-index:10001}
|
||||
</style>
|
||||
<table id="kvm_table" class="tablesorter four shift">
|
||||
<thead><tr><th class="th1"><a id="resetsort" class="nohand" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-th-list"></i></a>_(Name)_</th><th class="th2">_(Description)_</th><th>_(CPUs)_</th><th>_(Memory)_</th><th>_(vDisks / vCDs)_</th><th>_(Graphics)_</th><th class="th3">_(Autostart)_</th></tr></thead>
|
||||
<tbody id="kvm_list"><tr><td colspan='8'></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" onclick="addVM()" id="btnAddVM" value="_(Add VM)_" style="display:none">
|
||||
<input type="button" onclick="startAll()" value="_(Start All)_" style="display:none">
|
||||
<input type="button" onclick="stopAll()" value="_(Stop All)_" style="display:none">
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
||||
<script src="<?autov('/plugins/dynamix.vm.manager/javascript/dynamix.vm.manager.js')?>"></script>
|
||||
@@ -166,45 +136,36 @@ function changemedia(uuid,dev,bus,file) {
|
||||
if (file === "--select") getisoimage(uuid,dev,bus,file);
|
||||
if (file === "--eject") ajaxVMDispatch({action:"change-media", uuid:uuid , cdrom:"" , dev:dev , bus:bus , file:file}, "loadlist");
|
||||
}
|
||||
function dialogStyle() {
|
||||
$('.ui-dialog-titlebar-close').css({'display':'none'});
|
||||
$('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'});
|
||||
$('.ui-dialog-content').css({'padding-top':'15px','vertical-align':'bottom'});
|
||||
$('.ui-button-text').css({'padding':'0px 5px'});
|
||||
}
|
||||
function getisoimageboth(uuid,dev,bus,file,dev2,bus2,file2){
|
||||
var root = <?= '"'.$domain_cfg["MEDIADIR"].'"';?>;
|
||||
var match= ".iso";
|
||||
var box = $("#dialogWindow");
|
||||
box.html($("#templateISOboth").html());
|
||||
|
||||
box.find('#target').attr('data-pickroot',root).attr('data-picktop',root).attr('data-pickmatch',match).attr('value', file).fileTreeAttach(null,null,function(path){
|
||||
var bits = path.substr(1).split('/');
|
||||
var auto = bits.length>3 ? '' : share;
|
||||
box.find('#target').val(path+auto).change();
|
||||
});
|
||||
box.find('#target2').attr('data-pickroot',root).attr('data-picktop',root).attr('data-pickmatch',match).attr('value', file2).fileTreeAttach(null,null,function(path){
|
||||
var bits = path.substr(1).split('/');
|
||||
var auto = bits.length>3 ? '' : share;
|
||||
box.find('#target2').val(path+auto).change();
|
||||
});
|
||||
var height = 100;
|
||||
|
||||
box.find('#target').attr('value',file).fileTreeAttach(null,null,function(path){
|
||||
box.find('#target').val(path).change();
|
||||
});
|
||||
box.find('#target2').attr('value',file2).fileTreeAttach(null,null,function(path){
|
||||
box.find('#target2').val(path).change();
|
||||
});
|
||||
box.dialog({
|
||||
title: "Select ISOs for CDROMs",
|
||||
title: "_(Select ISOs for CDROMs)_",
|
||||
height: 530,
|
||||
width: 900,
|
||||
resizable: false,
|
||||
width: 600,
|
||||
height: 300,
|
||||
modal: true,
|
||||
show: {effect:'fade', duration:250},
|
||||
hide: {effect:'fade', duration:250},
|
||||
buttons: {
|
||||
"_(Update)_": function(){
|
||||
var target = box.find('#target');
|
||||
if (target.length) {
|
||||
target = target.val();
|
||||
} else target = '';
|
||||
if (target.length) target = target.val(); else target = '';
|
||||
var target2 = box.find('#target2');
|
||||
if (target2.length) {
|
||||
target2 = target2.val();
|
||||
} else target2 = '';
|
||||
if (target2.length) target2 = target2.val(); else target2 = '';
|
||||
box.find('#target').prop('disabled',true);
|
||||
box.find('#target2').prop('disabled',true);
|
||||
ajaxVMDispatch({action:"change-media-both", uuid:uuid , cdrom:"" , dev:dev , bus:bus , file:target, dev2:dev2 , bus2:bus2 , file2:target2}, "loadlist");
|
||||
ajaxVMDispatch({action:"change-media-both", uuid:uuid, cdrom:"", dev:dev, bus:bus, file:target, dev2:dev2, bus2:bus2, file2:target2}, "loadlist");
|
||||
box.dialog('close');
|
||||
},
|
||||
"_(Cancel)_": function(){
|
||||
@@ -215,34 +176,23 @@ function getisoimageboth(uuid,dev,bus,file,dev2,bus2,file2){
|
||||
dialogStyle();
|
||||
}
|
||||
function getisoimage(uuid,dev,bus,file){
|
||||
var root = <?= '"'.$domain_cfg["MEDIADIR"].'"';?>;
|
||||
var match= ".iso";
|
||||
var box = $("#dialogWindow");
|
||||
box.html($("#templateISO").html());
|
||||
|
||||
box.find('#target').attr('data-pickroot',root).attr('data-picktop',root).attr('data-pickmatch',match).fileTreeAttach(null,null,function(path){
|
||||
var bits = path.substr(1).split('/');
|
||||
var auto = bits.length>3 ? '' : share;
|
||||
box.find('#target').val(path+auto).change();
|
||||
});
|
||||
var height = 100;
|
||||
box.find('#target').attr('value',file).fileTreeAttach(null,null,function(path){
|
||||
box.find('#target').val(path).change();
|
||||
});
|
||||
box.dialog({
|
||||
title: "Select ISO",
|
||||
title: "_(Select ISO)_",
|
||||
height: 530,
|
||||
width: 900,
|
||||
resizable: false,
|
||||
width: 600,
|
||||
height: 300,
|
||||
modal: true,
|
||||
show: {effect:'fade', duration:250},
|
||||
hide: {effect:'fade', duration:250},
|
||||
buttons: {
|
||||
"_(Insert)_": function(){
|
||||
var target = box.find('#target');
|
||||
if (target.length) {
|
||||
target = target.val();
|
||||
if (!target ) {errorTarget(); return;}
|
||||
} else target = '';
|
||||
if (target.length) target = target.val(); else target = '';
|
||||
box.find('#target').prop('disabled',true);
|
||||
ajaxVMDispatch({action:"change-media", uuid:uuid , cdrom:"" , dev:dev , bus:bus , file:target}, "loadlist");
|
||||
ajaxVMDispatch({action:"change-media", uuid:uuid, cdrom:"", dev:dev, bus:bus, file:target}, "loadlist");
|
||||
box.dialog('close');
|
||||
},
|
||||
"_(Cancel)_": function(){
|
||||
@@ -253,44 +203,32 @@ function getisoimage(uuid,dev,bus,file){
|
||||
dialogStyle();
|
||||
}
|
||||
function VMClone(uuid, name){
|
||||
|
||||
//var root = <?= '"'.$domain_cfg["MEDIADIR"].'"';?>;
|
||||
var match= ".iso";
|
||||
var box = $("#dialogWindow");
|
||||
var height = 200;
|
||||
box.html($("#templateClone").html());
|
||||
box.find('#VMBeingCloned').html(name).change() ;
|
||||
box.find('#target').val(name + "_clone") ;
|
||||
document.getElementById("Free").checked = true ;
|
||||
document.getElementById("Overwrite").checked = true ;
|
||||
var Cancel = _("Cancel") ;
|
||||
box.find('#VMBeingCloned').html(name).change();
|
||||
box.find('#target').val(name + "_clone");
|
||||
document.getElementById("Free").checked = true;
|
||||
document.getElementById("Overwrite").checked = true;
|
||||
box.dialog({
|
||||
title: "VM Clone",
|
||||
resizable: false,
|
||||
title: "_(VM Clone)_",
|
||||
height: 'auto',
|
||||
width: 600,
|
||||
height: 500,
|
||||
resizable: false,
|
||||
modal: true,
|
||||
show: {effect:'fade', duration:250},
|
||||
hide: {effect:'fade', duration:250},
|
||||
buttons: {
|
||||
"_(Clone)_" : function(){
|
||||
"_(Clone)_": function(){
|
||||
var target = box.find('#target');
|
||||
if (target.length) {
|
||||
target = target.val();
|
||||
//if (!target ) {errorTarget(); return;}
|
||||
//if (!target) {errorTarget(); return;}
|
||||
} else target = '';
|
||||
|
||||
var clone = box.find("#target").prop('value') ;
|
||||
x = box.find('#Start').prop('checked') ;
|
||||
if (x) start = 'yes' ; else start = 'no' ;
|
||||
x = box.find('#Edit').prop('checked') ;
|
||||
if (x) edit = 'yes' ; else edit = 'no' ;
|
||||
x = box.find('#Overwrite').prop('checked') ;
|
||||
if (x) overwrite = 'yes' ; else overwrite = 'no' ;
|
||||
x = box.find('#Free').prop('checked') ;
|
||||
if (x) free = 'yes' ; else free = 'no' ;
|
||||
scripturl = "VMClone.php " + encodeURIComponent("/usr/local/emhttp/plugins/dynamix.vm.manager/include/VMClone.php&" + $.param({action:"clone" , name:name ,clone:clone, overwrite:overwrite , edit:edit, start,start, free:free})) ;
|
||||
openVMAction((scripturl),"VM Clone", "dynamix.vm.manager", "loadlist") ;
|
||||
var clone = box.find("#target").prop('value');
|
||||
var start = box.find('#Start').prop('checked') ? 'yes' : 'no';
|
||||
var edit = box.find('#Edit').prop('checked') ? 'yes' : 'no';
|
||||
var overwrite = box.find('#Overwrite').prop('checked') ? 'yes' : 'no';
|
||||
var free = box.find('#Free').prop('checked') ? 'yes' : 'no';
|
||||
scripturl = "VMClone.php " + encodeURIComponent("/usr/local/emhttp/plugins/dynamix.vm.manager/include/VMClone.php&" + $.param({action:"clone", name:name, clone:clone, overwrite:overwrite, edit:edit, start:start, free:free}));
|
||||
openVMAction((scripturl),"VM Clone", "dynamix.vm.manager", "loadlist");
|
||||
box.dialog('close');
|
||||
},
|
||||
"_(Cancel)_": function(){
|
||||
@@ -300,44 +238,30 @@ function VMClone(uuid, name){
|
||||
});
|
||||
dialogStyle();
|
||||
}
|
||||
|
||||
|
||||
function selectsnapshot(uuid, name ,snaps, opt, getlist,state){
|
||||
|
||||
var root = <?= '"'.$domain_cfg["MEDIADIR"].'"';?>;
|
||||
var match= ".iso";
|
||||
var box = $("#dialogWindow2");
|
||||
var box = $("#dialogWindow");
|
||||
box.html($("#templatesnapshot"+opt).html());
|
||||
var height = 200;
|
||||
const Capopt = opt.charAt(0).toUpperCase() + opt.slice(1) ;
|
||||
var optiontext = Capopt + " Snapshot" ;
|
||||
box.find('#VMName').html(name) ;
|
||||
box.find('#targetsnap').val(snaps) ;
|
||||
box.find('#targetsnapl').html(snaps) ;
|
||||
const capopt = opt.charAt(0).toUpperCase() + opt.slice(1);
|
||||
var optiontext = capopt + " _(Snapshot)_";
|
||||
box.find('#VMName').html(name);
|
||||
box.find('#targetsnap').val(snaps);
|
||||
box.find('#targetsnapl').html(snaps);
|
||||
if (getlist) {
|
||||
var only = 1 ;
|
||||
if (opt == "remove") only = 0;
|
||||
$.post("/plugins/dynamix.vm.manager/include/VMajax.php", {action:"snap-images", uuid:uuid , snapshotname:snaps, only:only}, function(data) {
|
||||
if (data.html) {
|
||||
box.find('#targetsnapimages').html(data.html) ;
|
||||
}
|
||||
var only = (opt == "remove") ? 0 : 1;
|
||||
$.post("/plugins/dynamix.vm.manager/include/VMajax.php", {action:"snap-images", uuid:uuid, snapshotname:snaps, only:only}, function(data) {
|
||||
if (data.html) box.find('#targetsnapimages').html(data.html);
|
||||
},'json');
|
||||
}
|
||||
|
||||
document.getElementById("targetsnaprmv").checked = true ;
|
||||
document.getElementById("targetsnaprmvmeta").checked = true ;
|
||||
document.getElementById("targetsnapkeep").checked = true ;
|
||||
document.getElementById("targetsnapfspc").checked = true ;
|
||||
|
||||
document.getElementById("targetsnaprmv").checked = true;
|
||||
document.getElementById("targetsnaprmvmeta").checked = true;
|
||||
document.getElementById("targetsnapkeep").checked = true;
|
||||
document.getElementById("targetsnapfspc").checked = true;
|
||||
box.dialog({
|
||||
title: "_("+optiontext+ ")_",
|
||||
resizable: false,
|
||||
title: optiontext,
|
||||
height: 'auto',
|
||||
width: 600,
|
||||
height: 500,
|
||||
resizable: false,
|
||||
modal: true,
|
||||
show: {effect:'fade', duration:250},
|
||||
hide: {effect:'fade', duration:250},
|
||||
|
||||
buttons: {
|
||||
"_(Proceed)_": function(){
|
||||
var target = box.find('#targetsnap');
|
||||
@@ -345,26 +269,22 @@ function selectsnapshot(uuid, name ,snaps, opt, getlist,state){
|
||||
target = target.val();
|
||||
if (!target ) {errorTarget(); return;}
|
||||
} else target = '';
|
||||
var remove = 'yes'
|
||||
var keep = 'yes'
|
||||
var removemeta = 'yes'
|
||||
var remove = 'yes'
|
||||
var keep = 'yes'
|
||||
var removemeta = 'yes'
|
||||
var free = 'yes'
|
||||
var desc = ''
|
||||
box.find('#targetsnap').prop('disabled',true);
|
||||
if (opt == "revert") {
|
||||
var x = box.find('#targetsnaprmv').prop('checked') ;
|
||||
if (x) remove = 'yes' ; else remove = 'no' ;
|
||||
x = box.find('#targetsnaprmvmeta').prop('checked') ;
|
||||
if (x) removemeta = 'yes' ; else removemeta = 'no' ;
|
||||
x = box.find('#targetsnapkeep').prop('checked') ;
|
||||
if (x) keep = 'yes' ; else keep = 'no' ;
|
||||
remove = box.find('#targetsnaprmv').prop('checked') ? 'yes' : 'no';
|
||||
removemeta = box.find('#targetsnaprmvmeta').prop('checked') ? 'yes' : 'no';
|
||||
keep = box.find('#targetsnapkeep').prop('checked') ? 'yes' : 'no';
|
||||
}
|
||||
if (opt == "create") {
|
||||
var x = box.find('#targetsnapfspc').prop('checked') ;
|
||||
if (x) free = 'yes' ; else free = 'no' ;
|
||||
var desc = box.find("#targetsnapdesc").prop('value') ;
|
||||
if (opt == "create") {
|
||||
free = box.find('#targetsnapfspc').prop('checked') ? 'yes' : 'no';
|
||||
desc = box.find("#targetsnapdesc").prop('value');
|
||||
}
|
||||
ajaxVMDispatch({action:"snap-" + opt +'-external', uuid:uuid , snapshotname:target , remove:remove, free:free ,removemeta:removemeta ,keep:keep, desc:desc} , "loadlist");
|
||||
ajaxVMDispatch({action:"snap-" + opt +'-external', uuid:uuid, snapshotname:target, remove:remove, free:free, removemeta:removemeta, keep:keep, desc:desc}, "loadlist");
|
||||
box.dialog('close');
|
||||
},
|
||||
"_(Cancel)_": function(){
|
||||
@@ -374,86 +294,72 @@ function selectsnapshot(uuid, name ,snaps, opt, getlist,state){
|
||||
});
|
||||
dialogStyle();
|
||||
}
|
||||
|
||||
function selectblock(uuid, name ,snaps, opt, getlist,state){
|
||||
|
||||
var root = <?= '"'.$domain_cfg["MEDIADIR"].'"';?>;
|
||||
var match= ".iso";
|
||||
var box = $("#dialogWindow2");
|
||||
function selectblock(uuid, name, snaps, opt, getlist, state){
|
||||
var box = $("#dialogWindow");
|
||||
box.html($("#templateblock").html());
|
||||
var height = 200;
|
||||
const Capopt = opt.charAt(0).toUpperCase() + opt.slice(1) ;
|
||||
var optiontext = Capopt + " Block Devices" ;
|
||||
box.find('#VMName').html(name) ;
|
||||
box.find('#targetsnap').val(snaps) ;
|
||||
box.find('#targetsnapl').html(snaps) ;
|
||||
|
||||
getlist = true ;
|
||||
const capopt = opt.charAt(0).toUpperCase() + opt.slice(1);
|
||||
var optiontext = capopt + " _(Block Devices)_";
|
||||
box.find('#VMName').html(name);
|
||||
box.find('#targetsnap').val(snaps);
|
||||
box.find('#targetsnapl').html(snaps);
|
||||
getlist = true;
|
||||
if (getlist) {
|
||||
var only = 1 ;
|
||||
var only = 1;
|
||||
if (opt == "remove") only = 0;
|
||||
$.post("/plugins/dynamix.vm.manager/include/VMajax.php", {action:"snap-list", uuid:uuid }, function(data) {
|
||||
if (data.html) {
|
||||
var targetbase = document.getElementById("targetblockbase") ;
|
||||
htmlstrbase = "<select class='targetblockbase' name='targetblockbase' id='targetblockbase'><option value='--base'>--base</option>" + data.html + "</select>"
|
||||
htmlstrtop = "<select class='targetblocktop' name='targetblocktop' id='targetblocktop'><option value='--top'>--top</option>" + data.html + "</select>"
|
||||
$("select.targetblockbase").replaceWith(htmlstrbase) ;
|
||||
$("select.targetblocktop").replaceWith(htmlstrtop) ;
|
||||
}
|
||||
$.post("/plugins/dynamix.vm.manager/include/VMajax.php", {action:"snap-list", uuid:uuid}, function(data){
|
||||
if (data.html) {
|
||||
var targetbase = document.getElementById("targetblockbase");
|
||||
htmlstrbase = "<select class='targetblockbase' name='targetblockbase' id='targetblockbase'><option value='--base'>--base</option>" + data.html + "</select>"
|
||||
htmlstrtop = "<select class='targetblocktop' name='targetblocktop' id='targetblocktop'><option value='--top'>--top</option>" + data.html + "</select>"
|
||||
$("select.targetblockbase").replaceWith(htmlstrbase);
|
||||
$("select.targetblocktop").replaceWith(htmlstrtop);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
document.getElementById("targetsnaprmv").checked = true ;
|
||||
document.getElementById("targetsnaprmvmeta").checked = true ;
|
||||
document.getElementById("targetsnapkeep").checked = true ;
|
||||
document.getElementById("targetsnapfspc").checked = true ;
|
||||
if (opt== "pull") {
|
||||
$('.toprow').hide();
|
||||
$('.targetpivotrow').hide();
|
||||
$('.targetdeleterow').hide();
|
||||
} else {
|
||||
$('.toprow').show();
|
||||
$('.targetpivotrow').show();
|
||||
$('.targetdeleterow').show();
|
||||
}
|
||||
|
||||
document.getElementById("targetsnaprmv").checked = true;
|
||||
document.getElementById("targetsnaprmvmeta").checked = true;
|
||||
document.getElementById("targetsnapkeep").checked = true;
|
||||
document.getElementById("targetsnapfspc").checked = true;
|
||||
if (opt == "pull") {
|
||||
$('.toprow').hide();
|
||||
$('.targetpivotrow').hide();
|
||||
$('.targetdeleterow').hide();
|
||||
} else {
|
||||
$('.toprow').show();
|
||||
$('.targetpivotrow').show();
|
||||
$('.targetdeleterow').show();
|
||||
}
|
||||
box.dialog({
|
||||
title: "_("+optiontext+ ")_",
|
||||
resizable: false,
|
||||
title: optiontext,
|
||||
height: 'auto',
|
||||
width: 600,
|
||||
height: 500,
|
||||
resizable: false,
|
||||
modal: true,
|
||||
show: {effect:'fade', duration:250},
|
||||
hide: {effect:'fade', duration:250},
|
||||
buttons: {
|
||||
_("Action")_: function(){
|
||||
"_(Action)_": function(){
|
||||
var target = box.find('#targetsnap');
|
||||
if (target.length) {
|
||||
target = target.val();
|
||||
if (!target ) {errorTarget(); return;}
|
||||
} else target = '';
|
||||
var remove = 'yes'
|
||||
var keep = 'yes'
|
||||
var removemeta = 'yes'
|
||||
var remove = 'yes'
|
||||
var keep = 'yes'
|
||||
var removemeta = 'yes'
|
||||
var free = 'yes'
|
||||
var delete_file = 'yes'
|
||||
var pivot = 'yes'
|
||||
var desc = ''
|
||||
box.find('#targetsnap').prop('disabled',true);
|
||||
if (opt == "create") {
|
||||
var x = box.find('#targetsnapfspc').prop('checked') ;
|
||||
if (x) free = 'yes' ; else free = 'no' ;
|
||||
var desc = box.find("#targetsnapdesc").prop('value') ;
|
||||
free = box.find('#targetsnapfspc').prop('checked') ? 'yes' : 'no';
|
||||
var desc = box.find("#targetsnapdesc").prop('value');
|
||||
}
|
||||
var targetbase = box.find("#targetblockbase").prop('value') ;
|
||||
var targettop = box.find("#targetblocktop").prop('value') ;
|
||||
|
||||
x = box.find('#targetpivot').prop('checked') ;
|
||||
if (x) pivot = 'yes' ; else pivot = 'no' ;
|
||||
x = box.find('#targetdelete').prop('checked') ;
|
||||
if (x) delete_file = 'yes' ; else delete_file = 'no' ;
|
||||
Ajaxurl = "VMAjaxCall.php " + encodeURIComponent("/usr/local/emhttp/plugins/dynamix.vm.manager/include/VMajax.php&" + $.param({action:opt , name:name ,targetbase:targetbase, targettop:targettop , snapshotname:target , remove:remove, targetpivot:pivot ,removemeta:removemeta ,targetdelete:delete_file})) ;
|
||||
openVMAction((Ajaxurl),"Block Commit", "dynamix.vm.manager", "loadlist") ;
|
||||
var targetbase = box.find("#targetblockbase").prop('value');
|
||||
var targettop = box.find("#targetblocktop").prop('value');
|
||||
pivot = box.find('#targetpivot').prop('checked') ? 'yes' : 'no';
|
||||
delete_file = box.find('#targetdelete').prop('checked') ? 'yes' : 'no';
|
||||
Ajaxurl = "VMAjaxCall.php " + encodeURIComponent("/usr/local/emhttp/plugins/dynamix.vm.manager/include/VMajax.php&" + $.param({action:opt, name:name, targetbase:targetbase, targettop:targettop, snapshotname:target, remove:remove, targetpivot:pivot, removemeta:removemeta, targetdelete:delete_file}));
|
||||
openVMAction((Ajaxurl),"Block Commit", "dynamix.vm.manager", "loadlist");
|
||||
box.dialog('close');
|
||||
},
|
||||
"_(Cancel)_": function(){
|
||||
@@ -463,13 +369,6 @@ function selectblock(uuid, name ,snaps, opt, getlist,state){
|
||||
});
|
||||
dialogStyle();
|
||||
}
|
||||
|
||||
function dialogStyle() {
|
||||
$('.ui-dialog-titlebar-close').css({'background':'transparent','border':'none','font-size':'1.8rem','margin-top':'-14px','margin-right':'-18px'}).html('<i class="fa fa-times"></i>').prop('title');
|
||||
$('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'});
|
||||
$('.ui-dialog-content').css({'padding-top':'15px','vertical-align':'bottom'});
|
||||
$('.ui-button-text').css({'padding':'0px 5px'});
|
||||
}
|
||||
var sortableHelper = function(e,ui){
|
||||
var child = ui.next();
|
||||
if (child.is(':visible')) child.addClass('unhide').hide();
|
||||
@@ -561,123 +460,75 @@ $(function() {
|
||||
});
|
||||
</script>
|
||||
|
||||
<table id="kvm_table" class="tablesorter four shift">
|
||||
<thead><tr><th class="th1"><a id="resetsort" class="nohand" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-th-list"></i></a>_(Name)_</th><th class="th2">_(Description)_</th><th>_(CPUs)_</th><th>_(Memory)_</th><th>_(vDisks / vCDs)_</th><th>_(Graphics)_</th><th>_(IP Address)_</th><th class="th3">_(Autostart)_</th></tr></thead>
|
||||
<tbody id="kvm_list"><tr><td colspan='8'></td></tr></tbody>
|
||||
</table>
|
||||
|
||||
<input type="button" onclick="addVM()" id="btnAddVM" value="_(Add VM)_" style="display:none">
|
||||
<input type="button" onclick="startAll()" value="_(Start All)_" style="display:none">
|
||||
<input type="button" onclick="stopAll()" value="_(Stop All)_" style="display:none">
|
||||
|
||||
<div id="dialogWindow"></div>
|
||||
<div markdown="1" id="templateISO" class="template">
|
||||
_(ISO Image)_:
|
||||
: <input type="text" id="target" autocomplete="off" spellcheck="false" value="" data-pickcloseonfile="true" data-pickfolders="true" data-pickfilter="" data-pickmatch="" data-pickroot="" data-picktop="">
|
||||
|
||||
<div id="templateISO" class="template">
|
||||
<dl>
|
||||
<dt>_(ISO Image)_:</dt>
|
||||
<dd><input type="text" id="target" autocomplete="off" spellcheck="false" value="" data-pickcloseonfile="true" data-pickfolders="true" data-pickfilter="iso"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div markdown="1" id="templateISOboth" class="template">
|
||||
_(CD1 ISO Image)_:
|
||||
: <input type="text" id="target" autocomplete="off" spellcheck="false" value="" data-pickcloseonfile="true" data-pickfolders="true" data-pickfilter="" data-pickmatch="" data-pickroot="" data-picktop=""><br>
|
||||
_(CD2 ISO Image)_:
|
||||
: <input type="text" id="target2" autocomplete="off" spellcheck="false" value="" data-pickcloseonfile="true" data-pickfolders="true" data-pickfilter="" data-pickmatch="" data-pickroot="" data-picktop="">
|
||||
<div id="templateISOboth" class="template">
|
||||
<dl>
|
||||
<dt>_(CD1 ISO Image)_:</dt>
|
||||
<dd><input type="text" id="target" autocomplete="off" spellcheck="false" value="" data-pickcloseonfile="true" data-pickfolders="true" data-pickfilter="iso"></dd>
|
||||
<dt>_(CD2 ISO Image)_:</dt>
|
||||
<dd><input type="text" id="target2" autocomplete="off" spellcheck="false" value="" data-pickcloseonfile="true" data-pickfolders="true" data-pickfilter="iso"></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div id="dialogWindow2"></div>
|
||||
<div markdown="1" id="templatesnapshotcreate" class="template">
|
||||
<table id='snapshot'>
|
||||
<br><br>
|
||||
<tr><td> _(VM Name)_:</td><td>
|
||||
<label id="VMName"></label></td></tr>
|
||||
<tr><td>_(Snapshot Name)_:</td><td>
|
||||
<input type="text" id="targetsnap" autocomplete="off" spellcheck="false" value="--generate" onclick="this.select()">
|
||||
_(Check free space)_:
|
||||
<input type="checkbox" id="targetsnapfspc" checked></td></tr>
|
||||
<tr><td>_(Description )_:</td><td>
|
||||
<input type="text" id="targetsnapdesc" autocomplete="off" spellcheck="false" value="" onclick="this.select()"></td></tr>
|
||||
<div id="templatesnapshotcreate" class="template">
|
||||
<table id='snapshot' class='snapshot'>
|
||||
<tr><td>_(VM Name)_:</td><td><label id="VMName"></label></td></tr>
|
||||
<tr><td>_(Snapshot Name)_:</td><td><input type="text" id="targetsnap" autocomplete="off" spellcheck="false" value="--generate" onclick="this.select()">_(Check free space)_: <input type="checkbox" id="targetsnapfspc" checked></td></tr>
|
||||
<tr><td>_(Description )_:</td><td><input type="text" id="targetsnapdesc" autocomplete="off" spellcheck="false" value="" onclick="this.select()"></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div markdown="1" id="templatesnapshotrevert" class="template">
|
||||
_(VM Name)_:
|
||||
<label id="VMName"></label>
|
||||
<br>
|
||||
_(Snapshot Name)_:
|
||||
<input type="text" id="targetsnap" hidden>
|
||||
<label id="targetsnapl"></label><br>
|
||||
_(Remove Images)_:
|
||||
<input type="checkbox" id="targetsnaprmv" checked >
|
||||
_(Remove Meta)_:
|
||||
<input type="checkbox" id="targetsnaprmvmeta" checked>
|
||||
<!--_(Keep snapshot)_:-->
|
||||
<input type="checkbox" id="targetsnapkeep" hidden><br>
|
||||
<div id="templatesnapshotrevert" class="template">
|
||||
_(VM Name)_: <label id="VMName"></label><br>
|
||||
_(Snapshot Name)_: <input type="text" id="targetsnap" hidden><label id="targetsnapl"></label><br>
|
||||
_(Remove Images)_: <input type="checkbox" id="targetsnaprmv" checked><br>
|
||||
_(Remove Meta)_:<input type="checkbox" id="targetsnaprmvmeta" checked> <input type="checkbox" id="targetsnapkeep" hidden><label id="targetsnapimages"></label><br>
|
||||
</div>
|
||||
|
||||
<label id="targetsnapimages"></label><br>
|
||||
<div id="templatesnapshotremove" class="template">
|
||||
<h3>!! _(Warning removing Snapshots can break the chain)_ !!</h3>
|
||||
|
||||
<div markdown="1" id="templatesnapshotremove" class="template" post>
|
||||
_(!! Warning removing Snapshots can break the chain !!)_<br><br>
|
||||
_(VM Name)_: <label id="VMName"></label><br>
|
||||
_(Snapshot Name)_: <input type="text" id="targetsnap" hidden><label id="targetsnapl"></label><label id="targetsnapimages"></label>
|
||||
</div>
|
||||
|
||||
_(VM Name)_:
|
||||
<label id="VMName"></label>
|
||||
<br>
|
||||
_(Snapshot Name)_:
|
||||
<input type="text" id="targetsnap" hidden>
|
||||
<label id="targetsnapl"></label><br>
|
||||
|
||||
<label id="targetsnapimages"></label><br>
|
||||
|
||||
<div markdown="1" id="templateblock" class="template">
|
||||
_(VM Name)_:
|
||||
<label id="VMName"></label>
|
||||
<br>
|
||||
_(Snapshot Name)_:
|
||||
<input type="text" id="targetsnap" hidden>
|
||||
<label id="targetsnapl"></label><br>
|
||||
<br><br><br><br>
|
||||
<table id='block'>
|
||||
<tr><td>_(Base Image)_:</td><td>
|
||||
<select class="targetblockbase" s>
|
||||
</select></td></tr>
|
||||
<tr name="toprow" class="toprow" ><td>_(Top Image )_:</td><td>
|
||||
<select class="targetblocktop" name="targetblocktop" id="targetblocktop">
|
||||
</select></td><td>
|
||||
<tr name="targetpivotrow" class="targetpivotrow" ><td>_(Pivot)_:</td><td>
|
||||
<input type="checkbox" id="targetpivot" checked></td></tr>
|
||||
<tr name="targetdeleterow" class="targetdeleterow" ><td>_(Delete)_:</td><td>
|
||||
<input type="checkbox" id="targetdelete" checked></td></tr>
|
||||
<div id="templateblock" class="template">
|
||||
_(VM Name)_: <label id="VMName"></label><br>
|
||||
_(Snapshot Name)_: <input type="text" id="targetsnap" hidden><label id="targetsnapl"></label><br><br>
|
||||
<table id='block' class='snapshot'>
|
||||
<tr><td>_(Base Image)_:</td><td><select class="targetblockbase"></select></td></tr>
|
||||
<tr name="toprow" class="toprow" ><td>_(Top Image )_:</td><td><select class="targetblocktop" name="targetblocktop" id="targetblocktop"></select></td><td></tr>
|
||||
<tr name="targetpivotrow" class="targetpivotrow" ><td>_(Pivot)_:</td><td><input type="checkbox" id="targetpivot" checked></td></tr>
|
||||
<tr name="targetdeleterow" class="targetdeleterow" ><td>_(Delete)_:</td><td><input type="checkbox" id="targetdelete" checked></td></tr>
|
||||
</table>
|
||||
<input type="checkbox" id="targetsnapkeep" hidden><br>
|
||||
<label id="targetsnapimages"></label><br>
|
||||
</div>
|
||||
|
||||
<div id="dialogWindow"></div>
|
||||
<div markdown="1" id="templateClone" class="template">
|
||||
<html <?=$display['rtl']?>lang="<?=strtok($locale,'_')?:'en'?>">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="viewport" content="width=1600">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<meta name="referrer" content="same-origin">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov("/webGui/styles/default-fonts.css")?>">
|
||||
</head>
|
||||
<body>
|
||||
<br>
|
||||
<table>
|
||||
<tr><td>_(VM Being Cloned)_:</td>
|
||||
<td><span id="VMBeingCloned"></span></td></tr>
|
||||
|
||||
<tr><td>_(New VM)_:</td>
|
||||
<td><input type="text" id="target" autocomplete="off" spellcheck="false" value="" onclick="this.select()" ></td></tr>
|
||||
|
||||
<tr><td>_(Overwrite)_:</td>
|
||||
<td><input type="checkbox" id="Overwrite" value="" ></td></tr>
|
||||
|
||||
<tr hidden><td>_(Start Cloned VM)_:</td>
|
||||
<td><input type="checkbox" id="Start" value="" ></td></tr>
|
||||
|
||||
<tr hidden><td>_(Edit VM after clone)_:</td>
|
||||
<td><input type="checkbox" id="Edit" value="" ></td></tr>
|
||||
|
||||
<tr><td>_(Check Free Space)_:</td>
|
||||
<td><input type="checkbox" id="Free" value="" ></td></tr>
|
||||
|
||||
<div id="templateClone" class="template">
|
||||
<table class='snapshot'>
|
||||
<tr><td>_(VM Being Cloned)_:</td><td><span id="VMBeingCloned"></span></td></tr>
|
||||
<tr><td>_(New VM)_:</td><td><input type="text" id="target" autocomplete="off" spellcheck="false" value="" onclick="this.select()" ></td></tr>
|
||||
<tr><td>_(Overwrite)_:</td><td><input type="checkbox" id="Overwrite" value="" ></td></tr>
|
||||
<tr hidden><td>_(Start Cloned VM)_:</td><td><input type="checkbox" id="Start" value="" ></td></tr>
|
||||
<tr hidden><td>_(Edit VM after clone)_:</td><td><input type="checkbox" id="Edit" value="" ></td></tr>
|
||||
<tr><td>_(Check Free Space)_:</td><td><input type="checkbox" id="Free" value="" ></td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -5,8 +5,8 @@ Tag="columns"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2015-2023, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -51,7 +51,7 @@ function detect(&$syslinux, $key) {
|
||||
return $value;
|
||||
}
|
||||
$syslinux = file('/boot/syslinux/syslinux.cfg',FILE_IGNORE_NEW_LINES+FILE_SKIP_EMPTY_LINES);
|
||||
$arrValidNetworks = getValidNetworks();
|
||||
$arrValidNetworks = getValidNetworks();
|
||||
$pcie_acs_override = detect($syslinux, 'pcie_acs_override');
|
||||
$vfio_allow_unsafe = detect($syslinux, 'allow_unsafe_interrupts');
|
||||
$bgcolor = strstr('white,azure',$display['theme']) ? '#f2f2f2' : '#1c1c1c';
|
||||
@@ -61,21 +61,6 @@ $libvirt_log = file_exists("/var/log/libvirt/libvirtd.log");
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.filetree.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<style>
|
||||
body{-webkit-overflow-scrolling:touch}
|
||||
.errortext{color:#EF3D47;display:none}
|
||||
.fileTree{background:<?=$bgcolor?>;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:absolute;z-index:100;display:none}
|
||||
.basic{display:block}
|
||||
.advanced{display:none}
|
||||
#winvirtio{display:none}
|
||||
#download_status{margin-left:5px;color:#777;display:none}
|
||||
#download_button{cursor:pointer;margin-left:-2px;color:#08C;display:none;transform:translate(0px,2px)}
|
||||
#download_button.fa-spin{cursor:default;color:#777}
|
||||
#download_button span{font-family:clear-sans}
|
||||
#download_button.fa-spin span{font-family:clear-sans;display:none}
|
||||
#remove_button{cursor:pointer;margin-left:-2px;color:#EF3D47;display:none;transform:translate(0px,2px)}
|
||||
#remove_button span{font-family:clear-sans}
|
||||
</style>
|
||||
|
||||
<?if ($hardware):?>
|
||||
<span class="status vhshift"><input type="checkbox" class="advancedview"></span>
|
||||
@@ -99,6 +84,14 @@ _(Enable VMs)_:
|
||||
|
||||
:vms_enable_help:
|
||||
|
||||
_(Disable Autostart/Start option for VMs)_:
|
||||
: <select id="DISABLE" name="DISABLE">
|
||||
<?= mk_option(htmlspecialchars($domain_cfg['DISABLE']), 'no', _('No'))?>
|
||||
<?= mk_option(htmlspecialchars($domain_cfg['DISABLE']), 'yes', _('Yes'))?>
|
||||
</select>
|
||||
|
||||
:vms_disable_help:
|
||||
|
||||
<?if ($hardware):?>
|
||||
<div class="advanced" markdown="1">
|
||||
<?if ($libvirt_up):?>
|
||||
@@ -233,7 +226,7 @@ _(VFIO allow unsafe interrupts)_:
|
||||
_(btrfs filesystem show)_:
|
||||
: <?="<pre id='btrfs-scrub'>".shell_exec("btrfs filesystem show /etc/libvirt")."</pre>"?>
|
||||
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareFS(this,'btrfs-scrub-vm','/etc/libvirt'>">
|
||||
<form markdown="1" method="POST" action="/update.php" target="progressFrame" onsubmit="prepareFS(this,'btrfs-scrub-vm','/etc/libvirt')>">
|
||||
<?exec("$docroot/webGui/scripts/btrfs_scrub status /etc/libvirt", $scrub_status, $retval);?>
|
||||
_(btrfs scrub status)_:
|
||||
: <?="<pre>".implode("\n", $scrub_status)."</pre>"?>
|
||||
|
||||
@@ -4,8 +4,9 @@ Cond="(pgrep('libvirtd')!==false)"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -15,14 +16,8 @@ Markdown="false"
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
?>
|
||||
<style type="text/css">
|
||||
.vmheader{padding:10px;font-size:1.4rem;text-align:left;color:#888}
|
||||
.vmtemplate{display:inline-block;width:80px;height:90px;margin-bottom:15px;margin-left:10px;text-align:center;vertical-align:top}
|
||||
.vmtemplate img{width:48px;height:48px}
|
||||
.vmtemplate p{text-align:center;margin-top:8px;line-height:12px}
|
||||
</style>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
foreach($arrAllTemplates as $strName => $arrTemplate):
|
||||
|
||||
@@ -5,8 +5,9 @@ Lock="true"
|
||||
Cond="exec(\"grep -o '^SERVICE=.enable' /boot/config/domain.cfg 2>/dev/null\")"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2021, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,14 +12,14 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'vms';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
|
||||
require_once "$docroot/plugins/dynamix/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
// get Fedora download archive
|
||||
$fedora = '/var/tmp/fedora-virtio-isos';
|
||||
$archive = 'https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2015-2023, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,13 +12,13 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'vms';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
$user_prefs = '/boot/config/plugins/dynamix.vm.manager/userprefs.cfg';
|
||||
if (file_exists('/boot/config/plugins/dynamix.vm.manager/vmpreview')) $vmpreview = true ; else $vmpreview = false ;
|
||||
@@ -28,7 +28,7 @@ if (empty($vms)) {
|
||||
return;
|
||||
}
|
||||
if (file_exists($user_prefs)) {
|
||||
$prefs = @parse_ini_file($user_prefs) ?: [];
|
||||
$prefs = (array)@parse_ini_file($user_prefs);
|
||||
$sort = [];
|
||||
foreach ($vms as $vm) $sort[] = array_search($vm,$prefs);
|
||||
array_multisort($sort,SORT_NUMERIC,$vms);
|
||||
@@ -75,27 +75,31 @@ foreach ($vms as $vm) {
|
||||
$autoport = $lv->domain_get_vmrc_autoport($res);
|
||||
$vmrcurl = '';
|
||||
$graphics = '';
|
||||
$virtual = false ;
|
||||
if ($vmrcport > 0) {
|
||||
$wsport = $lv->domain_get_ws_port($res);
|
||||
$vmrcprotocol = $lv->domain_get_vmrc_protocol($res);
|
||||
$vmrcurl = autov('/plugins/dynamix.vm.manager/'.$vmrcprotocol.'.html',true).'&autoconnect=true&host='._var($_SERVER,'HTTP_HOST');
|
||||
if ($vmrcprotocol == "spice") $vmrcurl .= '&vmname='. urlencode($vm) .'&port=/wsproxy/'.$vmrcport.'/'; else $vmrcurl .= '&port=&path=/wsproxy/'.$wsport.'/';
|
||||
$graphics = strtoupper($vmrcprotocol).":".$vmrcport;
|
||||
$graphics = strtoupper($vmrcprotocol).":".$vmrcport."\n";
|
||||
$virtual = true ;
|
||||
} elseif ($vmrcport == -1 || $autoport) {
|
||||
$vmrcprotocol = $lv->domain_get_vmrc_protocol($res);
|
||||
if ($autoport == "yes") $auto = "auto"; else $auto="manual";
|
||||
$graphics = strtoupper($vmrcprotocol).':'._($auto);
|
||||
} elseif (!empty($arrConfig['gpu'])) {
|
||||
$graphics = strtoupper($vmrcprotocol).':'._($auto)."\n";
|
||||
$virtual = true ;
|
||||
}
|
||||
if (!empty($arrConfig['gpu'])) {
|
||||
$arrValidGPUDevices = getValidGPUDevices();
|
||||
foreach ($arrConfig['gpu'] as $arrGPU) {
|
||||
foreach ($arrValidGPUDevices as $arrDev) {
|
||||
if ($arrGPU['id'] == $arrDev['id']) {
|
||||
if (count(array_filter($arrValidGPUDevices, function($v) use ($arrDev) { return $v['name'] == $arrDev['name']; })) > 1) {
|
||||
$graphics .= $arrDev['name'].' ('.$arrDev['id'].')'."\n";
|
||||
$vmrcprotocol = "VGA";
|
||||
if (!$virtual) $vmrcprotocol = "VGA";
|
||||
} else {
|
||||
$graphics .= $arrDev['name']."\n";
|
||||
$vmrcprotocol = "VGA";
|
||||
if (!$virtual) $vmrcprotocol = "VGA";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,10 +130,9 @@ foreach ($vms as $vm) {
|
||||
}
|
||||
|
||||
/* VM information */
|
||||
|
||||
if ($snapshots != null) $snapshotstr = _("(Snapshots :").count($snapshots).')' ; else $snapshotstr = _("(Snapshots :None)") ;
|
||||
$cdbus = $cdbus2 = $cdfile = $cdfile2 = "" ;
|
||||
$cdromcount = 0 ;
|
||||
if ($snapshots != null) $snapshotstr = _("(Snapshots :").count($snapshots).')'; else $snapshotstr = _("(Snapshots :None)");
|
||||
$cdbus = $cdbus2 = $cdfile = $cdfile2 = "";
|
||||
$cdromcount = 0;
|
||||
foreach ($cdroms as $arrCD) {
|
||||
$disk = $arrCD['file'] ?? $arrCD['partition'];
|
||||
$dev = $arrCD['device'];
|
||||
@@ -137,30 +140,67 @@ foreach ($vms as $vm) {
|
||||
if ($dev == "hda") {
|
||||
$cdbus = $arrValidDiskBuses[$arrCD['bus']] ?? 'VirtIO';
|
||||
$cdfile = $arrCD['file'] ?? $arrCD['partition'];
|
||||
if ($cdfile != "") $cdromcount++ ;
|
||||
if ($cdfile != "") $cdromcount++;
|
||||
}
|
||||
if ($dev == "hdb") {
|
||||
$cdbus2 = $arrValidDiskBuses[$arrCD['bus']] ?? 'VirtIO';
|
||||
$cdfile2 = $arrCD['file'] ?? $arrCD['partition'];
|
||||
if ($cdfile2 != "") $cdromcount++ ;
|
||||
if ($cdfile2 != "") $cdromcount++;
|
||||
}
|
||||
}
|
||||
|
||||
$ipliststr = $iptablestr = "" ;
|
||||
$gastate = getgastate($res);
|
||||
if ($gastate == "connected") {
|
||||
$ip = $lv->domain_interface_addresses($res, 1);
|
||||
if ($ip != false) {
|
||||
$duplicates = []; // hide duplicate interface names
|
||||
foreach ($ip as $arrIP) {
|
||||
$ipname = $arrIP["name"];
|
||||
if (preg_match('/^(lo|Loopback)/',$ipname)) continue; // omit loopback interface
|
||||
$iphdwadr = $arrIP["hwaddr"] == "" ? _("N/A") : $arrIP["hwaddr"];
|
||||
$iplist = $arrIP["addrs"];
|
||||
foreach ($iplist as $arraddr) {
|
||||
$ipaddrval = $arraddr["addr"];
|
||||
if (preg_match('/^f[c-f]/',$ipaddrval)) continue; // omit ipv6 private addresses
|
||||
$iptype = $arraddr["type"] ? "ipv6" : "ipv4";
|
||||
$ipprefix = $arraddr["prefix"];
|
||||
$ipnamemac = "$ipname ($iphdwadr)";
|
||||
if (!in_array($ipnamemac,$duplicates)) $duplicates[] = $ipnamemac; else $ipnamemac = "";
|
||||
$ipliststr .= "<tr><td>$ipnamemac</td><td></td><td></td><td>$iptype</td><td>$ipaddrval</td><td>$ipprefix</td></tr>";
|
||||
$iptablestr .= "$ipaddrval/$ipprefix\n" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($gastate == "disconnected") {
|
||||
$ipliststr .= "<tr><td>"._('Guest agent not installed')."</td><td></td><td></td><td></td></tr>";
|
||||
$iptablestr = _('Requires guest agent installed');
|
||||
} else {
|
||||
$ipliststr = "<tr><td>"._('Guest not running')."</td><td></td><td></td><td></td><td></td></tr>";
|
||||
$iptablestr = _('Requires guest running');
|
||||
}
|
||||
}
|
||||
$iptablestr = str_replace("\n", "<br>", trim($iptablestr));
|
||||
|
||||
$changemedia = "getisoimageboth(\"{$uuid}\",\"hda\",\"{$cdbus}\",\"{$cdfile}\",\"hdb\",\"{$cdbus2}\",\"{$cdfile2}\")";
|
||||
$cdstr = $cdromcount." / 2<a class='hand' title='$title' href='#' onclick='$changemedia'> <i class='fa fa-bullseye' ></i></a>";
|
||||
$title = _('Select ISO image');
|
||||
$cdstr = $cdromcount." / 2<a class='hand' title='$title' href='#' onclick='$changemedia'><i class='fa fa-circle-o'></i></a>";
|
||||
echo "<tr parent-id='$i' class='sortable'><td class='vm-name' style='width:220px;padding:8px'><i class='fa fa-arrows-v mover orange-text'></i>";
|
||||
echo "<span class='outer'><span id='vm-$uuid' $menu class='hand'>$image</span><span class='inner'><a href='#' onclick='return toggle_id(\"name-$i\")' title='click for more VM info'>$vm</a><br><i class='fa fa-$shape $status $color'></i><span class='state'>"._($status)." $snapshotstcount</span></span></span></td>";
|
||||
echo "<td>$desc</td>";
|
||||
echo "<td><a class='vcpu-$uuid' style='cursor:pointer'>$vcpu</a></td>";
|
||||
echo "<td>$mem</td>";
|
||||
echo "<td title='$diskdesc'><span class='state' >$disks $cdstr<br>$snapshotstr</span></td>";
|
||||
echo "<td>$graphics</td>";
|
||||
echo "<td><span class='vmgraphics'>$graphics</td>";
|
||||
echo "<td><span class='vmgraphics'>$iptablestr</td>";
|
||||
echo "<td><input class='autostart' type='checkbox' name='auto_{$vm}' title=\""._('Toggle VM autostart')."\" uuid='$uuid' $autostart></td></tr>";
|
||||
|
||||
/* Disk device information */
|
||||
echo "<tr child-id='$i' id='name-$i".(in_array('name-'.$i++,$show) ? "'>" : "' style='display:none'>");
|
||||
echo "<td colspan='8' style='margin:0;padding:0'>";
|
||||
echo "<table class='tablesorter domdisk'>";
|
||||
echo "<thead class='child'><tr><th><i class='fa fa-hdd-o'></i> <b>"._('Disk devices')."</b></th><th>"._('Serial')."</b></th><th>"._('Bus')."</th><th>"._('Capacity')."</th><th>"._('Allocation')."</th><th>Boot Order</th</tr></thead>";
|
||||
echo "<thead class='child'><tr><th><i class='fa fa-hdd-o'></i> <b>",_('Disk devices'),"</b></th><th>",_('Serial'),"</b></th><th>",_('Bus'),"</th><th>",_('Capacity'),"</th><th>",_('Allocation'),"</th><th>Boot Order</th</tr></thead>";
|
||||
echo "<tbody class='child'>";
|
||||
|
||||
/* Display VM disks */
|
||||
@@ -172,7 +212,7 @@ foreach ($vms as $vm) {
|
||||
$bus = $arrValidDiskBuses[$arrDisk['bus']] ?? 'VirtIO';
|
||||
$boot= $arrDisk["boot order"];
|
||||
$serial = $arrDisk["serial"];
|
||||
if ($boot < 1) $boot="Not set";
|
||||
if ($boot < 1) $boot = _('Not set');
|
||||
echo "<tr><td>$disk</td><td>$serial</td><td>$bus</td>";
|
||||
if ($state == 'shutoff') {
|
||||
echo "<td title='Click to increase Disk Size'>";
|
||||
@@ -196,85 +236,56 @@ foreach ($vms as $vm) {
|
||||
$capacity = $lv->format_size($arrCD['capacity'], 0);
|
||||
$allocation = $lv->format_size($arrCD['allocation'], 0);
|
||||
$disk = $arrCD['file'] ?? $arrCD['partition'] ?? "" ;
|
||||
$dev = $arrCD['device'];
|
||||
$bus = $arrValidDiskBuses[$arrCD['bus']] ?? 'VirtIO';
|
||||
$boot= $arrCD["boot order"] ?? "" ;
|
||||
if ($boot < 1) $boot="Not set";
|
||||
$dev = $arrCD['device'];
|
||||
$bus = $arrValidDiskBuses[$arrCD['bus']] ?? 'VirtIO';
|
||||
$boot = $arrCD["boot order"] ?? "" ;
|
||||
if ($boot < 1) $boot = _('Not set');
|
||||
if ($disk != "" ) {
|
||||
$title = _("Eject CD Drive").".";
|
||||
$changemedia = "changemedia(\"{$uuid}\",\"{$dev}\",\"{$bus}\", \"--eject\")";
|
||||
echo "<tr><td>$disk <a title='$title' href='#' onclick='$changemedia'> <i class='fa fa-eject' aria-hidden=true></i></a></td><td></td><td>$bus</td><td>$capacity</td><td>$allocation</td><td>$boot</td></tr>";
|
||||
$title = _('Eject CD Drive');
|
||||
$changemedia = "changemedia(\"{$uuid}\",\"{$dev}\",\"{$bus}\", \"--eject\")";
|
||||
echo "<tr><td>$disk <a title='$title' href='#' onclick='$changemedia'> <i class='fa fa-eject'></i></a></td><td></td><td>$bus</td><td>$capacity</td><td>$allocation</td><td>$boot</td></tr>";
|
||||
} else {
|
||||
$title = _("Insert CD").".";
|
||||
$title = _('Insert CD');
|
||||
$changemedia = "changemedia(\"{$uuid}\",\"{$dev}\",\"{$bus}\",\"--select\")";
|
||||
$disk = _("No CD image inserted in to drive");
|
||||
echo "<tr><td>$disk<a title='$title' href='#' onclick='$changemedia'> <i class='fa fa-bullseye' aria-hidden=true></i></a> </td><td></td><td>$bus</td><td>$capacity</td><td>$allocation</td><td>$boot</td></tr>";
|
||||
|
||||
echo "<tr><td>$disk<a title='$title' href='#' onclick='$changemedia'><i class='fa fa-circle-o'></i></a></td><td></td><td>$bus</td><td>$capacity</td><td>$allocation</td><td>$boot</td></tr>";
|
||||
}
|
||||
|
||||
}
|
||||
echo "</tbody>";
|
||||
/* Display VM IP Addresses "execute":"guest-network-get-interfaces" --pretty */
|
||||
echo "<thead class='child'><tr><th><i class='fa fa-sitemap'></i> <b>"._('Interfaces')."</b></th><th></th><th></th><th>"._('Type')."</th><th>"._('IP Address')."</th><th>"._('Prefix')."</th></tr></thead>";
|
||||
echo "<thead class='child'><tr><th><i class='fa fa-sitemap'></i> <b>",_('Interfaces')."</b></th><th></th><th></th><th>",_('Type')."</th><th>",_('IP Address'),"</th><th>",_('Prefix'),"</th></tr></thead>";
|
||||
echo "<tbody class='child'>";
|
||||
$gastate = getgastate($res);
|
||||
if ($gastate == "connected") {
|
||||
$ip = $lv->domain_interface_addresses($res, 1);
|
||||
if ($ip != false) {
|
||||
$duplicates = []; // hide duplicate interface names
|
||||
foreach ($ip as $arrIP) {
|
||||
$ipname = $arrIP["name"];
|
||||
if (preg_match('/^(lo|Loopback)/',$ipname)) continue; // omit loopback interface
|
||||
$iphdwadr = $arrIP["hwaddr"] == "" ? _("N/A") : $arrIP["hwaddr"];
|
||||
$iplist = $arrIP["addrs"];
|
||||
foreach ($iplist as $arraddr) {
|
||||
$ipaddrval = $arraddr["addr"];
|
||||
if (preg_match('/^f[c-f]/',$ipaddrval)) continue; // omit ipv6 private addresses
|
||||
$iptype = $arraddr["type"] ? "ipv6" : "ipv4";
|
||||
$ipprefix = $arraddr["prefix"];
|
||||
$ipnamemac = "$ipname ($iphdwadr)";
|
||||
if (!in_array($ipnamemac,$duplicates)) $duplicates[] = $ipnamemac; else $ipnamemac = "";
|
||||
echo "<tr><td>$ipnamemac</td><td></td><td></td><td>$iptype</td><td>$ipaddrval</td><td>$ipprefix</td></tr>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($gastate == "disconnected") echo "<tr><td>"._('Guest agent not installed')."</td><td></td><td></td><td></td></tr>";
|
||||
else echo "<tr><td>"._('Guest not running')."</td><td></td><td></td><td></td><td></td></tr>";
|
||||
}
|
||||
echo $ipliststr ;
|
||||
echo "</tbody>";
|
||||
/* Display VM Snapshots */
|
||||
if ($snapshots != null) {
|
||||
$j=0 ;
|
||||
$steps = array() ;
|
||||
foreach($snapshots as $snap) {
|
||||
$j = 0;
|
||||
$steps = array();
|
||||
foreach ($snapshots as $snap) {
|
||||
if ($snap['parent'] == "" || $snap['parent'] == "Base") $j++;
|
||||
$steps[$j] .= $snap['name'].';' ;
|
||||
}
|
||||
echo "<thead class='child' child-id='$i'><tr><th><i class='fa fa-clone'></i> <b>"._('Snapshots')."</b></th><th></th><th>"._('Date/Time')."</th><th>"._('Type')."</th><th>"._('Parent')."</th><th>"._('Memory')."</th></tr></thead>";
|
||||
echo "<tbody class='child'child-id='$i'>";
|
||||
foreach($steps as $stepsline)
|
||||
{
|
||||
$snapshotlist = explode(";",$stepsline) ;
|
||||
$tab = " " ;
|
||||
foreach($snapshotlist as $snapshotitem) {
|
||||
if ($snapshotitem == "") continue ;
|
||||
$snapshot = $snapshots[$snapshotitem] ;
|
||||
$snapshotstate = _(ucfirst($snapshot["state"])) ;
|
||||
$snapshotdesc = $snapshot["desc"] ;
|
||||
$snapshotmemory = _(ucfirst($snapshot["memory"]["@attributes"]["snapshot"])) ;
|
||||
$snapshotparent = $snapshot["parent"] ? $snapshot["parent"] : "None";
|
||||
$snapshotdatetime = my_time($snapshot["creationtime"],"Y-m-d" )."<br>".my_time($snapshot["creationtime"],"H:i:s") ;
|
||||
$snapmenu = sprintf("onclick=\"addVMSnapContext('%s','%s','%s','%s','%s','%s')\"", addslashes($vm),addslashes($uuid),addslashes($template),$state,$snapshot["name"],$vmpreview);
|
||||
echo "<tr><td><span id='vmsnap-$uuid' $snapmenu class='hand'>$tab|__ <i class='fa fa-clone'></i></span> ".$snapshot["name"]."</td><td>$snapshotdesc</td><td><span class='inner' style='font-size:1.1rem;'>$snapshotdatetime</span></td><td>$snapshotstate</td><td>$snapshotparent</td><td>$snapshotmemory</td></tr>";
|
||||
$tab .=" " ;
|
||||
$steps[$j] .= $snap['name'].';';
|
||||
}
|
||||
echo "<thead class='child' child-id='$i'><tr><th><i class='fa fa-clone'></i> <b>",_('Snapshots'),"</b></th><th></th><th>",_('Date/Time'),"</th><th>",_('Type'),"</th><th>",_('Parent'),"</th><th>",_('Memory'),"</th></tr></thead>";
|
||||
echo "<tbody class='child'child-id='$i'>";
|
||||
foreach ($steps as $stepsline) {
|
||||
$snapshotlist = explode(";",$stepsline);
|
||||
$tab = " ";
|
||||
foreach ($snapshotlist as $snapshotitem) {
|
||||
if ($snapshotitem == "") continue;
|
||||
$snapshot = $snapshots[$snapshotitem] ;
|
||||
$snapshotstate = _(ucfirst($snapshot["state"]));
|
||||
$snapshotdesc = $snapshot["desc"];
|
||||
$snapshotmemory = _(ucfirst($snapshot["memory"]["@attributes"]["snapshot"]));
|
||||
$snapshotparent = $snapshot["parent"] ? $snapshot["parent"] : "None";
|
||||
$snapshotdatetime = my_time($snapshot["creationtime"],"Y-m-d" )."<br>".my_time($snapshot["creationtime"],"H:i:s");
|
||||
$snapmenu = sprintf("onclick=\"addVMSnapContext('%s','%s','%s','%s','%s','%s')\"", addslashes($vm),addslashes($uuid),addslashes($template),$state,$snapshot["name"],$vmpreview);
|
||||
echo "<tr><td><span id='vmsnap-$uuid' $snapmenu class='hand'>$tab|__ <i class='fa fa-clone'></i></span> ",$snapshot["name"],"</td><td>$snapshotdesc</td><td><span class='inner' style='font-size:1.1rem;'>$snapshotdatetime</span></td><td>$snapshotstate</td><td>$snapshotparent</td><td>$snapshotmemory</td></tr>";
|
||||
$tab .=" ";
|
||||
}
|
||||
echo "</tbody>";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
|
||||
echo "\0".implode($kvm);
|
||||
?>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
$user_prefs = '/boot/config/plugins/dynamix.vm.manager/userprefs.cfg';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2015-2023, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -12,13 +12,13 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = 'vms';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
function requireLibvirt() {
|
||||
global $lv;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2015-2023, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -11,14 +12,15 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
// add translations
|
||||
if (substr($_SERVER['REQUEST_URI'],0,4) != '/VMs') {
|
||||
$_SERVER['REQUEST_URI'] = 'vms';
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
}
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
switch ($display['theme']) {
|
||||
case 'gray' : $bgcolor = '#121510'; $border = '#606e7f'; $top = -44; break;
|
||||
@@ -88,55 +90,6 @@ if (isset($_GET['uuid'])) {
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.filetree.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
|
||||
<style>
|
||||
body{-webkit-overflow-scrolling:touch}
|
||||
.fileTree{background:<?=$bgcolor?>;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:relative;z-index:100;display:none}
|
||||
#vmform table{margin-top:0}
|
||||
#vmform div.title + table{margin-top:0}
|
||||
#vmform table tr{vertical-align:top;line-height:40px}
|
||||
#vmform table tr td:nth-child(odd){width:300px;text-align:right;padding-right:10px}
|
||||
#vmform table tr td:nth-child(even){width:110px}
|
||||
#vmform table tr td:first-child{padding-right:30px}
|
||||
#vmform table tr td:last-child{width:inherit}
|
||||
#vmform .multiple{position:relative}
|
||||
#vmform .sectionbutton{position:absolute;left:2px;cursor:pointer;opacity:0.4;font-size:1.4rem;line-height:17px;z-index:10;transition-property:opacity,left;transition-duration:0.1s;transition-timing-function:linear}
|
||||
#vmform .sectionbutton.remove{top:0;opacity:0.3}
|
||||
#vmform .sectionbutton.add{bottom:0}
|
||||
#vmform .sectionbutton:hover{opacity:1.0}
|
||||
#vmform .sectiontab{position:absolute;top:2px;bottom:2px;left:0;width:6px;border-radius:3px;background-color:#DDDDDD;transition-property:background,width;transition-duration:0.1s;transition-timing-function:linear}
|
||||
#vmform .multiple:hover .sectionbutton{opacity:0.7;left:4px}
|
||||
#vmform .multiple:hover .sectionbutton.remove{opacity:0.6}
|
||||
#vmform .multiple:hover .sectiontab{background-color:#CCCCCC;width:8px}
|
||||
#vmform table.multiple{margin:10px 0;background:<?=$bgcolor?>;background-size:800px 100%;background-position:-800px;background-repeat:no-repeat;background-clip:content-box;transition:background 0.3s linear}
|
||||
#vmform table.multiple:hover{background-position:0 0;}
|
||||
#vmform table.multiple td{padding:5px 0}
|
||||
span.advancedview_panel{display:none;line-height:16px;margin-top:1px}
|
||||
.basic{display:none}
|
||||
.advanced{/*Empty placeholder*/}
|
||||
.switch-button-label.off{color:inherit}
|
||||
#template_img{cursor:pointer}
|
||||
#template_img:hover{opacity:0.5}
|
||||
#template_img:hover i{opacity:1.0}
|
||||
.template_img_chooser_inner{display:inline-block;width:80px;margin-bottom:15px;margin-right:10px;text-align:center;}
|
||||
.template_img_chooser_inner img{width:48px;height:48px}
|
||||
.template_img_chooser_inner p{text-align:center;line-height:8px;}
|
||||
#template_img_chooser{width:560px;height:300px;overflow-y:scroll;position:relative}
|
||||
#template_img_chooser div:hover{background-color:#eee;cursor:pointer;}
|
||||
#template_img_chooser_outer{position:absolute;display:none;border-radius:5px;border:1px solid <?=$border?>;background:<?=$bgcolor?>;z-index:10}
|
||||
#form_content{display:none}
|
||||
#vmform .four{overflow:hidden}
|
||||
#vmform .four label{float:left;display:table-cell;width:15%;}
|
||||
#vmform .four label:nth-child(4n+4){}
|
||||
#vmform .four label.cpu1{width:28%;height:16px;line-height:16px}
|
||||
#vmform .four label.cpu2{width:3%;height:16px;line-height:16px}
|
||||
#vmform .mac_generate{cursor:pointer;margin-left:-5px;color:#08C;font-size:1.3rem;transform:translate(0px, 2px)}
|
||||
#vmform .disk{display:none}
|
||||
#vmform .disk_preview{display:inline-block;color:#BBB;transform:translate(0px, 1px)}
|
||||
span#dropbox{border:1px solid <?=$border?>;background:<?=$bgcolor?>;padding:28px 12px;line-height:72px;margin-right:16px;}
|
||||
i.fa-plus-circle,i.fa-minus-circle{margin-left:8px}
|
||||
input[type=checkbox]{margin-left:0}
|
||||
</style>
|
||||
|
||||
<span class="status advancedview_panel" style="margin-top:<?=$top?>px"><input type="checkbox" class="advancedview"></span>
|
||||
<div class="domain">
|
||||
<form id="vmform" method="POST">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -281,6 +281,7 @@
|
||||
$pciboot = $config['pciboot'];
|
||||
$audios = $config['audio'];
|
||||
$template = $config['template'];
|
||||
$clocks = $config['clock'];
|
||||
|
||||
$type = $domain['type'];
|
||||
$name = $domain['name'];
|
||||
@@ -369,6 +370,7 @@
|
||||
$cpumode = '';
|
||||
$cpucache = '';
|
||||
$cpufeatures = '';
|
||||
$cpumigrate = '';
|
||||
if (!empty($domain['cpumode']) && $domain['cpumode'] == 'host-passthrough') {
|
||||
$cpumode .= "mode='host-passthrough'";
|
||||
$cpucache = "<cache mode='passthrough'/>";
|
||||
@@ -389,9 +391,11 @@
|
||||
$intCores = $vcpus / $intCPUThreadsPerCore;
|
||||
$intThreads = $intCPUThreadsPerCore;
|
||||
}
|
||||
|
||||
if (!empty($domain['cpumigrate'])) $cpumigrate = " migratable='".$domain['cpumigrate']."'" ;
|
||||
}
|
||||
|
||||
$cpustr = "<cpu $cpumode>
|
||||
$cpustr = "<cpu $cpumode $cpumigrate>
|
||||
<topology sockets='1' cores='{$intCores}' threads='{$intThreads}'/>
|
||||
$cpucache
|
||||
$cpufeatures
|
||||
@@ -439,10 +443,14 @@
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
if ($os_type == "windows") $hypervclock = "<timer name='hypervclock' present='yes'/>" ; else $hypervclock = "" ;
|
||||
|
||||
$clock = "<clock offset='" . $domain['clock'] . "'>
|
||||
<timer name='rtc' tickpolicy='catchup'/>
|
||||
<timer name='pit' tickpolicy='delay'/>
|
||||
<timer name='hpet' present='no'/>
|
||||
$hypervclock
|
||||
</clock>";
|
||||
|
||||
$hyperv = '';
|
||||
@@ -459,6 +467,42 @@
|
||||
<timer name='hpet' present='no'/>
|
||||
</clock>";
|
||||
}
|
||||
*/
|
||||
|
||||
$clock = "<clock offset='" . $domain['clock'] . "'>" ;
|
||||
foreach ($clocks as $clockname => $clockvalues) {
|
||||
switch ($clockname){
|
||||
case "rtc":
|
||||
if ($clockvalues['present'] == "yes") $clock .= "<timer name='rtc' tickpolicy='{$clockvalues['tickpolicy']}'/>";
|
||||
break ;
|
||||
case "pit":
|
||||
if ($clockvalues['present'] == "yes") $clock .= "<timer name='pit' tickpolicy='{$clockvalues['tickpolicy']}'/>";
|
||||
break ;
|
||||
case "hpet":
|
||||
$clock .= "<timer name='hpet' present='{$clockvalues['present']}'/>" ;
|
||||
break ;
|
||||
case "hypervclock":
|
||||
$clock .= "<timer name='hypervclock' present='{$clockvalues['present']}'/>" ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
$hyperv = "" ;
|
||||
if ($domain['hyperv'] == 1 && $os_type == "windows") {
|
||||
$hyperv = "<hyperv>
|
||||
<relaxed state='on'/>
|
||||
<vapic state='on'/>
|
||||
<spinlocks state='on' retries='8191'/>
|
||||
<vendor_id state='on' value='none'/>
|
||||
";
|
||||
|
||||
if ($clocks['hypervclock']['present'] == "yes")
|
||||
$hyperv .= "<vpindex state='on'/><synic state='on'/><stimer state='on'/>" ;
|
||||
$hyperv .="</hyperv>";
|
||||
#$clock = "<clock offset='" . $domain['clock'] . "'>
|
||||
# <timer name='hypervclock' present='yes'/>
|
||||
# <timer name='hpet' present='no'/>";
|
||||
}
|
||||
$clock .= "</clock>" ;
|
||||
|
||||
$usbstr = '';
|
||||
if (!empty($usb)) {
|
||||
@@ -732,6 +776,7 @@
|
||||
|
||||
$pcidevs='';
|
||||
$gpudevs_used=[];
|
||||
$multidevices = [] ; #Load?
|
||||
$vmrc='';
|
||||
$channelscopypaste = '';
|
||||
if (!empty($gpus)) {
|
||||
@@ -834,6 +879,15 @@
|
||||
$strRomFile = "<rom file='".$gpu['rom']."'/>";
|
||||
}
|
||||
|
||||
if ($gpu['multi'] == "on"){
|
||||
$newgpu_bus = dechex(hexdec($gpu_bus) + 0x20) ;
|
||||
if ($machine_type == "pc") $newgpu_slot = "0x01" ; else $newgpu_slot = "0x00" ;
|
||||
$strSpecialAddress = "<address type='pci' domain='0x0000' bus='0x$newgpu_bus' slot='$newgpu_slot' function='0x".$gpu_function."' multifunction='on' />" ;
|
||||
$multidevices[$gpu_bus] = "0x$gpu_bus" ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$pcidevs .= "<hostdev mode='subsystem' type='pci' managed='yes'".$strXVGA.">
|
||||
<driver name='vfio'/>
|
||||
<source>
|
||||
@@ -846,8 +900,8 @@
|
||||
$gpudevs_used[] = $gpu['id'];
|
||||
}
|
||||
}
|
||||
|
||||
$audiodevs_used=[];
|
||||
$strSpecialAddressAudio = "" ;
|
||||
if (!empty($audios)) {
|
||||
foreach ($audios as $i => $audio) {
|
||||
// Skip duplicate audio devices
|
||||
@@ -856,12 +910,20 @@
|
||||
}
|
||||
|
||||
[$audio_bus, $audio_slot, $audio_function] = my_explode(":", str_replace('.', ':', $audio['id']), 3);
|
||||
if ($audio_function != 0) {
|
||||
if (isset($multidevices[$audio_bus])) {
|
||||
$newaudio_bus = dechex(hexdec($audio_bus) + 0x20) ;
|
||||
if ($machine_type == "pc") $newaudio_slot = "0x01" ; else $newaudio_slot = "0x00" ;
|
||||
$strSpecialAddressAudio = "<address type='pci' domain='0x0000' bus='0x$newaudio_bus' slot='$newaudio_slot' function='0x".$audio_function."' />" ;
|
||||
}
|
||||
}
|
||||
|
||||
$pcidevs .= "<hostdev mode='subsystem' type='pci' managed='yes'>
|
||||
<driver name='vfio'/>
|
||||
<source>
|
||||
<address domain='0x0000' bus='0x".$audio_bus."' slot='0x".$audio_slot."' function='0x".$audio_function."'/>
|
||||
</source>
|
||||
$strSpecialAddressAudio
|
||||
</hostdev>";
|
||||
|
||||
$audiodevs_used[] = $audio['id'];
|
||||
@@ -869,6 +931,7 @@
|
||||
}
|
||||
|
||||
$pcidevs_used=[];
|
||||
$strSpecialAddressOther = "" ;
|
||||
if (!empty($pcis)) {
|
||||
foreach ($pcis as $i => $pci_id) {
|
||||
// Skip duplicate other pci devices
|
||||
@@ -877,12 +940,22 @@
|
||||
}
|
||||
if ($vmclone) [$pci_bus, $pci_slot, $pci_function] = my_explode(":", str_replace('.', ':', $pci_id['id']), 3);
|
||||
else [$pci_bus, $pci_slot, $pci_function] = my_explode(":", str_replace('.', ':', $pci_id), 3);
|
||||
|
||||
if ($pci_function != 0) {
|
||||
if (isset($multidevices[$pci_bus])) {
|
||||
$newpci_bus = dechex(hexdec($pci_bus) + 0x20) ;
|
||||
if ($machine_type == "pc") $newpci_slot = "0x01" ; else $newpci_slot = "0x00" ;
|
||||
$strSpecialAddressOther = "<address type='pci' domain='0x0000' bus='0x$newpci_bus' slot='$newpci_slot' function='0x".$pci_function."' />" ;
|
||||
}
|
||||
}
|
||||
|
||||
$pcidevs .= "<hostdev mode='subsystem' type='pci' managed='yes'>
|
||||
<driver name='vfio'/>
|
||||
<source>
|
||||
<address domain='0x0000' bus='0x" . $pci_bus . "' slot='0x" . $pci_slot . "' function='0x" . $pci_function . "'/>
|
||||
</source>" ;
|
||||
</source>
|
||||
$strSpecialAddressOther " ;
|
||||
|
||||
if (!empty($pciboot[$pci_id]) && !$vmclone) {
|
||||
$pcidevs .= "<boot order='".$pciboot[$pci_id]."'/>" ;
|
||||
}
|
||||
@@ -952,6 +1025,12 @@
|
||||
|
||||
}
|
||||
|
||||
function appendqemucmdline($xml,$cmdline) {
|
||||
$newxml = $xml ;
|
||||
if ($cmdline != null) $newxml = str_replace("</domain>",$cmdline."\n</domain>",$xml) ;
|
||||
return $newxml ;
|
||||
}
|
||||
|
||||
function domain_new($config) {
|
||||
|
||||
// attempt to create all disk images if needed
|
||||
@@ -975,6 +1054,8 @@
|
||||
|
||||
// generate xml for this domain
|
||||
$strXML = $this->config_to_xml($config);
|
||||
$qemucmdline = $config['qemucmdline'];
|
||||
$strXML = $this->appendqemucmdline($strXML,$qemucmdline) ;
|
||||
|
||||
|
||||
// Start the VM now if requested
|
||||
@@ -1405,7 +1486,7 @@
|
||||
}
|
||||
|
||||
//create a storage volume and add file extension
|
||||
function volume_create($name, $capacity, $allocation, $format) {
|
||||
/*function volume_create($name, $capacity, $allocation, $format) {
|
||||
$capacity = $this->parse_size($capacity);
|
||||
$allocation = $this->parse_size($allocation);
|
||||
($format != 'raw' ) ? $ext = $format : $ext = 'img';
|
||||
@@ -1422,7 +1503,7 @@
|
||||
|
||||
$tmp = libvirt_storagevolume_create_xml($pool, $xml);
|
||||
return ($tmp) ? $tmp : $this->_set_last_error();
|
||||
}
|
||||
}*/
|
||||
|
||||
function get_hypervisor_name() {
|
||||
$tmp = libvirt_connect_get_information($this->conn);
|
||||
@@ -1666,7 +1747,7 @@
|
||||
if (strpos($xml,'<qemu:commandline>')) {
|
||||
$tmp = explode("\n", $xml);
|
||||
for ($i = 0; $i < sizeof($tmp); $i++)
|
||||
if (strpos('.'.$tmp[$i], "<domain type='kvm'"))
|
||||
if (strpos('.'.$tmp[$i], "<domain type='kvm'") || strpos('.'.$tmp[$i], '<domain type="kvm"'))
|
||||
$tmp[$i] = "<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>";
|
||||
$xml = join("\n", $tmp);
|
||||
}
|
||||
@@ -2077,6 +2158,17 @@
|
||||
return $var;
|
||||
}
|
||||
|
||||
function domain_get_cpu_migrate($domain) {
|
||||
$tmp = $this->get_xpath($domain, '//domain/cpu/@migratable', false);
|
||||
if (!$tmp)
|
||||
return 'no';
|
||||
|
||||
$var = $tmp[0];
|
||||
unset($tmp);
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
function domain_get_vcpu($domain) {
|
||||
$tmp = $this->get_xpath($domain, '//domain/vcpu', false);
|
||||
$var = $tmp[0];
|
||||
@@ -2226,16 +2318,20 @@
|
||||
$objNodes = $xpath->query('//domain/devices/hostdev[@type="pci"]');
|
||||
if ($objNodes->length > 0) {
|
||||
foreach ($objNodes as $objNode) {
|
||||
$dom = $xpath->query('source/address/@domain', $objNode)->Item(0)->value;
|
||||
$bus = $xpath->query('source/address/@bus', $objNode)->Item(0)->value;
|
||||
$slot = $xpath->query('source/address/@slot', $objNode)->Item(0)->value;
|
||||
$func = $xpath->query('source/address/@function', $objNode)->Item(0)->value;
|
||||
$dom = $xpath->query('source/address/@domain', $objNode)->Item(0)->nodeValue;
|
||||
$bus = $xpath->query('source/address/@bus', $objNode)->Item(0)->nodeValue;
|
||||
$slot = $xpath->query('source/address/@slot', $objNode)->Item(0)->nodeValue;
|
||||
$func = $xpath->query('source/address/@function', $objNode)->Item(0)->nodeValue;
|
||||
$rom = $xpath->query('rom/@file', $objNode);
|
||||
$rom = ($rom->length > 0 ? $rom->Item(0)->value : '');
|
||||
$boot =$xpath->query('boot/@order', $objNode)->Item(0)->value;
|
||||
$rom = ($rom->length > 0 ? $rom->Item(0)->nodeValue : '');
|
||||
$boot =$xpath->query('boot/@order', $objNode)->Item(0)->nodeValue;
|
||||
$devid = str_replace('0x', '', 'pci_'.$dom.'_'.$bus.'_'.$slot.'_'.$func);
|
||||
$tmp2 = $this->get_node_device_information($devid);
|
||||
|
||||
$guest["multi"] = $xpath->query('address/@multifunction', $objNode)->Item(0)->nodeValue ? "on" : "off" ;
|
||||
$guest["dom"] = $xpath->query('address/@domain', $objNode)->Item(0)->nodeValue;
|
||||
$guest["bus"] = $xpath->query('address/@bus', $objNode)->Item(0)->nodeValue;
|
||||
$guest["slot"] = $xpath->query('address/@slot', $objNode)->Item(0)->nodeValue;
|
||||
$guest["func"] = $xpath->query('address/@function', $objNode)->Item(0)->nodeValue;
|
||||
$devs[] = [
|
||||
'domain' => $dom,
|
||||
'bus' => $bus,
|
||||
@@ -2247,7 +2343,8 @@
|
||||
'product' => $tmp2['product_name'],
|
||||
'product_id' => $tmp2['product_id'],
|
||||
'boot' => $boot,
|
||||
'rom' => $rom
|
||||
'rom' => $rom,
|
||||
'guest' => $guest
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -2602,7 +2699,7 @@
|
||||
}
|
||||
|
||||
//change disk capacity
|
||||
function disk_set_cap($disk, $cap) {
|
||||
/*function disk_set_cap($disk, $cap) {
|
||||
$xml = $this->domain_get_xml($domain);
|
||||
$tmp = explode("\n", $xml);
|
||||
for ($i = 0; $i < sizeof($tmp); $i++)
|
||||
@@ -2612,7 +2709,7 @@
|
||||
$xml = join("\n", $tmp);
|
||||
|
||||
return $this->domain_define($xml);
|
||||
}
|
||||
}*/
|
||||
|
||||
//change domain boot device
|
||||
function domain_set_boot_device($domain, $bootdev) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2021, Lime Technology
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
* Copyright 2015-2021, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2021, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -42,7 +42,8 @@
|
||||
* Usage:
|
||||
* $xml = Array2XML::createXML('root_node_name', $php_array);
|
||||
* echo $xml->saveXML();
|
||||
*/
|
||||
**/
|
||||
|
||||
class Array2XML {
|
||||
private static $xml = null;
|
||||
private static $encoding = 'UTF-8';
|
||||
@@ -160,8 +161,7 @@ private static $encoding = 'UTF-8';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt.php";
|
||||
require_once "$docroot/webGui/include/Custom.php";
|
||||
|
||||
@@ -650,6 +650,64 @@ private static $encoding = 'UTF-8';
|
||||
]
|
||||
];}
|
||||
|
||||
$arrDefaultClocks = [
|
||||
"windows" => [
|
||||
"hpet" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"hypervclock" => [
|
||||
"present" => "yes",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"pit" => [
|
||||
"present" => "yes",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"rtc" => [
|
||||
"present" => "yes",
|
||||
"tickpolicy" => "catchup"
|
||||
]
|
||||
],
|
||||
"hyperv" => [
|
||||
"hpet" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"hypervclock" => [
|
||||
"present" => "yes",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"pit" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"rtc" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "catchup"
|
||||
]
|
||||
] ,
|
||||
"other" => [
|
||||
"hpet" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"hypervclock" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"pit" => [
|
||||
"present" => "yes",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"rtc" => [
|
||||
"present" => "yes",
|
||||
"tickpolicy" => "catchup"
|
||||
]
|
||||
]
|
||||
] ;
|
||||
|
||||
|
||||
// Read configuration file (guaranteed to exist)
|
||||
$domain_cfgfile = "/boot/config/domain.cfg";
|
||||
$domain_cfg = parse_ini_file($domain_cfgfile);
|
||||
@@ -756,13 +814,13 @@ private static $encoding = 'UTF-8';
|
||||
$arrWhitelistGPUClassIDregex = '/^(0001|03)/';
|
||||
$arrWhitelistAudioClassIDregex = '/^(0403)/';
|
||||
|
||||
# "System peripheral [0880]" "Global unichip corp. [1ac1]" "Coral Edge Tpu [089a]" -pff "Global unichip corp. [1ac1]" "Coral Edge Tpu [089a]"
|
||||
# "System peripheral [0880]" "Global unichip corp. [1ac1]" "Coral Edge Tpu [089a]" -pff "Global unichip corp. [1ac1]" "Coral Edge Tpu [089a]"
|
||||
# typeid productid
|
||||
# file is csv typeid:productid
|
||||
#
|
||||
if (is_file("/boot/config/VMPCIOverride.cfg")) {
|
||||
$arrWhiteListOverride = str_getcsv(file_get_contents("/boot/config/VMPCIOverride.cfg")) ;
|
||||
}
|
||||
}
|
||||
$arrWhiteListOverride[] = "0880:089a" ;
|
||||
|
||||
$arrValidPCIDevices = [];
|
||||
@@ -779,7 +837,7 @@ private static $encoding = 'UTF-8';
|
||||
$boolBlacklisted = true;
|
||||
}
|
||||
|
||||
$overrideCheck = "${arrMatch['typeid']}:${arrMatch['productid']}" ;
|
||||
$overrideCheck = "{$arrMatch['typeid']}:{$arrMatch['productid']}" ;
|
||||
if (in_array($overrideCheck,$arrWhiteListOverride) ) $boolBlacklisted = false;
|
||||
|
||||
$strClass = 'other';
|
||||
@@ -1094,7 +1152,7 @@ private static $encoding = 'UTF-8';
|
||||
$arrValidNetworks['bridges'] = array_values($arrBridges);
|
||||
|
||||
// This breaks VMSettings.page if libvirt is not running
|
||||
if ($libvirt_running == "yes") {
|
||||
/* if ($libvirt_running == "yes") {
|
||||
$arrVirtual = $lv->libvirt_get_net_list($lv->get_connection());
|
||||
|
||||
if (($key = array_search('default', $arrVirtual)) !== false) {
|
||||
@@ -1104,7 +1162,7 @@ private static $encoding = 'UTF-8';
|
||||
array_unshift($arrVirtual, 'default');
|
||||
|
||||
$arrValidNetworks['libvirt'] = array_values($arrVirtual);
|
||||
}
|
||||
}*/
|
||||
|
||||
return $arrValidNetworks;
|
||||
}
|
||||
@@ -1166,25 +1224,26 @@ private static $encoding = 'UTF-8';
|
||||
'wsport' => $lv->domain_get_ws_port($res),
|
||||
'autoport' => $autoport,
|
||||
'copypaste' => $getcopypaste,
|
||||
'guest' => ['multi' => 'off' ],
|
||||
];
|
||||
}
|
||||
|
||||
foreach ($arrHostDevs as $arrHostDev) {
|
||||
$arrFoundGPUDevices = array_filter($arrValidGPUDevices, function($arrDev) use ($arrHostDev) {return ($arrDev['id'] == $arrHostDev['id']);});
|
||||
if (!empty($arrFoundGPUDevices)) {
|
||||
$arrGPUDevices[] = ['id' => $arrHostDev['id'], 'rom' => $arrHostDev['rom']];
|
||||
$arrGPUDevices[] = ['id' => $arrHostDev['id'], 'rom' => $arrHostDev['rom'], 'guest' => $arrHostDev['guest']];
|
||||
continue;
|
||||
}
|
||||
|
||||
$arrFoundAudioDevices = array_filter($arrValidAudioDevices, function($arrDev) use ($arrHostDev) {return ($arrDev['id'] == $arrHostDev['id']);});
|
||||
if (!empty($arrFoundAudioDevices)) {
|
||||
$arrAudioDevices[] = ['id' => $arrHostDev['id']];
|
||||
$arrAudioDevices[] = ['id' => $arrHostDev['id'], 'guest' => $arrHostDev['guest']];
|
||||
continue;
|
||||
}
|
||||
|
||||
$arrFoundOtherDevices = array_filter($arrValidOtherDevices, function($arrDev) use ($arrHostDev) {return ($arrDev['id'] == $arrHostDev['id']);});
|
||||
if (!empty($arrFoundOtherDevices)) {
|
||||
$arrOtherDevices[] = ['id' => $arrHostDev['id'],'boot' => $arrHostDev['boot']];
|
||||
$arrOtherDevices[] = ['id' => $arrHostDev['id'],'boot' => $arrHostDev['boot'], 'guest' => $arrHostDev['guest']];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1275,6 +1334,7 @@ private static $encoding = 'UTF-8';
|
||||
'maxmem' => $lv->domain_get_memory($res),
|
||||
'password' => '', //TODO?
|
||||
'cpumode' => $lv->domain_get_cpu_type($res),
|
||||
'cpumigrate' => $lv->domain_get_cpu_migrate($res),
|
||||
'vcpus' => $dom['nrVirtCpu'],
|
||||
'vcpu' => $lv->domain_get_vcpu_pins($res),
|
||||
'hyperv' => ($lv->domain_get_feature($res, 'hyperv') ? 1 : 0),
|
||||
@@ -1298,7 +1358,9 @@ private static $encoding = 'UTF-8';
|
||||
'pci' => $arrOtherDevices,
|
||||
'nic' => $arrNICs,
|
||||
'usb' => $arrUSBDevs,
|
||||
'shares' => $lv->domain_get_mount_filesystems($res)
|
||||
'shares' => $lv->domain_get_mount_filesystems($res),
|
||||
'qemucmdline' => getQEMUCmdLine($strDOMXML),
|
||||
'clocks' => getClocks($strDOMXML)
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1347,7 +1409,7 @@ private static $encoding = 'UTF-8';
|
||||
foreach ($old['devices']['disk'] as $k => $d) if ($source==$d['source']['@attributes']['file']) $new['devices']['disk'][$key]['driver']['@attributes'] = $d['driver']['@attributes'];
|
||||
}
|
||||
// settings not in the GUI, but maybe customized
|
||||
unset($new['clock']);
|
||||
unset($old['clock']);
|
||||
// preserve vnc/spice port settings
|
||||
// unset($new['devices']['graphics']['@attributes']['port'],$new['devices']['graphics']['@attributes']['autoport']);
|
||||
if (!$new['devices']['graphics']) unset($old['devices']['graphics']);
|
||||
@@ -1446,6 +1508,49 @@ private static $encoding = 'UTF-8';
|
||||
return json_encode($memorybacking); ;
|
||||
}
|
||||
|
||||
function getClocks($xml) {
|
||||
$clocks = new SimpleXMLElement($xml);
|
||||
$clocks = json_decode(json_encode($clocks->clock),true) ;
|
||||
$arrClocks = [
|
||||
"hpet" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"hypervclock" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"pit" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "delay"
|
||||
],
|
||||
"rtc" => [
|
||||
"present" => "no",
|
||||
"tickpolicy" => "delay"
|
||||
]
|
||||
] ;
|
||||
foreach ($clocks['timer'] as $timer) {
|
||||
$name = $timer["@attributes"]["name"] ;
|
||||
$tickpolicy = $timer["@attributes"]["tickpolicy"] ;
|
||||
$present = $timer["@attributes"]["present"] ;
|
||||
if (isset($present)) $arrClocks[$name]['present'] = $present ;
|
||||
if (isset($tickpolicy)) { $arrClocks[$name]['tickpolicy'] = $tickpolicy ; $arrClocks[$name]['present'] = 'yes' ; }
|
||||
}
|
||||
return json_encode($arrClocks) ;
|
||||
}
|
||||
|
||||
function getQEMUCmdLine($xml) {
|
||||
$x = strpos($xml,"<qemu:commandline>", 0) ;
|
||||
if ($x === false) return null ;
|
||||
$y = strpos($xml,"</qemu:commandline>", 0) ;
|
||||
$z=$y ;
|
||||
while ($y!=false) {
|
||||
$y = strpos($xml,"<qemu:commandline>", $z +19) ;
|
||||
if ($y != false) $z =$y ;
|
||||
}
|
||||
return substr($xml,$x, ($z + 19) -$x) ;
|
||||
}
|
||||
|
||||
function getchannels($res) {
|
||||
global $lv ;
|
||||
$xml = $lv->domain_get_xml($res) ;
|
||||
@@ -1497,7 +1602,7 @@ private static $encoding = 'UTF-8';
|
||||
*/
|
||||
$uuid = $lv->domain_get_uuid($clone) ;
|
||||
write("addLog\0".htmlspecialchars(_("Checking if clone exists")));
|
||||
if ($uuid) { $arrResponse = ['error' => _("Clone VM name already inuse")]; return false ;}
|
||||
if ($uuid) { $arrResponse = ['error' => _("Clone VM name already inuse")]; return false ;}
|
||||
#VM must be shutdown.
|
||||
$res = $lv->get_domain_by_name($vm);
|
||||
$dom = $lv->domain_get_info($res);
|
||||
@@ -1515,22 +1620,20 @@ private static $encoding = 'UTF-8';
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
$pathinfo = pathinfo($file) ;
|
||||
$filenew = $pathinfo["dirname"].'/'.$pathinfo["filename"].'.'.$name.'qcow2' ;
|
||||
$capacity = $capacity + $disk["capacity"] ;
|
||||
}
|
||||
$dirpath = $pathinfo["dirname"] ;
|
||||
|
||||
#Check free space.
|
||||
write("addLog\0".htmlspecialchars("Checking for free space"));
|
||||
$dirfree = disk_free_space($pathinfo["dirname"]) ;
|
||||
$sourcedir = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($pathinfo["dirname"])." 2>/dev/null"));
|
||||
$sourcedir = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($pathinfo["dirname"])." 2>/dev/null"));
|
||||
$repdir = str_replace('/mnt/user/', "/mnt/$sourcedir/", $pathinfo["dirname"]);
|
||||
$repdirfree = disk_free_space($repdir) ;
|
||||
$reflink = true ;
|
||||
$capacity *= 1 ;
|
||||
|
||||
if ($free == "yes" && $repdirfree < $capacity) { $reflink = false ;}
|
||||
if ($free == "yes" && $dirfree < $capacity) { write("addLog\0".htmlspecialchars(_("Insufficent storage for clone"))); return false ;}
|
||||
if ($free == "yes" && $dirfree < $capacity) { write("addLog\0".htmlspecialchars(_("Insufficent storage for clone"))); return false ;}
|
||||
|
||||
#Clone XML
|
||||
$uuid = $lv->domain_get_uuid($vm) ;
|
||||
@@ -1568,22 +1671,21 @@ private static $encoding = 'UTF-8';
|
||||
chgrp($clonedir, 'users');
|
||||
}
|
||||
write("addLog\0".htmlspecialchars("Checking for image files"));
|
||||
if ($file_exists && $overwrite != "yes") { write("addLog\0".htmlspecialchars(_("New image file names exist and Overwrite is not allowed"))); return( false) ; }
|
||||
if ($file_exists && $overwrite != "yes") { write("addLog\0".htmlspecialchars(_("New image file names exist and Overwrite is not allowed"))); return( false) ; }
|
||||
|
||||
#Create duplicate files.
|
||||
foreach($file_clone as $diskid => $disk) {
|
||||
$target = $disk['target'] ;
|
||||
$source = $disk['source'] ;
|
||||
if ($target == $source) { write("addLog\0".htmlspecialchars(_("New image file is same as old"))); return( false) ; }
|
||||
$sourcerealdisk = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($source)." 2>/dev/null"));
|
||||
$source = $disk['source'] ;
|
||||
if ($target == $source) { write("addLog\0".htmlspecialchars(_("New image file is same as old"))); return( false) ; }
|
||||
$sourcerealdisk = trim(shell_exec("getfattr --absolute-names --only-values -n system.LOCATION ".escapeshellarg($source)." 2>/dev/null"));
|
||||
$reptgt = str_replace('/mnt/user/', "/mnt/$sourcerealdisk/", $target);
|
||||
$repsrc = str_replace('/mnt/user/', "/mnt/$sourcerealdisk/", $source);
|
||||
#var_dump($repsrc,$reptgt) ;
|
||||
|
||||
|
||||
$cmdstr = "cp --reflink=always '$repsrc' '$reptgt'" ;
|
||||
if ($reflink == true) { $refcmd = $cmdstr ; } else {$refcmd = false; }
|
||||
$cmdstr = "rsync -ahPIXS --out-format=%f --info=flist0,misc0,stats0,name1,progress2 '$source' '$target'" ;
|
||||
$error = execCommand_nchan($cmdstr,$path,$refcmd) ;
|
||||
$error = execCommand_nchan_clone($cmdstr,$target,$refcmd) ;
|
||||
if (!$error) { write("addLog\0".htmlspecialchars("Image copied failed.")); return( false) ; }
|
||||
}
|
||||
|
||||
@@ -1594,23 +1696,23 @@ private static $encoding = 'UTF-8';
|
||||
file_put_contents("/tmp/clonexml" ,$xml) ;
|
||||
$rtn = $lv->domain_define($xml) ;
|
||||
return($rtn) ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function compare_creationtime($a, $b) {
|
||||
return strnatcmp($a['creationtime'], $b['creationtime']);
|
||||
}
|
||||
}
|
||||
|
||||
function compare_creationtimelt($a, $b) {
|
||||
return $a['creationtime'] < $b['creationtime'];
|
||||
}
|
||||
}
|
||||
|
||||
function getvmsnapshots($vm) {
|
||||
$snaps=array() ;
|
||||
$dbpath = "/etc/libvirt/qemu/snapshot/$vm" ;
|
||||
$snaps_json = file_get_contents($dbpath."/snapshots.db") ;
|
||||
$snaps = json_decode($snaps_json,true) ;
|
||||
$snaps = json_decode($snaps_json,true) ;
|
||||
if (is_array($snaps)) uasort($snaps,'compare_creationtime') ;
|
||||
return $snaps ;
|
||||
}
|
||||
@@ -1620,7 +1722,7 @@ private static $encoding = 'UTF-8';
|
||||
$dbpath = "/etc/libvirt/qemu/snapshot/$vm" ;
|
||||
if (!is_dir($dbpath)) mkdir($dbpath) ;
|
||||
$snaps_json = file_get_contents($dbpath."/snapshots.db") ;
|
||||
$snaps = json_decode($snaps_json,true) ;
|
||||
$snaps = json_decode($snaps_json,true) ;
|
||||
$snapshot_res=$lv->domain_snapshot_lookup_by_name($vm,$name) ;
|
||||
$snapshot_xml=$lv->domain_snapshot_get_xml($snapshot_res) ;
|
||||
$a = simplexml_load_string($snapshot_xml) ;
|
||||
@@ -1637,14 +1739,14 @@ private static $encoding = 'UTF-8';
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
$output = "" ;
|
||||
$output = array() ;
|
||||
exec("qemu-img info --backing-chain -U '$file' | grep image:",$output) ;
|
||||
foreach($output as $key => $line) {
|
||||
$line=str_replace("image: ","",$line) ;
|
||||
$output[$key] = $line ;
|
||||
$output[$key] = $line ;
|
||||
}
|
||||
|
||||
$snaps[$vmsnap]['backing'][$disk["device"]] = $output ;
|
||||
$snaps[$vmsnap]['backing'][$disk["device"]] = $output ;
|
||||
$rev = "r".$disk["device"] ;
|
||||
$reversed = array_reverse($output) ;
|
||||
$snaps[$vmsnap]['backing'][$rev] = $reversed ;
|
||||
@@ -1657,7 +1759,7 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
if (array_key_exists(0 , $b["disks"]["disk"])) $snaps[$vmsnap]["disks"]= $b["disks"]["disk"]; else $snaps[$vmsnap]["disks"][0]= $b["disks"]["disk"];
|
||||
|
||||
|
||||
|
||||
$value = json_encode($snaps,JSON_PRETTY_PRINT) ;
|
||||
file_put_contents($dbpath."/snapshots.db",$value) ;
|
||||
}
|
||||
@@ -1667,20 +1769,20 @@ private static $encoding = 'UTF-8';
|
||||
$dbpath = "/etc/libvirt/qemu/snapshot/$vm" ;
|
||||
if (!is_dir($dbpath)) mkdir($dbpath) ;
|
||||
$snaps_json = file_get_contents($dbpath."/snapshots.db") ;
|
||||
$snaps = json_decode($snaps_json,true) ;
|
||||
$snaps = json_decode($snaps_json,true) ;
|
||||
foreach($snaps as $vmsnap=>$snap)
|
||||
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
$output = "" ;
|
||||
$output = array() ;
|
||||
exec("qemu-img info --backing-chain -U '$file' | grep image:",$output) ;
|
||||
foreach($output as $key => $line) {
|
||||
$line=str_replace("image: ","",$line) ;
|
||||
$output[$key] = $line ;
|
||||
$output[$key] = $line ;
|
||||
}
|
||||
|
||||
$snaps[$vmsnap]['backing'][$disk["device"]] = $output ;
|
||||
|
||||
$snaps[$vmsnap]['backing'][$disk["device"]] = $output ;
|
||||
$rev = "r".$disk["device"] ;
|
||||
$reversed = array_reverse($output) ;
|
||||
$snaps[$vmsnap]['backing'][$rev] = $reversed ;
|
||||
@@ -1690,21 +1792,21 @@ private static $encoding = 'UTF-8';
|
||||
$snaps[$vmsnap]["parent"]= $parendfileinfo["extension"];
|
||||
$snaps[$vmsnap]["parent"] = str_replace("qcow2",'',$snaps[$vmsnap]["parent"]) ;
|
||||
if (isset($parentfind[1]) && !isset($parentfind[2])) $snaps[$vmsnap]["parent"]="Base" ;
|
||||
|
||||
|
||||
$value = json_encode($snaps,JSON_PRETTY_PRINT) ;
|
||||
$res = $lv->get_domain_by_name($vm);
|
||||
if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_create_snapshot($lv->domain_get_uuid($vm),$name) ;
|
||||
#if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_create_snapshot($lv->domain_get_uuid($vm),$name) ;
|
||||
|
||||
|
||||
#Remove any NVRAMs that are no longer valid.
|
||||
# Get uuid
|
||||
$vmuuid = $lv->domain_get_uuid($vm) ;
|
||||
#Get list of files
|
||||
#$filepath = "/etc/libvirt/qemu/nvram/'.$uuid*" ; #$snapshotname"
|
||||
$filepath = "/etc/libvirt/qemu/nvram/$vmuuid*" ; #$snapshotname"
|
||||
#Get list of files
|
||||
#$filepath = "/etc/libvirt/qemu/nvram/'.$uuid*" ; #$snapshotname"
|
||||
$filepath = "/etc/libvirt/qemu/nvram/$vmuuid*" ; #$snapshotname"
|
||||
$nvram_files=glob($filepath) ;
|
||||
foreach($nvram_files as $key => $nvram_file) {
|
||||
if ($nvram_file == "/etc/libvirt/qemu/nvram/$vmuuid"."_VARS-pure-efi.fd" || $nvram_file == "/etc/libvirt/qemu/nvram/$vmuuid"."_VARS-pure-efi-tpm.fd" ) unset($nvram_files[$key]) ;
|
||||
if ($nvram_file == "/etc/libvirt/qemu/nvram/$vmuuid"."_VARS-pure-efi.fd" || $nvram_file == "/etc/libvirt/qemu/nvram/$vmuuid"."_VARS-pure-efi-tpm.fd" ) unset($nvram_files[$key]) ;
|
||||
foreach ($snaps as $snapshotname => $snap) {
|
||||
$tpmfilename = "/etc/libvirt/qemu/nvram/".$vmuuid.$snapshotname."_VARS-pure-efi-tpm.fd" ;
|
||||
$nontpmfilename = "/etc/libvirt/qemu/nvram/".$vmuuid.$snapshotname."_VARS-pure-efi.fd" ;
|
||||
@@ -1714,7 +1816,7 @@ private static $encoding = 'UTF-8';
|
||||
}
|
||||
foreach ($nvram_files as $nvram_file) unlink($nvram_file) ;
|
||||
|
||||
|
||||
|
||||
file_put_contents($dbpath."/snapshots.db",$value) ;
|
||||
}
|
||||
|
||||
@@ -1722,7 +1824,7 @@ private static $encoding = 'UTF-8';
|
||||
global $lv ;
|
||||
$dbpath = "/etc/libvirt/qemu/snapshot/$vm" ;
|
||||
$snaps_json = file_get_contents($dbpath."/snapshots.db") ;
|
||||
$snaps = json_decode($snaps_json,true) ;
|
||||
$snaps = json_decode($snaps_json,true) ;
|
||||
unset($snaps[$name]) ;
|
||||
$value = json_encode($snaps,JSON_PRETTY_PRINT) ;
|
||||
file_put_contents($dbpath."/snapshots.db",$value) ;
|
||||
@@ -1732,19 +1834,19 @@ private static $encoding = 'UTF-8';
|
||||
|
||||
function vm_snapshot($vm,$snapshotname, $snapshotdesc, $free = "yes", $memorysnap = "yes") {
|
||||
global $lv ;
|
||||
|
||||
|
||||
#Get State
|
||||
$res = $lv->get_domain_by_name($vm);
|
||||
$dom = $lv->domain_get_info($res);
|
||||
$state = $lv->domain_state_translate($dom['state']);
|
||||
|
||||
#Get disks for --diskspec
|
||||
|
||||
#Get disks for --diskspec
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
$diskspec = "" ;
|
||||
$capacity = 0 ;
|
||||
if ($snapshotname == "--generate") $name= "S" . date("YmdHis") ; else $name=$snapshotname ;
|
||||
if ($snapshotdesc != "") $snapshotdesc = " --description '$snapshotdesc'" ;
|
||||
|
||||
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
$pathinfo = pathinfo($file) ;
|
||||
@@ -1756,38 +1858,38 @@ private static $encoding = 'UTF-8';
|
||||
#get memory
|
||||
$mem = $lv->domain_get_memory_stats($vm) ;
|
||||
$memory = $mem[6] ;
|
||||
|
||||
|
||||
if ($memorysnap = "yes") $memspec = ' --memspec "'.$pathinfo["dirname"].'/memory'.$name.'.mem",snapshot=external' ; else $memspec = "" ;
|
||||
$cmdstr = "virsh snapshot-create-as '$vm' --name '$name' $snapshotdesc --atomic" ;
|
||||
|
||||
|
||||
|
||||
|
||||
if ($state == "running") {
|
||||
$cmdstr .= " --live ".$memspec.$diskspec ;
|
||||
$capacity = $capacity + $memory ;
|
||||
|
||||
|
||||
} else {
|
||||
$cmdstr .= " --disk-only ".$diskspec ;
|
||||
$cmdstr .= " --disk-only ".$diskspec ;
|
||||
}
|
||||
|
||||
|
||||
#Check free space.
|
||||
$dirfree = disk_free_space($pathinfo["dirname"]) ;
|
||||
|
||||
|
||||
$capacity *= 1 ;
|
||||
|
||||
if ($free == "yes" && $dirfree < $capacity) { $arrResponse = ['error' => _("Insufficent Storage for Snapshot")]; return $arrResponse ;}
|
||||
|
||||
|
||||
if ($free == "yes" && $dirfree < $capacity) { $arrResponse = ['error' => _("Insufficent Storage for Snapshot")]; return $arrResponse ;}
|
||||
|
||||
#Copy nvram
|
||||
if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_create_snapshot($lv->domain_get_uuid($vm),$name) ;
|
||||
|
||||
$xmlfile = $pathinfo["dirname"]."/".$name.".running" ;
|
||||
file_put_contents("/tmp/xmltst", "$xmlfile" ) ;
|
||||
if ($state == "running") exec("virsh dumpxml '$vm' > ".escapeshellarg($xmlfile),$outxml,$rtnxml) ;
|
||||
|
||||
|
||||
$output= [] ;
|
||||
$test = false ;
|
||||
if ($test) exec($cmdstr." --print-xml 2>&1",$output,$return) ; else exec($cmdstr." 2>&1",$output,$return) ;
|
||||
|
||||
if (strpos(" ".$output[0],"error") ) {
|
||||
if (strpos(" ".$output[0],"error") ) {
|
||||
$arrResponse = ['error' => substr($output[0],6) ] ;
|
||||
} else {
|
||||
$arrResponse = ['success' => true] ;
|
||||
@@ -1805,8 +1907,8 @@ private static $encoding = 'UTF-8';
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
|
||||
switch ($snapslist[$snap]['state']) {
|
||||
case "shutoff":
|
||||
case "running":
|
||||
case "shutoff":
|
||||
case "running":
|
||||
#VM must be shutdown.
|
||||
$res = $lv->get_domain_by_name($vm);
|
||||
$dom = $lv->domain_get_info($res);
|
||||
@@ -1819,7 +1921,7 @@ private static $encoding = 'UTF-8';
|
||||
$xmlobj = custom::createArray('domain',$strXML) ;
|
||||
|
||||
# Process disks and update path.
|
||||
$disks=($snapslist[$snap]['disks']) ;
|
||||
$disks=($snapslist[$snap]['disks']) ;
|
||||
foreach ($disks as $disk) {
|
||||
$diskname = $disk["@attributes"]["name"] ;
|
||||
if ($diskname == "hda" || $diskname == "hdb") continue ;
|
||||
@@ -1861,7 +1963,7 @@ private static $encoding = 'UTF-8';
|
||||
$item++ ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uasort($snapslist,'compare_creationtimelt') ;
|
||||
foreach($snapslist as $s) {
|
||||
$name = $s['name'] ;
|
||||
@@ -1879,13 +1981,13 @@ private static $encoding = 'UTF-8';
|
||||
# Restore Memory.
|
||||
|
||||
$makerun = true ;
|
||||
if ($makerun == true) exec("virsh restore ".escapeshellarg($memoryfile)) ;
|
||||
#exec("virsh restore $memoryfile") ;
|
||||
}
|
||||
if ($makerun == true) exec("virsh restore ".escapeshellarg($memoryfile)) ;
|
||||
#exec("virsh restore $memoryfile") ;
|
||||
}
|
||||
#Delete Metadata only.
|
||||
if ($actionmeta == "yes") {
|
||||
if ($actionmeta == "yes") {
|
||||
$ret = delete_snapshots_database("$vm","$name") ;
|
||||
}
|
||||
}
|
||||
if (is_file($memoryfile) && $action == "yes") unlink($memoryfile) ;
|
||||
if (is_file($xmlfile) && $action == "yes") unlink($xmlfile) ;
|
||||
if ($s['name'] == $snap) break ;
|
||||
@@ -1893,11 +1995,11 @@ private static $encoding = 'UTF-8';
|
||||
#if VM was started restart.
|
||||
if ($state == 'running' && $snapslist[$snap]['state'] != "running") {
|
||||
$arrResponse = $lv->domain_start($vm) ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_revert_snapshot($lv->domain_get_uuid($vm),$name) ;
|
||||
break ;
|
||||
|
||||
|
||||
}
|
||||
$arrResponse = ['success' => true] ;
|
||||
return($arrResponse) ;
|
||||
@@ -1907,28 +2009,29 @@ private static $encoding = 'UTF-8';
|
||||
global $lv ;
|
||||
$snapslist= getvmsnapshots($vm) ;
|
||||
$data = "<br><br>Images and metadata to remove if tickbox checked.<br>" ;
|
||||
|
||||
$capacity = 0 ;
|
||||
$diskspec = "" ;
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
$output = "" ;
|
||||
$output = array() ;
|
||||
exec("qemu-img info --backing-chain -U '$file' | grep image:",$output) ;
|
||||
foreach($output as $key => $line) {
|
||||
$line=str_replace("image: ","",$line) ;
|
||||
$output[$key] = $line ;
|
||||
$output[$key] = $line ;
|
||||
}
|
||||
$snaps[$vm][$disk["device"]] = $output ;
|
||||
$snaps[$vm][$disk["device"]] = $output ;
|
||||
$rev = "r".$disk["device"] ;
|
||||
$reversed = array_reverse($output) ;
|
||||
$snaps[$vm][$rev] = $reversed ;
|
||||
$pathinfo = pathinfo($file) ;
|
||||
$filenew = $pathinfo["dirname"].'/'.$pathinfo["filename"].'.'.$name.'qcow2' ;
|
||||
$diskspec .= " --diskspec ".$disk["device"].",snapshot=external,file=".$filenew ;
|
||||
#$filenew = $pathinfo["dirname"].'/'.$pathinfo["filename"].'.'.$name.'qcow2' ;
|
||||
#$diskspec .= " --diskspec ".$disk["device"].",snapshot=external,file=".$filenew ;
|
||||
$capacity = $capacity + $disk["capacity"] ;
|
||||
}
|
||||
|
||||
$snapdisks= $snapslist[$snap]['disks'] ;
|
||||
|
||||
|
||||
foreach ($snapdisks as $diskkey => $snapdisk) {
|
||||
$diskname = $snapdisk["@attributes"]["name"] ;
|
||||
if ($diskname == "hda" || $diskname == "hdb") continue ;
|
||||
@@ -1941,7 +2044,7 @@ private static $encoding = 'UTF-8';
|
||||
{
|
||||
if (!isset($snaps[$vm]["r".$diskname][$item])) break ;
|
||||
$newpath = $snaps[$vm]["r".$diskname][$item] ;
|
||||
if (is_file($path)) $data .= "$newpath<br>" ;
|
||||
if (is_file($path)) $data .= "$newpath<br>" ;
|
||||
$item++ ;
|
||||
|
||||
}
|
||||
@@ -1959,7 +2062,7 @@ private static $encoding = 'UTF-8';
|
||||
}
|
||||
return($data) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function vm_snapremove($vm, $snap) {
|
||||
global $lv ;
|
||||
@@ -1970,14 +2073,14 @@ private static $encoding = 'UTF-8';
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
$output = "" ;
|
||||
$output = array() ;
|
||||
exec("qemu-img info --backing-chain -U $file | grep image:",$output) ;
|
||||
foreach($output as $key => $line) {
|
||||
$line=str_replace("image: ","",$line) ;
|
||||
$output[$key] = $line ;
|
||||
$output[$key] = $line ;
|
||||
}
|
||||
|
||||
$snaps[$vm][$disk["device"]] = $output ;
|
||||
$snaps[$vm][$disk["device"]] = $output ;
|
||||
$rev = "r".$disk["device"] ;
|
||||
$reversed = array_reverse($output) ;
|
||||
$snaps[$vm][$rev] = $reversed ;
|
||||
@@ -1989,7 +2092,7 @@ private static $encoding = 'UTF-8';
|
||||
$xmlobj = custom::createArray('domain',$strXML) ;
|
||||
|
||||
# Process disks.
|
||||
$disks=($snapslist[$snap]['disks']) ;
|
||||
$disks=($snapslist[$snap]['disks']) ;
|
||||
foreach ($disks as $disk) {
|
||||
$diskname = $disk["@attributes"]["name"] ;
|
||||
if ($diskname == "hda" || $diskname == "hdb") continue ;
|
||||
@@ -2000,30 +2103,30 @@ private static $encoding = 'UTF-8';
|
||||
return ($data) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$disks=($snapslist[$snap]['disks']) ;
|
||||
foreach ($disks as $disk) {
|
||||
$diskname = $disk["@attributes"]["name"] ;
|
||||
if ($diskname == "hda" || $diskname == "hdb") continue ;
|
||||
$path = $disk["source"]["@attributes"]["file"] ;
|
||||
if (is_file($path)) {
|
||||
if(!unlink("$path")) {
|
||||
if(!unlink("$path")) {
|
||||
$data = ["error" => "Unable to remove image file $path"] ;
|
||||
return ($data) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Delete NVRAM
|
||||
# Delete NVRAM
|
||||
if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_delete_snapshot($lv->domain_get_uuid($vm),$snap) ;
|
||||
|
||||
$ret = delete_snapshots_database("$vm","$snap") ;
|
||||
|
||||
|
||||
if(!$ret)
|
||||
$data = ["error" => "Unable to remove snap metadata $snap"] ;
|
||||
else
|
||||
$data = ["success => 'true"] ;
|
||||
|
||||
|
||||
return($data) ;
|
||||
}
|
||||
|
||||
@@ -2060,7 +2163,7 @@ OPTIONS
|
||||
blockcommit Debian --path /mnt/user/domains/Debian/vdisk1.S20230513120410qcow2 --verbose --pivot --delete
|
||||
*/
|
||||
# Error if VM Not running.
|
||||
|
||||
|
||||
$snapslist= getvmsnapshots($vm) ;
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
|
||||
@@ -2070,7 +2173,7 @@ OPTIONS
|
||||
if ($pivot == "yes") $cmdstr .= " --pivot " ;
|
||||
if ($action == "yes") $cmdstr .= " --delete " ;
|
||||
# Process disks and update path.
|
||||
$snapdisks=($snapslist[$snap]['disks']) ;
|
||||
$snapdisks=($snapslist[$snap]['disks']) ;
|
||||
if ($base != "--base" && $base != "") {
|
||||
#get file name from snapshot.
|
||||
$snapdisks=($snapslist[$base]['disks']) ;
|
||||
@@ -2095,15 +2198,15 @@ OPTIONS
|
||||
}
|
||||
|
||||
$error = execCommand_nchan($cmdstr,$path) ;
|
||||
if (!$error) {
|
||||
$arrResponse = ['error' => substr($output[0],6) ] ;
|
||||
if (!$error) {
|
||||
$arrResponse = ['error' => "Process Failed"] ;
|
||||
return($arrResponse) ;
|
||||
} else {
|
||||
$arrResponse = ['success' => true] ;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
# Delete NVRAM
|
||||
# Delete NVRAM
|
||||
#if (!empty($lv->domain_get_ovmf($res))) $nvram = $lv->nvram_delete_snapshot($lv->domain_get_uuid($vm),$snap) ;
|
||||
|
||||
refresh_snapshots_database($vm) ;
|
||||
@@ -2146,13 +2249,13 @@ OPTIONS
|
||||
$disks =$lv->get_disk_stats($vm) ;
|
||||
foreach($disks as $disk) {
|
||||
$file = $disk["file"] ;
|
||||
$output = "" ;
|
||||
$output = array() ;
|
||||
exec("qemu-img info --backing-chain -U '$file' | grep image:",$output) ;
|
||||
foreach($output as $key => $line) {
|
||||
$line=str_replace("image: ","",$line) ;
|
||||
$output[$key] = $line ;
|
||||
$output[$key] = $line ;
|
||||
}
|
||||
$snaps[$vm][$disk["device"]] = $output ;
|
||||
$snaps[$vm][$disk["device"]] = $output ;
|
||||
$rev = "r".$disk["device"] ;
|
||||
$reversed = array_reverse($output) ;
|
||||
$snaps[$vm][$rev] = $reversed ;
|
||||
@@ -2167,7 +2270,7 @@ OPTIONS
|
||||
$cmdstr = "virsh blockpull '$vm' --path '$path' --verbose --pivot --delete" ;
|
||||
$cmdstr = "virsh blockpull '$vm' --path '$path' --verbose --wait " ;
|
||||
# Process disks and update path.
|
||||
$snapdisks=($snapslist[$snap]['disks']) ;
|
||||
$snapdisks=($snapslist[$snap]['disks']) ;
|
||||
if ($base != "--base" && $base != "") {
|
||||
#get file name from snapshot.
|
||||
$snapdisks=($snapslist[$base]['disks']) ;
|
||||
@@ -2184,9 +2287,9 @@ OPTIONS
|
||||
|
||||
|
||||
$error = execCommand_nchan($cmdstr,$path) ;
|
||||
|
||||
if (!$error) {
|
||||
$arrResponse = ['error' => substr($output[0],6) ] ;
|
||||
|
||||
if (!$error) {
|
||||
$arrResponse = ['error' => "Process Failed" ] ;
|
||||
return($arrResponse) ;
|
||||
} else {
|
||||
# Remove nvram snapshot
|
||||
@@ -2196,6 +2299,7 @@ OPTIONS
|
||||
}
|
||||
|
||||
refresh_snapshots_database($vm) ;
|
||||
$ret = $ret = delete_snapshots_database("$vm","$snap") ;
|
||||
if($ret)
|
||||
$data = ["error" => "Unable to remove snap metadata $snap"] ;
|
||||
else
|
||||
@@ -2241,6 +2345,6 @@ OPTIONS
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -69,14 +69,14 @@ function addVMContext(name, uuid, template, state, vmrcurl, vmrcprotocol, log, c
|
||||
if (x!=-1) path = path.substring(0,x);
|
||||
if (vmrcurl !== "" && state == "running") {
|
||||
if (console == "web" || console == "both") {
|
||||
var vmrctext=_("VM Console") + "(" + vmrcprotocol + ")" ;
|
||||
var vmrctext=_("VM Console") + " (" + vmrcprotocol + ")" ;
|
||||
opts.push({text:vmrctext, icon:"fa-desktop", action:function(e) {
|
||||
e.preventDefault();
|
||||
window.open(vmrcurl, '_blank', 'scrollbars=yes,resizable=yes');
|
||||
}});
|
||||
}
|
||||
if (console == "remote" || console == "both") {
|
||||
opts.push({text:_("VM remote-viewer")+ "(" + vmrcprotocol + ")" , icon:"fa-desktop", action:function(e) {
|
||||
opts.push({text:_("VM remote-viewer")+ " (" + vmrcprotocol + ")" , icon:"fa-desktop", action:function(e) {
|
||||
e.preventDefault();
|
||||
ajaxVMDispatchconsoleRV({action:"domain-consoleRV", uuid:uuid, vmrcurl:vmrcurl}, "loadlist") ;
|
||||
}});
|
||||
@@ -137,12 +137,12 @@ function addVMContext(name, uuid, template, state, vmrcurl, vmrcprotocol, log, c
|
||||
}});
|
||||
if (vmrcprotocol == "VNC" || vmrcprotocol == "SPICE") {
|
||||
if (console == "web" || console == "both") {
|
||||
opts.push({text:_("Start with console")+ "(" + vmrcprotocol + ")" , icon:"fa-play", action:function(e) {
|
||||
opts.push({text:_("Start with console")+ " (" + vmrcprotocol + ")" , icon:"fa-play", action:function(e) {
|
||||
e.preventDefault();
|
||||
ajaxVMDispatchconsole({action:"domain-start-console", uuid:uuid, vmrcurl:vmrcurl}, "loadlist") ;
|
||||
}});}
|
||||
if (console == "remote" || console == "both") {
|
||||
opts.push({text:_("Start with remote-viewer")+ "(" + vmrcprotocol + ")" , icon:"fa-play", action:function(e) {
|
||||
opts.push({text:_("Start with remote-viewer")+ " (" + vmrcprotocol + ")" , icon:"fa-play", action:function(e) {
|
||||
e.preventDefault();
|
||||
ajaxVMDispatchconsoleRV({action:"domain-start-consoleRV", uuid:uuid, vmrcurl:vmrcurl}, "loadlist") ;
|
||||
}});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/php -q
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -11,47 +12,47 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = '';
|
||||
$login_locale = _var($display,'locale');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
function write(...$messages){
|
||||
$com = curl_init();
|
||||
curl_setopt_array($com,[
|
||||
CURLOPT_URL => 'http://localhost/pub/vmaction?buffer_length=1',
|
||||
CURLOPT_UNIX_SOCKET_PATH => '/var/run/nginx.socket',
|
||||
CURLOPT_POST => 1,
|
||||
CURLOPT_RETURNTRANSFER => true
|
||||
]);
|
||||
foreach ($messages as $message) {
|
||||
curl_setopt($com, CURLOPT_POSTFIELDS, $message);
|
||||
curl_exec($com);
|
||||
}
|
||||
curl_close($com);
|
||||
$com = curl_init();
|
||||
curl_setopt_array($com,[
|
||||
CURLOPT_URL => 'http://localhost/pub/vmaction?buffer_length=1',
|
||||
CURLOPT_UNIX_SOCKET_PATH => '/var/run/nginx.socket',
|
||||
CURLOPT_POST => 1,
|
||||
CURLOPT_RETURNTRANSFER => true
|
||||
]);
|
||||
foreach ($messages as $message) {
|
||||
curl_setopt($com, CURLOPT_POSTFIELDS, $message);
|
||||
curl_exec($com);
|
||||
}
|
||||
curl_close($com);
|
||||
}
|
||||
function execCommand_nchan($command,$idx) {
|
||||
$waitID = mt_rand();
|
||||
[$cmd,$args] = explode(' ',$command,2);
|
||||
write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._('Command execution')."</legend>".basename($cmd).' '.str_replace(" -","<br> -",htmlspecialchars($args))."<br><span id='wait-$waitID'>"._('Please wait')." </span><p class='logLine'></p></fieldset>","show_Wait\0$waitID");
|
||||
write("addLog\0<br>") ;
|
||||
write("addToID\0$idx\0 $action") ;
|
||||
$proc = popen("$command 2>&1",'r');
|
||||
while ($out = fgets($proc)) {
|
||||
$out = preg_replace("%[\t\n\x0B\f\r]+%", '',$out);
|
||||
if (substr($out,0,1) == "B") { ;
|
||||
write("progress\0$idx\0".htmlspecialchars(substr($out,strrpos($out,"Block Pull")))) ;
|
||||
} else echo write("addToID\0$idx\0 ".htmlspecialchars($out));
|
||||
}
|
||||
$retval = pclose($proc);
|
||||
$out = $retval ? _('The command failed').'.' : _('The command finished successfully').'!';
|
||||
write("stop_Wait\0$waitID","addLog\0<br><b>$out</b>");
|
||||
return $retval===0;
|
||||
$waitID = mt_rand();
|
||||
[$cmd,$args] = explode(' ',$command,2);
|
||||
write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._('Command execution')."</legend>".basename($cmd).' '.str_replace(" -","<br> -",htmlspecialchars($args))."<br><span id='wait-$waitID'>"._('Please wait')." </span><p class='logLine'></p></fieldset>","show_Wait\0$waitID");
|
||||
write("addLog\0<br>") ;
|
||||
#write("addToID\0$idx\0 $action") ;
|
||||
$proc = popen("$command 2>&1",'r');
|
||||
while ($out = fgets($proc)) {
|
||||
$out = preg_replace("%[\t\n\x0B\f\r]+%", '',$out);
|
||||
if (substr($out,0,1) == "B") { ;
|
||||
write("progress\0$idx\0".htmlspecialchars(substr($out,strrpos($out,"Block Pull")))) ;
|
||||
} else echo write("addToID\0$idx\0 ".htmlspecialchars($out));
|
||||
}
|
||||
$retval = pclose($proc);
|
||||
$out = $retval ? _('The command failed').'.' : _('The command finished successfully').'!';
|
||||
write("stop_Wait\0$waitID","addLog\0<br><b>$out</b>");
|
||||
return $retval===0;
|
||||
}
|
||||
|
||||
#{action:"snap-", uuid:uuid , snapshotname:target , remove:remove, free:free ,removemeta:removemeta ,keep:keep, desc:desc}
|
||||
@@ -65,10 +66,10 @@ $style[] = "legend{font-size:1.1rem!important;font-weight:bold}";
|
||||
$style[] = "</style>";
|
||||
|
||||
foreach (explode('&', $url) as $chunk) {
|
||||
$param = explode("=", $chunk);
|
||||
if ($param) {
|
||||
${urldecode($param[0])} = urldecode($param[1]) ;
|
||||
}
|
||||
$param = explode("=", $chunk);
|
||||
if ($param) {
|
||||
${urldecode($param[0])} = urldecode($param[1]) ;
|
||||
}
|
||||
}
|
||||
$id = 1 ;
|
||||
write(implode($style)."<p class='logLine'></p>");
|
||||
@@ -78,25 +79,23 @@ write("addLog\0".htmlspecialchars("VMName $name "));
|
||||
write("addLog\0".htmlspecialchars("SNAP $snapshotname "));
|
||||
write("addLog\0".htmlspecialchars("Base $targetbase "));
|
||||
if ($action == "commit") {
|
||||
write("addLog\0".htmlspecialchars("Top $targettop "));
|
||||
write("addLog\0".htmlspecialchars("Pivot $targetpivot "));
|
||||
write("addLog\0".htmlspecialchars("Delete $targetdelete "));
|
||||
write("addLog\0".htmlspecialchars("Top $targettop "));
|
||||
write("addLog\0".htmlspecialchars("Pivot $targetpivot "));
|
||||
write("addLog\0".htmlspecialchars("Delete $targetdelete "));
|
||||
}
|
||||
|
||||
switch ($action) {
|
||||
case "commit":
|
||||
vm_blockcommit($name,$snapshotname,$path,$targetbase,$targettop,$targetpivot,$targetdelete) ;
|
||||
break ;
|
||||
case "copy":
|
||||
vm_blockcopy($name,$snapshotname,$path,$targetbase,$targettop,$pivot,' ') ;
|
||||
break;
|
||||
case "pull":
|
||||
vm_blockpull($name,$snapshotname,$path,$targetbase,$targettop,$pivot,' ') ;
|
||||
break ;
|
||||
|
||||
}
|
||||
case "commit":
|
||||
vm_blockcommit($name,$snapshotname,$path,$targetbase,$targettop,$targetpivot,$targetdelete) ;
|
||||
break ;
|
||||
case "copy":
|
||||
vm_blockcopy($name,$snapshotname,$path,$targetbase,$targettop,$pivot,' ') ;
|
||||
break;
|
||||
case "pull":
|
||||
vm_blockpull($name,$snapshotname,$path,$targetbase,$targettop,$pivot,' ') ;
|
||||
break ;
|
||||
}
|
||||
#execCommand_nchan("ls /") ;
|
||||
write("stop_Wait\0$waitID") ;
|
||||
write('_DONE_','');
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/php -q
|
||||
<?PHP
|
||||
/* Copyright 2005-2023, Lime Technology
|
||||
* Copyright 2012-2023, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -11,67 +12,65 @@
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
|
||||
require_once "$docroot/webGui/include/Wrappers.php";
|
||||
$docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp');
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
// add translations
|
||||
$_SERVER['REQUEST_URI'] = '';
|
||||
$login_locale = _var($display,'locale');
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
require_once "$docroot/webGui/include/Translations.php";
|
||||
require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
function write(...$messages){
|
||||
$com = curl_init();
|
||||
curl_setopt_array($com,[
|
||||
CURLOPT_URL => 'http://localhost/pub/vmaction?buffer_length=1',
|
||||
CURLOPT_UNIX_SOCKET_PATH => '/var/run/nginx.socket',
|
||||
CURLOPT_POST => 1,
|
||||
CURLOPT_RETURNTRANSFER => true
|
||||
]);
|
||||
foreach ($messages as $message) {
|
||||
curl_setopt($com, CURLOPT_POSTFIELDS, $message);
|
||||
curl_exec($com);
|
||||
}
|
||||
curl_close($com);
|
||||
}
|
||||
function execCommand_nchan($command,$idx,$refcmd=false) {
|
||||
$waitID = mt_rand();
|
||||
if ($refcmd) {
|
||||
[$cmd,$args] = explode(' ',$refcmd,2);
|
||||
write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._('Command execution')."</legend>".basename($cmd).' '.str_replace(" -","<br> -",htmlspecialchars($args))."<br><span id='wait-$waitID'>"._('Please wait')." </span><p class='logLine'></p></fieldset>","show_Wait\0$waitID");
|
||||
$rtn = exec("$refcmd 2>&1", $output,$return) ;
|
||||
if ($return == 0) $reflinkok = true ; else {
|
||||
$reflinkok = false ;
|
||||
write("addLog\0<br><b>{$output[0]}</b>");
|
||||
}
|
||||
$out = $return ? _('The command failed revert to rsync')."." : _('The command finished successfully').'!';
|
||||
write("stop_Wait\0$waitID","addLog\0<br><b>$out</b>");
|
||||
}
|
||||
|
||||
if ($reflinkok) {
|
||||
return true ;
|
||||
} else {
|
||||
$waitID = mt_rand();
|
||||
[$cmd,$args] = explode(' ',$command,2);
|
||||
write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._('Command execution')."</legend>".basename($cmd).' '.str_replace(" -","<br> -",htmlspecialchars($args))."<br><span id='wait-$waitID'>"._('Please wait')." </span><p class='logLine'></p></fieldset>","show_Wait\0$waitID");
|
||||
|
||||
write("addToID\0$idx\0Cloning VM: ") ;
|
||||
$proc = popen("$command 2>&1 &",'r');
|
||||
while ($out = fread($proc,100)) {
|
||||
$out = preg_replace("%[\t\n\x0B\f\r]+%", '',$out);
|
||||
$out = trim($out) ;
|
||||
$values = explode(' ',$out) ;
|
||||
$string = _("Data copied: ").$values[0].' '._(" Percentage: ").$values[1].' '._(" Transfer Rate: ").$values[2].' '._(" Time remaining: ").$values[4].$values[5] ;
|
||||
write("progress\0$idx\0".htmlspecialchars($string)) ;
|
||||
if ($out) $stringsave=$string ;
|
||||
}
|
||||
$retval = pclose($proc);
|
||||
write("progress\0$idx\0".htmlspecialchars($stringsave)) ;
|
||||
$out = $retval ? _('The command failed').'.' : _('The command finished successfully').'!';
|
||||
write("stop_Wait\0$waitID","addLog\0<br><b>$out</b>");
|
||||
return $retval===0;
|
||||
function write(...$messages) {
|
||||
$com = curl_init();
|
||||
curl_setopt_array($com,[
|
||||
CURLOPT_URL => 'http://localhost/pub/vmaction?buffer_length=1',
|
||||
CURLOPT_UNIX_SOCKET_PATH => '/var/run/nginx.socket',
|
||||
CURLOPT_POST => 1,
|
||||
CURLOPT_RETURNTRANSFER => true
|
||||
]);
|
||||
foreach ($messages as $message) {
|
||||
curl_setopt($com, CURLOPT_POSTFIELDS, $message);
|
||||
curl_exec($com);
|
||||
}
|
||||
curl_close($com);
|
||||
}
|
||||
|
||||
function execCommand_nchan_clone($command,$idx,$refcmd=false) {
|
||||
$waitID = mt_rand();
|
||||
if ($refcmd) {
|
||||
[$cmd,$args] = explode(' ',$refcmd,2);
|
||||
write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._('Command execution')."</legend>".basename($cmd).' '.str_replace(" -","<br> -",htmlspecialchars($args))."<br><span id='wait-$waitID'>"._('Please wait')." </span><p class='logLine'></p></fieldset>","show_Wait\0$waitID");
|
||||
$rtn = exec("$refcmd 2>&1", $output,$return) ;
|
||||
if ($return == 0) $reflinkok = true ; else {
|
||||
$reflinkok = false ;
|
||||
write("addLog\0<br><b>{$output[0]}</b>");
|
||||
}
|
||||
$out = $return ? _('The command failed revert to rsync')."." : _('The command finished successfully').'!';
|
||||
write("stop_Wait\0$waitID","addLog\0<br><b>$out</b>");
|
||||
}
|
||||
if ($reflinkok) {
|
||||
return true ;
|
||||
} else {
|
||||
$waitID = mt_rand();
|
||||
[$cmd,$args] = explode(' ',$command,2);
|
||||
write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._('Command execution')."</legend>".basename($cmd).' '.str_replace(" -","<br> -",htmlspecialchars($args))."<br><span id='wait-$waitID'>"._('Please wait')." </span><p class='logLine'></p></fieldset>","show_Wait\0$waitID");
|
||||
write("addToID\0$idx\0Cloning VM: ") ;
|
||||
$proc = popen("$command 2>&1 &",'r');
|
||||
while ($out = fread($proc,100)) {
|
||||
$out = preg_replace("%[\t\n\x0B\f\r]+%", '',$out);
|
||||
$out = trim($out);
|
||||
$values = explode(' ',$out);
|
||||
$string = _("Data copied: ").$values[0].' '._(" Percentage: ").$values[1].' '._(" Transfer Rate: ").$values[2].' '._(" Time remaining: ").$values[4].$values[5];
|
||||
write("progress\0$idx\0".htmlspecialchars($string));
|
||||
if ($out) $stringsave=$string;
|
||||
}
|
||||
$retval = pclose($proc);
|
||||
write("progress\0$idx\0".htmlspecialchars($stringsave));
|
||||
$out = $retval ? _('The command failed').'.' : _('The command finished successfully').'!';
|
||||
write("stop_Wait\0$waitID","addLog\0<br><b>$out</b>");
|
||||
return $retval===0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +85,10 @@ $style[] = "legend{font-size:1.1rem!important;font-weight:bold}";
|
||||
$style[] = "</style>";
|
||||
|
||||
foreach (explode('&', $url) as $chunk) {
|
||||
$param = explode("=", $chunk);
|
||||
if ($param) {
|
||||
${urldecode($param[0])} = urldecode($param[1]) ;
|
||||
}
|
||||
$param = explode("=", $chunk);
|
||||
if ($param) {
|
||||
${urldecode($param[0])} = urldecode($param[1]) ;
|
||||
}
|
||||
}
|
||||
$id = 1 ;
|
||||
write(implode($style)."<p class='logLine'></p>");
|
||||
@@ -99,10 +98,10 @@ write("<p class='logLine'></p>","addLog\0<fieldset class='docker'><legend>"._("O
|
||||
write("addLog\0".htmlspecialchars("Cloning $name to $clone"));
|
||||
|
||||
switch ($action) {
|
||||
case "clone":
|
||||
$rtn = vm_clone($name,$clone,$overwrite,$start,$edit,$free,$waitID) ;
|
||||
break ;
|
||||
}
|
||||
case "clone":
|
||||
$rtn = vm_clone($name,$clone,$overwrite,$start,$edit,$free,$waitID) ;
|
||||
break ;
|
||||
}
|
||||
write("stop_Wait\0$waitID") ;
|
||||
if ($rtn) write('_DONE_',''); else write('_ERROR_','');
|
||||
?>
|
||||
?>
|
||||
|
||||
4
emhttp/plugins/dynamix.vm.manager/sheets/AddVM-azure.css
Normal file
4
emhttp/plugins/dynamix.vm.manager/sheets/AddVM-azure.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.fileTree{background:#f2f2f2;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:relative;z-index:100;display:none}
|
||||
#vmform table.multiple{margin:10px 0;background:#f2f2f2;background-size:800px 100%;background-position:-800px;background-repeat:no-repeat;background-clip:content-box;transition:background 0.3s linear}
|
||||
#template_img_chooser_outer{position:absolute;display:none;border-radius:5px;border:1px solid <?=$border?>;background:#f2f2f2;z-index:10}
|
||||
span#dropbox{border:1px solid <?=$border?>;background:#f2f2f2;padding:28px 12px;line-height:72px;margin-right:16px;}
|
||||
4
emhttp/plugins/dynamix.vm.manager/sheets/AddVM-black.css
Normal file
4
emhttp/plugins/dynamix.vm.manager/sheets/AddVM-black.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.fileTree{background:#1c1c1c;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:relative;z-index:100;display:none}
|
||||
#vmform table.multiple{margin:10px 0;background:#1c1c1c;background-size:800px 100%;background-position:-800px;background-repeat:no-repeat;background-clip:content-box;transition:background 0.3s linear}
|
||||
#template_img_chooser_outer{position:absolute;display:none;border-radius:5px;border:1px solid <?=$border?>;background:#1c1c1c;z-index:10}
|
||||
span#dropbox{border:1px solid <?=$border?>;background:#1c1c1c;padding:28px 12px;line-height:72px;margin-right:16px;}
|
||||
4
emhttp/plugins/dynamix.vm.manager/sheets/AddVM-gray.css
Normal file
4
emhttp/plugins/dynamix.vm.manager/sheets/AddVM-gray.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.fileTree{background:#1c1c1c;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:relative;z-index:100;display:none}
|
||||
#vmform table.multiple{margin:10px 0;background:#1c1c1c;background-size:800px 100%;background-position:-800px;background-repeat:no-repeat;background-clip:content-box;transition:background 0.3s linear}
|
||||
#template_img_chooser_outer{position:absolute;display:none;border-radius:5px;border:1px solid <?=$border?>;background:#1c1c1c;z-index:10}
|
||||
span#dropbox{border:1px solid <?=$border?>;background:#1c1c1c;padding:28px 12px;line-height:72px;margin-right:16px;}
|
||||
4
emhttp/plugins/dynamix.vm.manager/sheets/AddVM-white.css
Normal file
4
emhttp/plugins/dynamix.vm.manager/sheets/AddVM-white.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.fileTree{background:#f2f2f2;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:relative;z-index:100;display:none}
|
||||
#vmform table.multiple{margin:10px 0;background:#f2f2f2;background-size:800px 100%;background-position:-800px;background-repeat:no-repeat;background-clip:content-box;transition:background 0.3s linear}
|
||||
#template_img_chooser_outer{position:absolute;display:none;border-radius:5px;border:1px solid <?=$border?>;background:#f2f2f2;z-index:10}
|
||||
span#dropbox{border:1px solid <?=$border?>;background:#f2f2f2;padding:28px 12px;line-height:72px;margin-right:16px;}
|
||||
43
emhttp/plugins/dynamix.vm.manager/sheets/AddVM.css
Normal file
43
emhttp/plugins/dynamix.vm.manager/sheets/AddVM.css
Normal file
@@ -0,0 +1,43 @@
|
||||
body{-webkit-overflow-scrolling:touch}
|
||||
#vmform table{margin-top:0}
|
||||
#vmform div.title + table{margin-top:0}
|
||||
#vmform table tr{vertical-align:top;line-height:40px}
|
||||
#vmform table tr td:nth-child(odd){width:300px;text-align:right;padding-right:10px}
|
||||
#vmform table tr td:nth-child(even){width:110px}
|
||||
#vmform table tr td:first-child{padding-right:30px}
|
||||
#vmform table tr td:last-child{width:inherit}
|
||||
#vmform .multiple{position:relative}
|
||||
#vmform .sectionbutton{position:absolute;left:2px;cursor:pointer;opacity:0.4;font-size:1.4rem;line-height:17px;z-index:10;transition-property:opacity,left;transition-duration:0.1s;transition-timing-function:linear}
|
||||
#vmform .sectionbutton.remove{top:0;opacity:0.3}
|
||||
#vmform .sectionbutton.add{bottom:0}
|
||||
#vmform .sectionbutton:hover{opacity:1.0}
|
||||
#vmform .sectiontab{position:absolute;top:2px;bottom:2px;left:0;width:6px;border-radius:3px;background-color:#DDDDDD;transition-property:background,width;transition-duration:0.1s;transition-timing-function:linear}
|
||||
#vmform .multiple:hover .sectionbutton{opacity:0.7;left:4px}
|
||||
#vmform .multiple:hover .sectionbutton.remove{opacity:0.6}
|
||||
#vmform .multiple:hover .sectiontab{background-color:#CCCCCC;width:8px}
|
||||
#vmform table.multiple:hover{background-position:0 0;}
|
||||
#vmform table.multiple td{padding:5px 0}
|
||||
span.advancedview_panel{display:none;line-height:16px;margin-top:1px}
|
||||
.basic{display:none}
|
||||
.advanced{/*Empty placeholder*/}
|
||||
.switch-button-label.off{color:inherit}
|
||||
#template_img{cursor:pointer}
|
||||
#template_img:hover{opacity:0.5}
|
||||
#template_img:hover i{opacity:1.0}
|
||||
.template_img_chooser_inner{display:inline-block;width:80px;margin-bottom:15px;margin-right:10px;text-align:center;}
|
||||
.template_img_chooser_inner img{width:48px;height:48px}
|
||||
.template_img_chooser_inner p{text-align:center;line-height:8px;}
|
||||
#template_img_chooser{width:560px;height:300px;overflow-y:scroll;position:relative}
|
||||
#template_img_chooser div:hover{background-color:#eee;cursor:pointer;}
|
||||
#form_content{display:none}
|
||||
#vmform .four{overflow:hidden}
|
||||
#vmform .four label{float:left;display:table-cell;width:15%;}
|
||||
#vmform .four label:nth-child(4n+4){}
|
||||
#vmform .four label.cpu1{width:28%;height:16px;line-height:16px}
|
||||
#vmform .four label.cpu2{width:3%;height:16px;line-height:16px}
|
||||
#vmform .mac_generate{cursor:pointer;margin-left:-5px;color:#08C;font-size:1.3rem;transform:translate(0px, 2px)}
|
||||
#vmform .disk{display:none}
|
||||
#vmform .disk_preview{display:inline-block;color:#BBB;transform:translate(0px, 1px)}
|
||||
i.fa-plus-circle,i.fa-minus-circle{margin-left:8px}
|
||||
input[type=checkbox]{margin-left:0}
|
||||
#vmform table.timers td.present {width:150px;}
|
||||
@@ -0,0 +1,4 @@
|
||||
.fileTree{background:#f2f2f2;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:relative;z-index:100;display:none}
|
||||
#vmform table.multiple{margin:10px 0;background:#f2f2f2;background-size:800px 100%;background-position:-800px;background-repeat:no-repeat;background-clip:content-box;transition:background 0.3s linear}
|
||||
#template_img_chooser_outer{position:absolute;display:none;border-radius:5px;border:1px solid <?=$border?>;background:#f2f2f2;z-index:10}
|
||||
span#dropbox{border:1px solid <?=$border?>;background:#f2f2f2;padding:28px 12px;line-height:72px;margin-right:16px;}
|
||||
@@ -0,0 +1,4 @@
|
||||
.fileTree{background:#1c1c1c;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:relative;z-index:100;display:none}
|
||||
#vmform table.multiple{margin:10px 0;background:#1c1c1c;background-size:800px 100%;background-position:-800px;background-repeat:no-repeat;background-clip:content-box;transition:background 0.3s linear}
|
||||
#template_img_chooser_outer{position:absolute;display:none;border-radius:5px;border:1px solid <?=$border?>;background:#1c1c1c;z-index:10}
|
||||
span#dropbox{border:1px solid <?=$border?>;background:#1c1c1c;padding:28px 12px;line-height:72px;margin-right:16px;}
|
||||
@@ -0,0 +1,4 @@
|
||||
.fileTree{background:#1c1c1c;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:relative;z-index:100;display:none}
|
||||
#vmform table.multiple{margin:10px 0;background:#1c1c1c;background-size:800px 100%;background-position:-800px;background-repeat:no-repeat;background-clip:content-box;transition:background 0.3s linear}
|
||||
#template_img_chooser_outer{position:absolute;display:none;border-radius:5px;border:1px solid <?=$border?>;background:#1c1c1c;z-index:10}
|
||||
span#dropbox{border:1px solid <?=$border?>;background:#1c1c1c;padding:28px 12px;line-height:72px;margin-right:16px;}
|
||||
@@ -0,0 +1,4 @@
|
||||
.fileTree{background:#f2f2f2;width:300px;max-height:150px;overflow-y:scroll;overflow-x:hidden;position:relative;z-index:100;display:none}
|
||||
#vmform table.multiple{margin:10px 0;background:#f2f2f2;background-size:800px 100%;background-position:-800px;background-repeat:no-repeat;background-clip:content-box;transition:background 0.3s linear}
|
||||
#template_img_chooser_outer{position:absolute;display:none;border-radius:5px;border:1px solid <?=$border?>;background:#f2f2f2;z-index:10}
|
||||
span#dropbox{border:1px solid <?=$border?>;background:#f2f2f2;padding:28px 12px;line-height:72px;margin-right:16px;}
|
||||
43
emhttp/plugins/dynamix.vm.manager/sheets/UpdateVM.css
Normal file
43
emhttp/plugins/dynamix.vm.manager/sheets/UpdateVM.css
Normal file
@@ -0,0 +1,43 @@
|
||||
body{-webkit-overflow-scrolling:touch}
|
||||
#vmform table{margin-top:0}
|
||||
#vmform div.title + table{margin-top:0}
|
||||
#vmform table tr{vertical-align:top;line-height:40px}
|
||||
#vmform table tr td:nth-child(odd){width:300px;text-align:right;padding-right:10px}
|
||||
#vmform table tr td:nth-child(even){width:110px}
|
||||
#vmform table tr td:first-child{padding-right:30px}
|
||||
#vmform table tr td:last-child{width:inherit}
|
||||
#vmform .multiple{position:relative}
|
||||
#vmform .sectionbutton{position:absolute;left:2px;cursor:pointer;opacity:0.4;font-size:1.4rem;line-height:17px;z-index:10;transition-property:opacity,left;transition-duration:0.1s;transition-timing-function:linear}
|
||||
#vmform .sectionbutton.remove{top:0;opacity:0.3}
|
||||
#vmform .sectionbutton.add{bottom:0}
|
||||
#vmform .sectionbutton:hover{opacity:1.0}
|
||||
#vmform .sectiontab{position:absolute;top:2px;bottom:2px;left:0;width:6px;border-radius:3px;background-color:#DDDDDD;transition-property:background,width;transition-duration:0.1s;transition-timing-function:linear}
|
||||
#vmform .multiple:hover .sectionbutton{opacity:0.7;left:4px}
|
||||
#vmform .multiple:hover .sectionbutton.remove{opacity:0.6}
|
||||
#vmform .multiple:hover .sectiontab{background-color:#CCCCCC;width:8px}
|
||||
#vmform table.multiple:hover{background-position:0 0;}
|
||||
#vmform table.multiple td{padding:5px 0}
|
||||
span.advancedview_panel{display:none;line-height:16px;margin-top:1px}
|
||||
.basic{display:none}
|
||||
.advanced{/*Empty placeholder*/}
|
||||
.switch-button-label.off{color:inherit}
|
||||
#template_img{cursor:pointer}
|
||||
#template_img:hover{opacity:0.5}
|
||||
#template_img:hover i{opacity:1.0}
|
||||
.template_img_chooser_inner{display:inline-block;width:80px;margin-bottom:15px;margin-right:10px;text-align:center;}
|
||||
.template_img_chooser_inner img{width:48px;height:48px}
|
||||
.template_img_chooser_inner p{text-align:center;line-height:8px;}
|
||||
#template_img_chooser{width:560px;height:300px;overflow-y:scroll;position:relative}
|
||||
#template_img_chooser div:hover{background-color:#eee;cursor:pointer;}
|
||||
#form_content{display:none}
|
||||
#vmform .four{overflow:hidden}
|
||||
#vmform .four label{float:left;display:table-cell;width:15%;}
|
||||
#vmform .four label:nth-child(4n+4){}
|
||||
#vmform .four label.cpu1{width:28%;height:16px;line-height:16px}
|
||||
#vmform .four label.cpu2{width:3%;height:16px;line-height:16px}
|
||||
#vmform .mac_generate{cursor:pointer;margin-left:-5px;color:#08C;font-size:1.3rem;transform:translate(0px, 2px)}
|
||||
#vmform .disk{display:none}
|
||||
#vmform .disk_preview{display:inline-block;color:#BBB;transform:translate(0px, 1px)}
|
||||
i.fa-plus-circle,i.fa-minus-circle{margin-left:8px}
|
||||
input[type=checkbox]{margin-left:0}
|
||||
#vmform table.timers td.present {width:150px;}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user