mirror of
https://github.com/yacy/yacy_search_server.git
synced 2024-09-19 00:01:41 +02:00
Hardened system update checks.
When a downloaded archive release is corrupted, empty, or can not be opened for any reason, the update script must not be launched because it erases the existing lib/*.jar libraries.
This commit is contained in:
parent
b5711b8fe1
commit
467650c042
|
@ -58,7 +58,8 @@
|
|||
<div class="commit">Download of release #[downloadedRelease]# finished. Restart Initiated.</div>::
|
||||
<div class="error">No more recent release found.</div>::
|
||||
<div class="error">Omitting update because this is a development environment.</div>::
|
||||
<div class="error">Omitting update because download of release #[downloadedRelease]# failed.</div>
|
||||
<div class="error">Omitting update because download of release #[downloadedRelease]# failed.</div>::
|
||||
<div class="error">Omitting update because an error occurred while trying to deploy the release.</div>
|
||||
#(/autoUpdate)#
|
||||
</p></form></dd>
|
||||
</dl>
|
||||
|
|
|
@ -149,10 +149,14 @@ public class ConfigUpdate_p {
|
|||
sb.getLog().info("AUTO-UPDATE: omitting update because download failed (file cannot be found, is too small or signature was bad)");
|
||||
prop.put("candeploy_autoUpdate", "4");
|
||||
} else {
|
||||
yacyRelease.deployRelease(downloaded);
|
||||
sb.terminate(10, "manual release update to " + downloaded.getName());
|
||||
sb.getLog().info("AUTO-UPDATE: deploy and restart initiated");
|
||||
prop.put("candeploy_autoUpdate", "1");
|
||||
if(yacyRelease.deployRelease(downloaded)) {
|
||||
sb.terminate(10, "manual release update to " + downloaded.getName());
|
||||
sb.getLog().info("AUTO-UPDATE: deploy and restart initiated");
|
||||
prop.put("candeploy_autoUpdate", "1");
|
||||
} else {
|
||||
sb.getLog().info("AUTO-UPDATE: omitting update because an error occurred while trying to deploy the release..");
|
||||
prop.put("candeploy_autoUpdate", "5");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,6 +196,12 @@ XDtoU7vQ/wIAAP//AwBb7ktEXQ4nqQAAAABJRU5ErkJggg==" width="128" height="64" alt="K
|
|||
::
|
||||
<p><b>The file you are trying to install is not located in the release directory.<br />
|
||||
Go back to the <a href="ConfigUpdate_p.html">System Update</a> page.</p>
|
||||
::
|
||||
<p><b>An error occurred when trying to install release #[release]#</b><br/>
|
||||
Please check your <a href="ViewLog_p.html">log</a> or go back to the <a href="ConfigUpdate_p.html">System Update</a> page.</p>
|
||||
::
|
||||
<p><b>You are in a development environment or the file you are trying to install is empty.</b><br/>
|
||||
Go back to the <a href="ConfigUpdate_p.html">System Update</a> page.</p>
|
||||
#(/info)#
|
||||
</body>
|
||||
</html>
|
|
@ -80,10 +80,16 @@ public class Steering {
|
|||
final File releaseFile = new File(sb.releasePath, releaseFileName);
|
||||
if (FileUtils.isInDirectory(releaseFile, sb.releasePath)) {
|
||||
if ((!devenvironment) && (releaseFileName.length() > 0) && (releaseFile.exists())) {
|
||||
yacyRelease.deployRelease(releaseFile);
|
||||
if(yacyRelease.deployRelease(releaseFile)) {
|
||||
prop.put("info", "5");
|
||||
prop.putHTML("info_release", releaseFileName);
|
||||
} else {
|
||||
prop.put("info", "7");
|
||||
prop.putHTML("info_release", releaseFileName);
|
||||
}
|
||||
} else {
|
||||
prop.put("info", "8");
|
||||
}
|
||||
prop.put("info", "5");
|
||||
prop.putHTML("info_release", releaseFileName);
|
||||
} else {
|
||||
prop.put("info", "6");
|
||||
}
|
||||
|
|
|
@ -476,11 +476,13 @@ public final class yacyRelease extends yacyVersion {
|
|||
|
||||
/**
|
||||
* stop yacy and run a batch script, applies a new release and restarts yacy
|
||||
* @param releaseFile
|
||||
* @param releaseFile release file to apply
|
||||
* @return true when release file has been successfully extracted and asynchronous update has been triggered
|
||||
*/
|
||||
public static void deployRelease(final File releaseFile) {
|
||||
public static boolean deployRelease(final File releaseFile) {
|
||||
boolean restartTriggered = false;
|
||||
if (yacyBuildProperties.isPkgManager()) {
|
||||
return;
|
||||
return restartTriggered;
|
||||
}
|
||||
try {
|
||||
final Switchboard sb = Switchboard.getSwitchboard();
|
||||
|
@ -488,7 +490,7 @@ public final class yacyRelease extends yacyVersion {
|
|||
try{
|
||||
tarTools.unTar(tarTools.getInputStream(releaseFile), sb.getDataPath() + "/DATA/RELEASE/".replace("/", File.separator));
|
||||
} catch (final Exception e){
|
||||
ConcurrentLog.severe("UNTAR", "failed", e);
|
||||
throw new IOException("Could not untar release file", e);
|
||||
}
|
||||
String script = null;
|
||||
String scriptFileName = null;
|
||||
|
@ -560,12 +562,14 @@ public final class yacyRelease extends yacyVersion {
|
|||
OS.deployScript(scriptFile, script);
|
||||
ConcurrentLog.info("UPDATE", "wrote update-script to " + scriptFile.getAbsolutePath());
|
||||
OS.execAsynchronous(scriptFile);
|
||||
restartTriggered = true;
|
||||
ConcurrentLog.info("UPDATE", "script is running");
|
||||
sb.setConfig("update.time.deploy", System.currentTimeMillis());
|
||||
sb.terminate(10, "auto-deploy for " + releaseFile.getName());
|
||||
} catch (final IOException e) {
|
||||
ConcurrentLog.severe("UPDATE", "update failed", e);
|
||||
}
|
||||
return restartTriggered;
|
||||
}
|
||||
|
||||
public static void main(final String[] args) {
|
||||
|
|
|
@ -2498,9 +2498,13 @@ public final class Switchboard extends serverSwitch {
|
|||
this.log
|
||||
.info("AUTO-UPDATE: omitting update because download failed (file cannot be found, is too small or signature is bad)");
|
||||
} else {
|
||||
yacyRelease.deployRelease(downloaded);
|
||||
terminate(10, "auto-update to install " + downloaded.getName());
|
||||
this.log.info("AUTO-UPDATE: deploy and restart initiated");
|
||||
if(yacyRelease.deployRelease(downloaded)) {
|
||||
terminate(10, "auto-update to install " + downloaded.getName());
|
||||
this.log.info("AUTO-UPDATE: deploy and restart initiated");
|
||||
} else {
|
||||
this.log
|
||||
.info("AUTO-UPDATE: omitting update because an error occurred while trying to deploy the release.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4032,6 +4036,11 @@ public final class Switchboard extends serverSwitch {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers asynchronous shutdown occurring after a given delay
|
||||
* @param delay delay time in milliseconds
|
||||
* @param reason shutdown reason for log information
|
||||
*/
|
||||
public void terminate(final long delay, final String reason) {
|
||||
if ( delay <= 0 ) {
|
||||
throw new IllegalArgumentException("The shutdown delay must be greater than 0.");
|
||||
|
|
|
@ -28,6 +28,7 @@ package net.yacy.utils;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -39,69 +40,138 @@ import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
|||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Tar archives utilities for YaCy
|
||||
*/
|
||||
public class tarTools {
|
||||
|
||||
public static InputStream getInputStream(final String tarFileName) throws Exception{
|
||||
if (tarFileName.endsWith(".gz")) {
|
||||
try {
|
||||
return new GZIPInputStream(new FileInputStream(new File(tarFileName)));
|
||||
} catch (final IOException e) {
|
||||
|
||||
/**
|
||||
* Convenience method to open a stream on a tar archive file eventually
|
||||
* compressed with gzip.
|
||||
*
|
||||
* @param tarPath
|
||||
* .tar or .tar.gz file path
|
||||
* @return an opened input stream
|
||||
* @throws FileNotFoundException
|
||||
* when the file does not exist, is a directory rather than a
|
||||
* regular file, or for some other reason cannot be opened for
|
||||
* reading.
|
||||
*/
|
||||
public static InputStream getInputStream(final String tarPath) throws FileNotFoundException {
|
||||
if (tarPath.endsWith(".gz")) {
|
||||
try {
|
||||
return new GZIPInputStream(new FileInputStream(new File(tarPath)));
|
||||
} catch (FileNotFoundException e) {
|
||||
/*
|
||||
* FileNotFoundException is is a subClass of IOException but the
|
||||
* following behavior does not apply
|
||||
*/
|
||||
throw e;
|
||||
} catch (final IOException e) {
|
||||
// this might happen if the stream is not in gzip format.
|
||||
// there may be a 'gz' extension, but it may still be a raw tar file
|
||||
// this can be caused by 'one too much gzip-content header' that was attached
|
||||
// by a release file server, so just try to open is as normal stream
|
||||
return new FileInputStream(new File(tarFileName));
|
||||
}
|
||||
return new FileInputStream(new File(tarPath));
|
||||
}
|
||||
}
|
||||
return new FileInputStream(new File(tarFileName));
|
||||
return new FileInputStream(new File(tarPath));
|
||||
}
|
||||
|
||||
public static InputStream getInputStream(final File tarFileName) throws Exception{
|
||||
return getInputStream(tarFileName.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* untar for any archive, overwrites existing data
|
||||
* @param in use getInputStream() for convenience
|
||||
* @param untarDir destination path
|
||||
* @throws Exception (IOException or FileNotFoundException)
|
||||
* Convenience method to open a stream on a tar archive file eventually
|
||||
* compressed with gzip.
|
||||
*
|
||||
* @param tarFile
|
||||
* .tar or .tar.gz file
|
||||
* @return an opened input stream
|
||||
* @throws FileNotFoundException
|
||||
* when the file does not exist, is a directory rather than a
|
||||
* regular file, or for some other reason cannot be opened for
|
||||
* reading.
|
||||
*/
|
||||
public static void unTar(final InputStream in, final String untarDir) throws Exception{
|
||||
public static InputStream getInputStream(final File tarFile) throws Exception {
|
||||
return getInputStream(tarFile.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Untar for any tar archive, overwrites existing data. Closes the
|
||||
* InputStream once terminated.
|
||||
*
|
||||
* @param in
|
||||
* input stream. Must not be null. (use
|
||||
* {@link #getInputStream(String)} for convenience)
|
||||
* @param untarDir
|
||||
* destination path. Must not be null.
|
||||
* @throws IOException
|
||||
* when a read/write error occurred
|
||||
* @throws FileNotFoundException
|
||||
* when the untarDir does not exists
|
||||
* @throws NullPointerException
|
||||
* when a parameter is null
|
||||
*/
|
||||
public static void unTar(final InputStream in, final String untarDir) throws IOException {
|
||||
ConcurrentLog.info("UNTAR", "starting");
|
||||
if(new File(untarDir).exists()){
|
||||
if (new File(untarDir).exists()) {
|
||||
final TarArchiveInputStream tin = new TarArchiveInputStream(in);
|
||||
TarArchiveEntry tarEntry = tin.getNextTarEntry();
|
||||
while(tarEntry != null){
|
||||
final File destPath = new File(untarDir + File.separator + tarEntry.getName());
|
||||
if (!tarEntry.isDirectory()) {
|
||||
new File(destPath.getParent()).mkdirs(); // create missing subdirectories
|
||||
final FileOutputStream fout = new FileOutputStream(destPath);
|
||||
IOUtils.copyLarge(tin,fout,0,tarEntry.getSize());
|
||||
fout.close();
|
||||
} else {
|
||||
destPath.mkdir();
|
||||
try {
|
||||
TarArchiveEntry tarEntry = tin.getNextTarEntry();
|
||||
if (tarEntry == null) {
|
||||
throw new IOException("tar archive is empty or corrupted");
|
||||
}
|
||||
while(tarEntry != null){
|
||||
final File destPath = new File(untarDir + File.separator + tarEntry.getName());
|
||||
if (!tarEntry.isDirectory()) {
|
||||
new File(destPath.getParent()).mkdirs(); // create missing subdirectories
|
||||
final FileOutputStream fout = new FileOutputStream(destPath);
|
||||
IOUtils.copyLarge(tin,fout,0,tarEntry.getSize());
|
||||
fout.close();
|
||||
} else {
|
||||
destPath.mkdir();
|
||||
}
|
||||
tarEntry = tin.getNextTarEntry();
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
tin.close();
|
||||
} catch (IOException ignored) {
|
||||
ConcurrentLog.warn("UNTAR", "InputStream could not be closed");
|
||||
}
|
||||
tarEntry = tin.getNextTarEntry();
|
||||
}
|
||||
tin.close();
|
||||
} else { // untarDir doesn't exist
|
||||
ConcurrentLog.warn("UNTAR", "destination " + untarDir + " doesn't exist.");
|
||||
/* Still have to close the input stream */
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ignored) {
|
||||
ConcurrentLog.warn("UNTAR", "InputStream could not be closed");
|
||||
}
|
||||
throw new FileNotFoundException("Output untar directory not found : " + untarDir);
|
||||
}
|
||||
ConcurrentLog.info("UNTAR", "finished");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Untar a tar archive.
|
||||
* @param args
|
||||
* <ol>
|
||||
* <li>args[0] : source file path</li>
|
||||
* <li>args[1] : destination directory path</li>
|
||||
* </ol>
|
||||
*/
|
||||
public static void main(final String args[]) {
|
||||
// @arg0 source
|
||||
// @arg1 destination
|
||||
if(args.length == 2){
|
||||
try {
|
||||
unTar(getInputStream(args[0]), args[1]);
|
||||
} catch (final Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
} else {
|
||||
System.out.println("usage: <source> <destination>");
|
||||
if (args.length == 2) {
|
||||
try {
|
||||
unTar(getInputStream(args[0]), args[1]);
|
||||
} catch (final Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
} else {
|
||||
System.out.println("usage: <source> <destination>");
|
||||
}
|
||||
} finally {
|
||||
ConcurrentLog.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user