Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/nextcloudpi.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornachoparker <nacho@ownyourbits.com>2017-08-24 11:31:18 +0300
committernachoparker <nacho@ownyourbits.com>2017-08-24 22:35:17 +0300
commitf044c6d6b22885393b2f46477c88317fdf688994 (patch)
treef44901f1afa1a586233975b86137865aec528667
parentedccf4a7e196762dd973f3701e217c5f7d743eb3 (diff)
ncp-web: use SSE to display process output in real time. Exit status green/redv0.24.2
-rw-r--r--ncp-web/green-circle.svg34
-rw-r--r--ncp-web/index.php5
-rw-r--r--ncp-web/ncp-launcher.php7
-rw-r--r--ncp-web/ncp-output.php93
-rw-r--r--ncp-web/ncp.css12
-rw-r--r--ncp-web/ncp.js35
-rw-r--r--ncp-web/red-circle.svg33
-rw-r--r--nextcloudpi.sh5
-rwxr-xr-xupdate.sh14
9 files changed, 231 insertions, 7 deletions
diff --git a/ncp-web/green-circle.svg b/ncp-web/green-circle.svg
new file mode 100644
index 00000000..e82ffe38
--- /dev/null
+++ b/ncp-web/green-circle.svg
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ height="11.457627"
+ width="11.288136"
+ viewbox="0 0 599 599"
+ id="Green circle"
+ version="1.1">
+ <metadata
+ id="metadata8">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs6" />
+ <ellipse
+ ry="5.7288136"
+ rx="5.6440678"
+ cy="5.7288136"
+ cx="5.6440678"
+ style="fill:#339933;stroke-width:1.42157066"
+ id="green_circle" />
+</svg>
diff --git a/ncp-web/index.php b/ncp-web/index.php
index 65ceff78..7ddbed87 100644
--- a/ncp-web/index.php
+++ b/ncp-web/index.php
@@ -1,5 +1,5 @@
<!--
- NextcloudPi Web Panel javascript library
+ NextcloudPi Web Panel frontend
Copyleft 2017 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
GPL licensed (see end of file) * Use at your own risk!
@@ -20,7 +20,7 @@
session_start();
// security headers
- header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self';");
+ header("Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; object-src 'self';");
header("X-XSS-Protection: 1; mode=block");
header("X-Content-Type-Options: nosniff");
header("X-Robots-Tag: none");
@@ -117,6 +117,7 @@
<div id="config-button-wrapper">
<button id="config-button">Run</button>
<img id="loading-gif" src="loading-small.gif">
+ <div id="circle-retstatus" class="icon-red-circle"></div>
</div>
</form>
<textarea readonly id="details-box" rows="25" cols="60"></textarea>
diff --git a/ncp-web/ncp-launcher.php b/ncp-web/ncp-launcher.php
index 032b01ef..efb24761 100644
--- a/ncp-web/ncp-launcher.php
+++ b/ncp-web/ncp-launcher.php
@@ -11,6 +11,7 @@
include ('csrf.php');
session_start();
+ignore_user_abort( true );
if ( $_POST['action'] == "cfgreq" )
{
@@ -97,9 +98,11 @@ else if ( $_POST['action'] == "launch" && $_POST['config'] )
// Get new token
echo '{ "token": "' . getCSRFToken() . '",';
- echo ' "output": ';
+ echo ' "output": "" , ';
+ echo ' "ret": ';
- echo json_encode( shell_exec( 'bash -c "sudo /home/www/ncp-launcher.sh ' . $file . '"' ) ) . ' }';
+ exec( 'bash -c "sudo /home/www/ncp-launcher.sh ' . $file . '"' , $output , $ret );
+ echo '"' . $ret . '" }';
}
else if ( $_POST['action'] == "poweroff" )
diff --git a/ncp-web/ncp-output.php b/ncp-web/ncp-output.php
new file mode 100644
index 00000000..750c71c6
--- /dev/null
+++ b/ncp-web/ncp-output.php
@@ -0,0 +1,93 @@
+<?php
+///
+// Dispatcher of SSE events with the contents of the NCP log
+//
+// Copyleft 2017 by Ignacio Nunez Hernanz <nacho _a_t_ ownyourbits _d_o_t_ com>
+// GPL licensed (see end of file) * Use at your own risk!
+//
+// More at https://ownyourbits.com/2017/02/13/nextcloud-ready-raspberry-pi-image/
+///
+
+header('Content-Type: text/event-stream; charset=utf-8');
+header('Cache-Control: no-cache'); // recommended to prevent caching of event data.
+
+
+/**
+ * Constructs the SSE data format and flushes that data to the client.
+ * ( from html5rocks.com )
+ *
+ * @param string $id Timestamp/id of this connection.
+ * @param string $msg Line of text that should be transmitted.
+ */
+function sendMsg($id, $msg)
+{
+ echo "id: $id" . PHP_EOL;
+ echo "data: $msg" . PHP_EOL;
+ echo PHP_EOL;
+ ob_flush();
+ flush();
+}
+
+/**
+ * Pings the client-browser to force detection of closed socket
+ */
+function pingClient()
+{
+ echo ' ';
+ ob_flush();
+ flush();
+}
+
+/**
+ * Imitates 'tail --follow' functionality, and sends lines as SSE events
+ * , while pinging browser to detect closed tab.
+ * ( based on stack overflow )
+ */
+function follow($file)
+{
+ $size = 0;
+ while (true)
+ {
+ clearstatcache();
+ $currentSize = filesize($file);
+ if ($size == $currentSize)
+ {
+ usleep(200000); // 0.2s
+ // if the user refreshes the tab >5 times, it won't load because it doesn't detect closed socket
+ // , and all workers are in use
+ pingClient();
+ continue;
+ }
+
+ $fh = fopen($file, "r");
+ fseek($fh, $size);
+
+ while ($line = fgets($fh))
+ sendMsg( 'output' , $line );
+
+ fclose($fh);
+ $size = $currentSize;
+ }
+}
+
+session_write_close();
+echo str_pad('',1024*1024*4); // make sure the browser buffer becomes full
+follow( '/run/ncp.log' );
+
+// License
+//
+// This script is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This script is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this script; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+?>
diff --git a/ncp-web/ncp.css b/ncp-web/ncp.css
index 012721dc..b829eea7 100644
--- a/ncp-web/ncp.css
+++ b/ncp-web/ncp.css
@@ -1113,6 +1113,18 @@ select {
background-image: url('poweroff.svg');
}
+.icon-red-circle {
+ background-image: url('red-circle.svg');
+ padding: 8px;
+ display: none;
+}
+
+.icon-green-circle {
+ background-image: url('green-circle.svg');
+ padding: 8px;
+}
+
+
#expand #expandDisplayName {
padding: 8px;
opacity: 0.6;
diff --git a/ncp-web/ncp.js b/ncp-web/ncp.js
index b200c8b0..707c2f6d 100644
--- a/ncp-web/ncp.js
+++ b/ncp-web/ncp.js
@@ -19,6 +19,25 @@ function errorMsg()
$(function()
{
+ // Event source to receive process output in real time
+ if (!!window.EventSource)
+ var source = new EventSource('ncp-output.php');
+ else
+ $('#config-box-title').fill( "Browser not supported" );
+
+ source.addEventListener('message', function(e)
+ {
+ if ( e.origin != 'https://' + window.location.hostname + ':4443')
+ {
+ $('#details-box').fill( "Invalid origin" );
+ return;
+ }
+
+ var textarea = $('#details-box');
+ textarea.fill( textarea.text() + e.data + '\n' );
+ textarea[0].scrollTop = textarea[0].scrollHeight;
+ }, false);
+
// Show selected option configuration box
$( 'li' , '#app-navigation' ).on('click', function(e)
{
@@ -38,6 +57,7 @@ $(function()
var ret = $.parseJSON( result );
if ( ret.token )
$('#csrf-token').set( { value: ret.token } );
+ $('#circle-retstatus').hide();
$('#config-box').ht( ret.output );
$('#config-box-title').fill( $( 'input' , '#' + selectedID ).get( '.value' ) );
$('#config-box-wrapper').show();
@@ -64,6 +84,11 @@ $(function()
cfg[item.name] = item.value;
} );
+ // reset box
+ $('#details-box').fill();
+ $('#details-box').show();
+ $('#circle-retstatus').hide();
+
// request
$.request('post', 'ncp-launcher.php', { action:'launch',
ref:selectedID ,
@@ -74,8 +99,14 @@ $(function()
var ret = $.parseJSON( result );
if ( ret.token )
$('#csrf-token').set( { value: ret.token } );
- $('#details-box').fill(ret.output);
- $('#details-box').show();
+ if ( ret.ret ) // means that the process was launched
+ {
+ if ( ret.ret == '0' ) $('#circle-retstatus').set( '+icon-green-circle' );
+ else $('#circle-retstatus').set( '-icon-green-circle' );
+ $('#circle-retstatus').show();
+ }
+ else // print error from server instead
+ $('#details-box').fill(ret.output);
$('#config-button').set('@disabled',null);
$('#loading-gif').hide();
confLock = false;
diff --git a/ncp-web/red-circle.svg b/ncp-web/red-circle.svg
new file mode 100644
index 00000000..acf7f898
--- /dev/null
+++ b/ncp-web/red-circle.svg
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ height="11.118644"
+ width="11.118644"
+ viewbox="0 0 0 0"
+ id="Red circle"
+ version="1.1">
+ <metadata
+ id="metadata8">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs6" />
+ <circle
+ r="5.5593219"
+ cy="5.5593219"
+ cx="5.5593219"
+ style="fill:#ff0000;stroke-width:1.38983047"
+ id="red_circle" />
+</svg>
diff --git a/nextcloudpi.sh b/nextcloudpi.sh
index abfd5a07..ffc9232c 100644
--- a/nextcloudpi.sh
+++ b/nextcloudpi.sh
@@ -60,7 +60,10 @@ DIR=/usr/local/etc/nextcloudpi-config.d
test -f $DIR/$1 || { echo "File not found"; exit 1; }
source /usr/local/etc/library.sh
cd $DIR
-launch_script $1
+touch /run/ncp.log
+chmod 640 /run/ncp.log
+chown root:www-data /run/ncp.log
+launch_script $1 &> /run/ncp.log
EOF
chmod 700 /home/www/ncp-launcher.sh
echo "www-data ALL = NOPASSWD: /home/www/ncp-launcher.sh , /sbin/halt" >> /etc/sudoers
diff --git a/update.sh b/update.sh
index d315392b..483c20ff 100755
--- a/update.sh
+++ b/update.sh
@@ -119,6 +119,20 @@ sed -i 's|www-data.*|www-data ALL = NOPASSWD: /home/www/ncp-launcher.sh , /sbin/
# fix fail2ban misconfig in stretch
rm -f /etc/fail2ban/jail.d/defaults-debian.conf
+# update ncp-launcher to support realtime updates with SSE
+ cat > /home/www/ncp-launcher.sh <<'EOF'
+#!/bin/bash
+DIR=/usr/local/etc/nextcloudpi-config.d
+test -f $DIR/$1 || { echo "File not found"; exit 1; }
+source /usr/local/etc/library.sh
+cd $DIR
+touch /run/ncp.log
+chmod 640 /run/ncp.log
+chown root:www-data /run/ncp.log
+launch_script $1 &> /run/ncp.log
+EOF
+ chmod 700 /home/www/ncp-launcher.sh
+
# License
#
# This script is free software; you can redistribute it and/or modify it