31 Commits

Author SHA1 Message Date
192d2ce3a8 Update .drone.yml
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone/tag Build was killed
2025-03-28 15:07:35 +00:00
490503f476 upgrade changes
Some checks reported errors
continuous-integration/drone/push Build was killed
2025-03-26 20:04:08 +01:00
184ec08938 Merge branch 'main' of ssh://git.format.hu/safebox/web-installer
Some checks reported errors
continuous-integration/drone/push Build was killed
2025-03-26 13:00:04 +01:00
75b2212f8f search for updates 2025-03-26 12:59:53 +01:00
c745c05eb5 Update .drone.yml
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-22 15:56:59 +00:00
7377f5290c change service table id
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-19 14:15:58 +01:00
594a430eb9 check_upgrade
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-19 14:12:32 +01:00
ae4a031584 change update service name 2025-03-19 14:08:58 +01:00
7b09b19e81 upgrade call
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-19 00:47:47 +01:00
65e8554032 update call
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-19 00:31:33 +01:00
6b3a409dc2 vpn cancel button
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-18 23:49:18 +01:00
c7e4f79f2f cancel mod 2025-03-18 17:11:45 +01:00
f0dbafd37c refresh btn
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-18 17:06:15 +01:00
22a1b07b85 uninstall, cancel just in case of reinstall
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-18 16:42:55 +01:00
cb00ade9b6 deployment edit mods
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-18 15:25:44 +01:00
b6a43bf316 show letsencrypt in progress if file or domain does not exists
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-14 15:23:31 +01:00
95ab5e1d1c show letsencryptinfo according to new json structure
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-14 15:12:55 +01:00
ed6b08b481 close all deployments except the current one
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-14 14:48:38 +01:00
aefc09d222 uninstall confirm
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-14 14:24:25 +01:00
d146d2d054 refresh deployments
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-14 13:21:11 +01:00
38305ffbee diagnostic->local backend
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-13 21:57:12 +01:00
6889af9aa8 add git for development
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-13 21:27:49 +01:00
de23eaf27c check_vpn status
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-13 21:08:33 +01:00
26e37a16d3 uninstall, check_uninstall JS
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-13 13:02:02 +01:00
49fa4e040d uninstall, check_uninstall
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-13 13:00:25 +01:00
16ea6140bd redeploy
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-13 00:48:03 +01:00
1cfa962229 do not finish check_deployment
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-12 23:26:39 +01:00
d08594458e remove from output if finished so reinstall can start
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-12 17:44:01 +01:00
3301fb300f addition field class rename
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-12 16:09:17 +01:00
48a00a4e00 resolve duplicate id
All checks were successful
continuous-integration/drone/push Build is passing
2025-03-12 15:33:40 +01:00
dbda5055db check_deployment debug 2025-03-12 15:12:14 +01:00
7 changed files with 267 additions and 65 deletions

View File

@@ -6,10 +6,9 @@ node_selector:
physical-node: dev1
trigger:
branch:
- main
event:
- push
- tag
workspace:
path: /drone/src
@@ -30,6 +29,9 @@ steps:
platforms:
- linux/amd64
- linux/arm64
when:
event:
- push
- name: pull image to dockerhub
image: docker.io/owncloudci/drone-docker-buildx:4
@@ -44,4 +46,7 @@ steps:
from_secret: dockerhub-password
platforms:
- linux/amd64
- linux/arm64
- linux/arm64
when:
event:
- tag

View File

@@ -63,8 +63,9 @@ RUN apk --no-cache add php${PHP_VERSION} \
php${PHP_VERSION}-fpm \
php${PHP_VERSION}-curl \
php${PHP_VERSION}-pecl-redis \
vim \
curl \
vim \
git \
rm -rf /var/cache/apk/*
COPY nginx.conf /etc/nginx/nginx.conf

View File

@@ -127,7 +127,7 @@ function get_vpn_url($domain,$passkey) {
}
function show_service($name, $containers) {
$str = '<table id="'.$name.'">';
$str = '<table id="service_'.$name.'">';
$str .= "<tr><th>{$name}</th></tr>";
$containers = trim($containers);
$arr = explode("|",$containers);
@@ -141,14 +141,14 @@ function show_service($name, $containers) {
}
function show_service_update($name, $update, $uptodate) {
$str = '<table id="'.$name.'">';
$str = '<table id="update_'.$name.'">';
$str .= "<tr><th>{$name}</th></tr>";
$update = trim($update);
if (!empty($update)) {
$arr = explode(" ",$update);
foreach ($arr as $container) {
$str .= "<tr><td>&nbsp;</td><td>".$container."</td><td>UPDATE AVAILABLE</td><td>UPDATE</td></tr>";
$str .= "<tr><td>&nbsp;</td><td>".$container."</td><td>UPDATE AVAILABLE</td><td><a href=\"#\" onclick=\"upgrade('{$name}')\">UPDATE</a></td></tr>";
}
}
@@ -307,9 +307,9 @@ function check_letsencrypt() {
// TODO json error
}
else {
foreach ($data as $d) {
$result[$d["domain"]] = $d;
}
foreach ($data as $domain => $domain_data) {
$result[$domain] = $domain_data;
}
}
}
else $result = "";

View File

@@ -178,6 +178,15 @@
<script>
jQuery(document).ready(function(){
jQuery('#diagnostic').click(function() {
if (jQuery(this).val()=='yes') {
jQuery('#local_backend').val('yes');
}
else {
jQuery('#local_backend').val('no');
}
});
jQuery('#advanced').click(function() {
jQuery('#advanced_div').toggle();
});

View File

@@ -16,6 +16,9 @@ body#scan{
/* background-color: #7E57C2; */
}
.red {color: red}
.green {color: green}
.mt-100{
margin-top: 100px;
}

View File

@@ -8,7 +8,7 @@
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.2.1/dist/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<!-- Custom styles for this template -->
<link href="installer.css?t=4" rel="stylesheet">
<link href="installer.css?t=5" rel="stylesheet">
</head>
<body id="manage" class="text-center">
<div class="container-fluid">
@@ -16,8 +16,14 @@
<h1>Found deployed environment</h1>
<div style="text-align:left;float:left">
<div style="text-align:left;float:left;width:33%">
<a href="javascript:void()" id="vpn_btn">VPN</a>
Status:
<span id="vpn_on" class="hidden green"><b>ON</b></span>
<span id="vpn_off" class="hidden red"><b>OFF</b></span>
</div>
<div style="text-align:center;float:left;width:34%">
<a href="manage.html" id="refresh_btn">REFRESH</a>
</div>
<div style="text-align:right;float:right">
<a href="javascript:void()" id="settings_btn">SETTINGS</a>
@@ -60,7 +66,8 @@
</div>
<div class="row">
<div class="mb-3">
<button class="btn btn-lg btn-primary btn-block" type="submit" id="vpn_save_btn"> Save </button>
<button class="btn btn-lg btn-primary btn-block" type="submit" id="vpn_save_btn"> Save </button> &nbsp;
<button class="btn btn-lg btn-primary btn-block" type="button" id="vpn_cancel_btn"> Cancel </button>
</div>
</div>
</form>
@@ -99,8 +106,10 @@
<fieldset>
<legend>Updates</legend>
<div style="text-align:left">
<a href="javascript:void()" id="update_btn">Search for updates</a>
</div>
<div id="updates" style="text-align:left">
<a href="javascript:void()" id="update_btn">Search updates</a>
</div>
</fieldset>
<br>
@@ -220,6 +229,22 @@ function add_repository() {
});
}
function check_vpn() {
var url = 'scan.php?op=check_vpn';
jQuery.get(url, function(data) {
console.log('check_vpn: '+data);
if (data=="2") {
$('#vpn_off').hide();
$('#vpn_on').show();
}
else {
$('#vpn_on').hide();
$('#vpn_off').show();
}
setTimeout(check_vpn, 10000);
});
}
function save_vpn() {
var url = 'scan.php?op=save_vpn&vpn_domain='+jQuery('#vpn_domain').val()+'&vpn_pass='+jQuery('#vpn_pass').val()+'&letsencrypt_mail='+jQuery('#letsencrypt_mail').val()+'&letsencrypt_servername='+jQuery('#letsencrypt_servername').val();
@@ -254,7 +279,35 @@ function get_updates() {
});
}
function check_upgrade() {
var url = 'scan.php?op=check_upgrade';
jQuery.get(url, function(data) {
console.log('check_upgrade: '+data);
if (data=="WAIT" || data=="") {
setTimeout(check_upgrade, 1000);
}
else {
// TODO
}
});
}
function upgrade(service) {
var url = 'scan.php?op=upgrade&service='+service;
console.log('upgrade start: '+service);
jQuery.get(url, function(data) {
console.log('upgrade end: '+service);
if (data=="OK") {
setTimeout(check_upgrade, 1000);
}
});
}
function load_template(additional) {
jQuery("div.deployment").each(function(index) {
$(this).html('');
});
jQuery("#"+additional).html('Loading '+additional+' template...');
var url = 'scan.php?op=deployment&additional='+additional;
jQuery.get(url, function(data) {
@@ -277,7 +330,10 @@ function check_reinstall(additional) {
}
function reinstall(additional) {
jQuery("#"+additional).html('Loading...');
jQuery("div.deployment").each(function(index) {
$(this).html('');
});
jQuery("#"+additional).html('Loading '+additional+' template...');
var url = 'scan.php?op=reinstall&additional='+additional;
jQuery.get(url, function(data) {
console.log('reinstall '+additional+': '+data);
@@ -288,31 +344,48 @@ function reinstall(additional) {
}
function check_uninstall(additional) {
var url = 'scan.php?op=check_uninstall';
var url = 'scan.php?op=check_uninstall&additional='+additional;
jQuery.get(url, function(data) {
console.log('check_uninstall '+additional+': '+data);
console.log('check_uninstall '+additional+': '+data);
if (data!="") {
jQuery("#"+additional).html(data);
jQuery("#"+additional).html(data);
}
if (data!="OK") {
setTimeout(check_uninstall, 1000, additional);
}
else {
jQuery("#"+additional).html('Uninstall has finished');
get_deployments();
}
else setTimeout(check_uninstall, 1000, additional);
});
}
function uninstall(additional) {
jQuery("div.deployment").each(function(index) {
$(this).html('');
});
data = '<fieldset><form action="#" method="post"><div class="row">YOU ARE GOING TO UNINSTALL '+additional.toUpperCase()+'.<br>ARE YOU SURE? IF YES, PLEASE CLICK ON THE BUTTON BELOW.<br><br></div><div class="row"><div class="mb-3"><button class="btn btn-lg btn-primary btn-block" type="button" onclick="confirm_uninstall(\''+additional+'\')">Uninstall</button></div></div></form></fieldset>';
jQuery("#"+additional).html(data);
}
function confirm_uninstall(additional) {
jQuery("#"+additional).html('Loading...');
var url = 'scan.php?op=uninstall&additional='+additional;
jQuery.get(url, function(data) {
console.log('uninstall '+additional+': '+data);
if (data!="") {
jQuery("#"+additional).html(data);
setTimeout(check_uninstall, 1000, additional);
}
console.log('uninstall '+additional+': '+data);
if (data!="") {
jQuery("#"+additional).html(data);
setTimeout(check_uninstall, 1000, additional);
}
});
}
function check_deployment(additional) {
var url = 'scan.php?op=check_deployment&additional='+additional;
jQuery.get(url, function(data) {
console.log('check_deployment '+additional+': '+data);
console.log('check_deployment '+additional);
//console.log('check_deployment data: '+data);
if (data!="") {
jQuery("#"+additional).html(data);
}
@@ -322,7 +395,7 @@ function check_deployment(additional) {
function deploy(additional) {
pars = '';
jQuery('input.additional_field').each(function(index) {
jQuery('input.additional_'+additional).each(function(index) {
console.log('Field ' + $(this).attr('name') + ': ' + $(this).val());
//pars += '&'+$(this).attr('id') + '=' + $(this).val();
pars += '&'+$(this).attr('name') + '=' + $(this).val();
@@ -338,6 +411,24 @@ function deploy(additional) {
});
}
function redeploy(additional) {
pars = '';
jQuery('input.additional_'+additional).each(function(index) {
console.log('Field ' + $(this).attr('name') + ': ' + $(this).val());
//pars += '&'+$(this).attr('id') + '=' + $(this).val();
pars += '&'+$(this).attr('name') + '=' + $(this).val();
});
//console.log(pars);
var url = 'scan.php?op=redeploy&additional='+additional+pars;
jQuery.get(url, function(data) {
console.log('redeploy '+additional+': '+data);
if (data!="") {
jQuery("#"+additional).html(data);
setTimeout(check_deployment, 1000, additional);
}
});
}
function check_services() {
var url = 'scan.php?op=check_services';
jQuery.get(url, function(data) {
@@ -385,6 +476,7 @@ jQuery(document).ready(function(){
get_repositories();
get_system();
get_services();
check_vpn();
jQuery('#deployments_btn').click(function() {
jQuery('#services').hide();
@@ -407,6 +499,10 @@ jQuery(document).ready(function(){
jQuery('#settings').hide();
});
jQuery('#vpn_cancel_btn').click(function() {
jQuery('#vpn').hide();
});
jQuery('#update_btn').click(function() {
jQuery('#updates').html('Looking for updates... Please wait...');
get_updates();

166
scan.php
View File

@@ -142,11 +142,11 @@ switch ($_GET["op"]) {
if ($data["DEPLOYMENTS"]["deployments"]=="NONE") echo "There are no deployments.<br>";
else {
foreach ($data["DEPLOYMENTS"] as $service_name => $content) {
$orig_service_name = $service_name;
$service_name = strtolower($service_name);
//echo base64_decode($content);
$orig_service_name = $service_name;
$service_name = strtolower($service_name);
//echo base64_decode($content);
if (array_key_exists($service_name,$data["INSTALLED_SERVICES"])) {
echo '<div>'.$service_name.' - '.$content.' - INSTALLED - <a href="#" onclick="uninstall(\''.$service_name.'\')">UNINSTALL</a> - <a href="#" onclick="reinstall(\''.$service_name.'\')">REINSTALL</a></div>';
echo '<div><a href="#" onclick="reinstall(\''.$service_name.'\')">'.$orig_service_name.'</a> - '.$content.' - INSTALLED</div>';
}
else echo '<div><a href="#" onclick="load_template(\''.$service_name.'\')">'.$orig_service_name.'</a> - '.$content.'</div>';
echo '<div id="'.$service_name.'" class="deployment"></div>';
@@ -196,43 +196,62 @@ switch ($_GET["op"]) {
//var_dump($template);
//var_dump($template);
$letsencrypt = check_letsencrypt();
foreach ($template->fields as $field) {
if ($field->key=="DOMAIN") {
if (!empty($letsencrypt[$field->value])) {
echo "LETSENCRYPT: ".$letsencrypt[$field->value]["status"]." - ".$letsencrypt[$field->value]["date"];
echo " - <a href=\"letsencrypt_log.php?domain={$field->value}\" target=\"_blank\">LOG</a><br><br>";
}
}
}
if (empty($letsencrypt)) echo "LETSENCRYPT in progress...";
else {
foreach ($template->fields as $field) {
if ($field->key=="DOMAIN") {
if (!empty($letsencrypt[$field->value])) {
echo "LETSENCRYPT: ".$letsencrypt[$field->value]["status"]." - ".$letsencrypt[$field->value]["date"];
echo " - <a href=\"letsencrypt_log.php?domain={$field->value}\" target=\"_blank\">LOG</a><br><br>";
}
else echo "LETSENCRYPT in progress for {$field->value}.";
}
}
}
}
foreach ($template->fields as $field) {
if (isset($field->generated)) {
echo "<input type=\"hidden\" value=\"generated:{$field->generated}\" name=\"{$field->key}\" id=\"{$template->name}_{$field->key}\" class=\"additional_field\">";
echo "<input type=\"hidden\" value=\"generated:{$field->generated}\" name=\"{$field->key}\" id=\"{$template->name}_{$field->key}\" class=\"additional_{$template->name}\">";
}
else {
echo "<div class=\"row\"><div class=\"mb-3\"><label>".$field->description."</label>
<input ".($field->required=="true" ? "required" : "")." type=\"".(!empty($field->type) ? $field->type : "text")."\" value=\"{$field->value}\" name=\"{$field->key}\" id=\"{$template->name}_{$field->key}\" class=\"additional_field\">
<input ".($field->required=="true" ? "required" : "")." type=\"".(!empty($field->type) ? $field->type : "text")."\" value=\"{$field->value}\" name=\"{$field->key}\" id=\"{$template->name}_{$field->key}\" class=\"additional_{$template->name}\">
</div></div>";
}
}
echo "
<div class=\"row\">
<div class=\"mb-3\">
<input type=\"hidden\" value=\"{$template->name}\" id=\"additional\">
<button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\" id=\"deploy_btn\">".($reinstall ? "Reinstall" : "Install")."</button>
</div>
</div>
</form></fieldset>
echo "
<div class=\"row\">
<div class=\"mb-3\">
<button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\" id=\"deploy_{$template->name}_btn\">".($reinstall ? "Reinstall" : "Install")."</button>
</div>";
if ($reinstall) {
echo "
<div class=\"mb-3\" style=\"margin-left:30px;\">
<button class=\"btn btn-lg btn-primary btn-block\" type=\"button\" id=\"uninstall_{$template->name}_btn\" onclick=\"uninstall('{$template->name}')\">Uninstall</button>
</div>";
}
echo "<div class=\"mb-3\" style=\"margin-left:30px;\">
<button class=\"btn btn-lg btn-primary btn-block\" type=\"button\" id=\"cancel_{$template->name}_btn\">Cancel</button>
</div>";
echo "
</div>
</form></fieldset>
<script>
jQuery('#deploy_{$template->name}_form').submit(function() {
deploy('{$template->name}');
".($reinstall ? "redeploy" : "deploy")."('{$template->name}');
return false;
});
jQuery('#cancel_{$template->name}_btn').click(function() {
$('div#{$template->name}').html('');
});
</script>
";
}
elseif ($data["STATUS"]=="2") { // deploy
echo "Install has finished.";
echo "<script>get_deployments();</script>";
}
remove_response("$key");
}
@@ -244,10 +263,13 @@ switch ($_GET["op"]) {
foreach ($arr as $key=>$data) {
if ($key=="deploy-".$_GET["additional"]) {
if ($data["STATUS"]=="1") {
echo "Install in progress... Please wait...";
//echo "Install in progress... Please wait...";
echo "";
}
elseif ($data["STATUS"]=="2") {
echo "Install has finished.";
echo "<script>get_deployments();</script>";
remove_response("$key"); // remove from output if finished so reinstall can start
}
}
}
@@ -255,6 +277,7 @@ switch ($_GET["op"]) {
else echo ""; // no deployment, finished
}
break;
case "redeploy":
case "deploy":
if ($key=check_deploy($_GET["additional"])) {
$text="A deployment ({$_GET["additional"]}) has already started.<br>Please wait and do not start a new one...";
@@ -293,7 +316,7 @@ switch ($_GET["op"]) {
}
}
$payload = base64_encode(json_encode($fields, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT));
$arr = array("NAME" => $_GET["additional"], "ACTION" => "deploy", "PAYLOAD" => $payload);
$arr = array("NAME" => $_GET["additional"], "ACTION" => $_GET["op"], "PAYLOAD" => $payload);
$json = json_encode($arr, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
if (set_output("deployment",$json)) echo "OK";
else echo "ERROR";
@@ -307,20 +330,71 @@ switch ($_GET["op"]) {
if (set_output("deployment",$json)) echo "OK";
else echo "ERROR";
break;
case "uninstall":
if ($key=check_deploy()) {
$text="Deploy/uninstall process has already started.<br>Please wait and do not start a new one...";
}
else {
$text="Uninstall in progress... Please wait...";
$arr = array("NAME" => $_GET["additional"], "ACTION" => "uninstall");
$json = json_encode($arr, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
$op = "deployment";
if (set_output("deployment",$json)) echo "OK";
else echo "ERROR";
}
echo $text;
break;
case "check_uninstall":
$arr = check_deploy($_GET["additional"]);
if (!empty($arr)) { // deployment in progress
foreach ($arr as $key=>$data) {
if ($key=="deploy-".$_GET["additional"]) {
if ($data["STATUS"]=="1") {
echo "Install in progress... You can't uninstall while in progress...";
}
elseif ($data["STATUS"]=="2") {
echo "Install has finished...";
echo "<script>get_deployments();</script>";
remove_response("$key");
}
}
}
}
else { // no deployment in progress -> uninstall
$key = "uninstall-".$_GET["additional"];
$arr = check_response($key);
if (!empty($arr)) {
$data = $arr[$key];
if ($data["STATUS"]=="1") {
echo "Uninstall in progress... Please wait... ".date("Y-m-d H:i:s");
}
elseif ($data["STATUS"]=="2") {
echo "OK";
remove_response("$key");
}
}
else echo "Uninstall in progress... Please wait...";
}
break;
case "uninstall":
if ($key=check_deploy($_GET["additional"])) {
$text="Deploy/uninstall process has already started.<br>Please wait and do not start a new one...";
}
else {
$text="Uninstall in progress... Please wait...";
$arr = array("NAME" => $_GET["additional"], "ACTION" => "uninstall");
$json = json_encode($arr, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
if (set_output("deployment",$json)) echo "OK";
else echo "ERROR";
}
echo $text;
break;
case "check_upgrade":
$arr = check_response("upgrade");
if (!empty($arr)) {
foreach ($arr as $key=>$data) {
if ($key=="upgrade") {
var_dump($arr);
//remove_response("$key");
}
}
}
else echo "WAIT";
break;
case "upgrade":
$arr = array("NAME" => $_GET["service"], "ACTION" => "upgrade");
$json = json_encode($arr, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
if (set_output("upgrade",$json)) echo "OK";
else echo "ERROR";
break;
case "repositories":
$arr = array("STATUS" => 0);
$json = json_encode($arr, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
@@ -353,6 +427,20 @@ switch ($_GET["op"]) {
if (set_output("add_repository",$json)) echo "OK";
else echo "ERROR";
break;
case "check_vpn":
$key = "check_vpn";
$arr = array("STATUS" => 0);
$json = json_encode($arr, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT);
set_output($key,$json);
sleep(1);
$arr = check_response($key);
if (!empty($arr)) {
$data = $arr[$key];
echo $data["STATUS"];
remove_response("$key");
}
else echo "NO";
break;
case "save_vpn":
remove_response("save_repository");