Skip to content

Commit

Permalink
initial ability to clone modules from another RACHEL
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Field committed Jul 13, 2017
1 parent 8836db0 commit 7d38c70
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 22 deletions.
72 changes: 71 additions & 1 deletion admin/background.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,13 @@
} else if (isset($_GET['clearLogs'])) {
clearLogs();

}
} else if (isset($_GET['cloneServer'])) {
cloneServer();

} else if (isset($_GET['setRsyncDaemon'])) {
setRsyncDaemon($_GET['setRsyncDaemon']);

}
error_log("Unknown request to background.php: " . print_r($_GET, true));
header("HTTP/1.1 500 Internal Server Error");
exit;
Expand Down Expand Up @@ -116,6 +121,10 @@ function deleteModule($moddir) {
function addModules($moddirs) {

$host = RSYNCHOST;
if (!empty($_GET['server'])) {
$host = preg_replace("/[^\w\d\.\-\:\/]/", "", $_GET['server']);
}

$relmodpath = getrelmodpath();

$moddirs = explode(",", $moddirs);
Expand Down Expand Up @@ -322,6 +331,32 @@ function setLocalContent($state) {
exit;
}

// XXX this doesn't work yet -- something weired about starting
// an rsync process under php
function setRsyncDaemon($state) {
# save the prefrence
$db = getdb();
$db_state = $db->escapeString($state);
$db->exec("REPLACE INTO prefs (pref, value) values ('run_rsyncd', '$db_state')");
# start the daemon (or stop it)
if ($state) {
error_log("starting rsyncd");
exec("rsync --daemon > /dev/null 2>&1", $out, $rv);
error_log("rv: $rv");
error_log("out: " . print_r($out, true));
} else {
error_log("stoping rsyncd");
exec("pkill -f 'rsync --daemon'", $out, $rv);
error_log("rv: $rv");
error_log("out: " . print_r($out, true));
}
header("HTTP/1.1 200 OK");
header("Content-Type: application/json");
echo "{ \"status\" : \"OK\" }\n";
exit;

}

function getBatteryInfo() {
$level = rtrim(file_get_contents("/tmp/batteryLastChargeLevel"));
$status = rtrim(file_get_contents("/tmp/chargeStatus"));
Expand Down Expand Up @@ -367,4 +402,39 @@ function clearLogs() {
exit;
}

# retrieves a .modules file from a user-supplied server
# -- this must be another RACHEL server
function cloneServer() {
# though the intent is an IP or hostname, we do
# accept appended port numbers and paths so that
# fancy-pants types can access special configurations
$server = preg_replace("/[^\w\d\.\-\:\/]+/", "", $_GET['cloneServer']);
# we have to suppress warnings here or they go to the browser
# and interfere with our ability to send headers
$contents = @file_get_contents("http://$server/export-modfile.php");
if ($contents === false) {
if ($http_response_header[0]) {
header($http_response_header[0]);
} else {
# probably means the server wasn't found
# - not officially a 404, but close enough
header("HTTP/1.1 404 Not Found");
}
} else {

# XXX: alternately we could update installmods() to take
# a string as well as a file, but for now:
$tempfile = tempnam(sys_get_temp_dir(), "rachelclone");
file_put_contents($tempfile, $contents);
installmods($tempfile, $server);
header("HTTP/1.1 200 OK");
header("Content-Type: application/json");
echo "{ \"status\" : \"OK\" }\n";

}

exit;

}

?>
6 changes: 6 additions & 0 deletions admin/common.php
Original file line number Diff line number Diff line change
Expand Up @@ -771,4 +771,10 @@ function show_local_content_link() {
return $rv;
}

function run_rsyncd() {
$db = getdb();
$rv = $db->querySingle("SELECT 1 FROM prefs WHERE pref = 'run_rsyncd' AND value = '1'");
return $rv;
}

?>
13 changes: 13 additions & 0 deletions admin/externals/rsyncd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
max connections = 10
log file = /var/log/rsync.log
pid file = /var/run/rsyncd.pid
timeout = 600
use chroot = false
uid = 0
gid = 0

[rachelmods]
comment = RACHEL Modules
path = /media/RACHEL/rachel/modules
read only = yes
list = yes
128 changes: 113 additions & 15 deletions admin/install.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

$mods_fs = getmods_fs();

$known_servers = array(
"jeremy" => "192.168.1.74",
"jfield" => "192.168.1.6",
);

# here is where we handle the "advanced" installation options,
# because of the file upload option, there's compatibility issues
# doing it in ajax through our background.php script, so we do it the
Expand All @@ -24,11 +29,6 @@

} else if (isset($_POST['server'])) {

$known_servers = array(
"jeremy" => "192.168.1.74",
"jfield" => "192.168.1.6",
);

if (isset($known_servers[ $_POST['server'] ])) {
$server = $known_servers[ $_POST['server'] ];
} else {
Expand Down Expand Up @@ -107,7 +107,7 @@
margin: 5px;
width: 20em;
}
#availspin {
#availspin, #advspin {
margin: 0; padding: 0;
position: relative;
top: 8px;
Expand Down Expand Up @@ -195,6 +195,8 @@
var ajaxTimeout = 10000;
var taskRefreshRate = 2000;

var knownServers = <?php echo json_encode($known_servers); ?>;

// need to convert the string that comes back because
// we need to escape "." in the selector name
function sel (text) {
Expand Down Expand Up @@ -250,7 +252,7 @@ function enableAvailUI() {
}

// add (i.e. rsync) a module
function addMods(moddirs) {
function addMods(moddirs, server) {

disableAvailUI();

Expand All @@ -262,17 +264,26 @@ function addMods(moddirs) {
moddirs = $("#available").val();
}

// optional server argument, turn it into a query string addition
if (server) {
server = "&server=" + server;
} else {
server = "";
}

// nothing selected - nothing to do
if (!moddirs) {
enableAvailUI();
return false;
}

console.log("background.php?addModules=" + moddirs + server);

// turn it into a comma-separated list
moddirs = moddirs.join();

$.ajax({
url: "background.php?addModules=" + moddirs,
url: "background.php?addModules=" + moddirs + server,
success: function(results) {

// honestly I'm not clear on why moddirs is available
Expand All @@ -291,7 +302,7 @@ function addMods(moddirs) {
},
error: function(xhr, status, error) {
console.log("failure");
// notify via button
// XXX notify via button
}
});

Expand Down Expand Up @@ -468,6 +479,14 @@ function pollTasks() {
$("#tasks").append("<li>None</li>");
// when all the tasks are done, we get a fresh copy of
// the local module list, in case anything funny happened
// XXX unintended side effect (but maybe ok?) this makes
// it so that when there are no tasks (normal state)
// the local "modlist" gets updated every poll -- that
// means if you `mkdir modules/foo` then "foo" will show
// up here without a page load. Cool, but perhaps too
// much unintended server load? Also, if there are tasks
// then this check *doesn't* take place until they're done.
// Sort of weird.
populateLocalModuleList();
}

Expand Down Expand Up @@ -717,22 +736,98 @@ function toggleAdvanced() {
}
}

function checkReinstall() {
function checkInstall() {
// if we're reinstalling the current set we don't need to do
// a real form submit (no filesystem interaction) so we can
// intercept and use the ajax methods here
// XXX this will not work when we add lang support
if ( $('select[name="mfile"]').val() == "reinstall existing set" ) {

modlist = [];
$("#modlist li").each( function(idx, li) {
modlist.push(li.id);
});

// see which server they want
var server = whichServer();

// if we don't check that there's something there,
// it installs everything - and that would be bad
if (modlist.length) {
addMods(modlist);
addMods(modlist, server);
}
toggleAdvanced();
return false;

// we're installing from another (RACHEL) server -- get a .modules
// file from that server and then
// XXX this will not work when we add lang support
} else if ( $('select[name="mfile"]').val() == "clone from server" ) {

// they didn't enter a server -- focus and bail
if (! $("#server_custom").val().match(/\w/)) {
$("#server_custom").focus();
return false;
}

$("#advspin").show();
$("#advnotice").html("");

// see which server they want
var server = whichServer();

// the response here is not json,
// just a raw .modules file (i.e. text/plain)
$.ajax({
url: "background.php?cloneServer=" + server,
success: function(results) {
console.log("SUCCESS: " + results);
toggleAdvanced();
},
error: function(xhr, status, error) {
$("#advnotice").css("color", "#c00");
$("#advnotice").html("X " + error + " : '" + server + "'");
},
complete: function(xhr, status) {
$("#advspin").hide();
}
});
return false;
}

}

function whichServer() {
// see which server they want
var server = null;
if ($("#server_custom").val() && $("#server_custom").val().match(/\w/)) {
server = $("#server_custom").val();
} else if (knownServers.hasOwnProperty($("#server").val())) {
server = knownServers[ $("#server").val() ];
} else if ($("#server").val()) {
server = $("#server").val();
}
return server;
}

// this just disables the server dropdown if the person
// selects cloning a server (we don't allow cloning the master servers)
function checkClone() {
// XXX this will not work when we add lang support
if ($("#mfile").val() == "clone from server") {
$("#server").prop("disabled", true);
$("#server_custom").focus();
} else {
$("#server").prop("disabled", false);
}
}

// disables server dropdown if the person enters one manually
function serverCustomInput() {
if ($("#server_custom").val().match(/\w/)) {
$("#server").prop("disabled", true);
} else {
$("#server").prop("disabled", false);
}
}

Expand All @@ -743,15 +838,16 @@ function checkReinstall() {

<button id="advancedbut" type="button" onclick="toggleAdvanced();">advanced</button>

<form id="advanced" method="post" onsubmit="return checkReinstall();" enctype="multipart/form-data">
<form id="advanced" method="post" onsubmit="return checkInstall();" enctype="multipart/form-data">
<table>
<tr>
<th>.modules:</th>
<td>
<select name="mfile">
<select name="mfile" onchange="checkClone();" id="mfile">
<!-- when this is internationalized, the value will be different -->
<!-- than the contents of the <option> tag -->
<option value="reinstall existing set">reinstall existing set</option>
<option value="clone from server">clone from server</option>
<option disabled>──────────</option>
<?php
# are we reliably in the admin directory
Expand Down Expand Up @@ -784,17 +880,19 @@ function checkReinstall() {
<tr>
<th>server:</th>
<td>
<select name="server">
<select name="server" id="server">
<option>dev.worldpossible.org</option>
<option>jeremy</option>
<option>jfield</option>
</select>
</td>
<td>
<i>&mdash; or &mdash;</i> specify host <input type="text" name="server_custom" value="">
<i>&mdash; or &mdash;</i> specify host <input type="text" name="server_custom" id="server_custom" oninput="serverCustomInput()" value="">
</td>
</table>
<input type="submit" name="advanced_install" value="Install">
<img src="../art/spinner.gif" id="advspin">
<span id="advnotice"></span>
</form>

<form id="availform"><!-- submitted via ajax -->
Expand Down
12 changes: 12 additions & 0 deletions admin/post-update-script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ main() {
#checkVariables
installESP
installAWStats
installRsyncdConf

}

Expand Down Expand Up @@ -196,4 +197,15 @@ restartWebserver() {
fi
}

# doesn't run rsync, but puts a conf file in place so it
# can be turned on if wanted
installRsyncdConf() {
if [[ $isPlus ]]; then
if [[ -f /etc/rsyncd.conf ]]; then
mv /etc/rsyncd.conf /etc/rsyncd.conf.prev
fi
cp -r $adminDir/externals/rsyncd.conf /etc/
fi
}

main "$@"

0 comments on commit 7d38c70

Please sign in to comment.