// ConfigUpdate_p.java
// (C) 2007 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany
// first published 11.07.2007 on http://yacy.net
//
// This is a part of YaCy, a peer-to-peer based web search engine
//
// $LastChangedDate$
// $LastChangedRevision$
// $LastChangedBy$
//
// LICENSE
//
// This program 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 program 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 program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import java.io.File ;
import java.io.IOException ;
import java.util.ArrayList ;
import java.util.Date ;
import java.util.NavigableSet ;
import java.util.Set ;
import java.util.TreeSet ;
import net.yacy.cora.document.id.DigestURL ;
import net.yacy.cora.protocol.RequestHeader ;
import net.yacy.cora.util.ConcurrentLog ;
import net.yacy.data.TransactionManager ;
import net.yacy.kelondro.util.FileUtils ;
import net.yacy.kelondro.util.OS ;
import net.yacy.peers.operation.yacyBuildProperties ;
import net.yacy.peers.operation.yacyRelease ;
import net.yacy.peers.operation.yacyVersion ;
import net.yacy.search.Switchboard ;
import net.yacy.server.serverObjects ;
import net.yacy.server.serverSwitch ;
public class ConfigUpdate_p {
public static serverObjects respond ( final RequestHeader header , final serverObjects post , final serverSwitch env ) {
// return variable that accumulates replacements
final serverObjects prop = new serverObjects ( ) ;
final Switchboard sb = ( Switchboard ) env ;
// set if this should be visible
if ( yacyBuildProperties . isPkgManager ( ) ) {
prop . put ( "candeploy" , "2" ) ;
return prop ;
} else if ( OS . isWindows & & sb . appPath . toString ( ) . indexOf ( "Program Files" ) > - 1 ) {
prop . put ( "candeploy" , "3" ) ;
return prop ;
} else if ( OS . canExecUnix | | OS . isWindows ) {
// we can deploy a new system with (i.e.)
// cd DATA/RELEASE;tar xfz $1;cp -Rf yacy/* ../../;rm -Rf yacy
prop . put ( "candeploy" , "1" ) ;
} else {
prop . put ( "candeploy" , "0" ) ;
}
prop . put ( "candeploy_configCommit" , "0" ) ;
prop . put ( "candeploy_autoUpdate" , "0" ) ;
prop . put ( "candeploy_downloadsAvailable" , "0" ) ;
prop . put ( "candeploy_downloadError" , "0" ) ;
if ( post ! = null ) {
if ( post . containsKey ( "downloadRelease" ) ) {
// download a release
final String release = post . get ( "releasedownload" , "" ) ;
if ( ! release . isEmpty ( ) ) {
try {
yacyRelease versionToDownload = new yacyRelease ( new DigestURL ( release ) ) ;
// replace this version with version which contains public key
final yacyRelease . DevAndMainVersions allReleases = yacyRelease . allReleases ( false , false ) ;
final Set < yacyRelease > mostReleases = versionToDownload . isMainRelease ( ) ? allReleases . main : allReleases . dev ;
for ( final yacyRelease rel : mostReleases ) {
if ( rel . equals ( versionToDownload ) ) {
versionToDownload = rel ;
break ;
}
}
File downloadedRelease = versionToDownload . downloadRelease ( ) ;
if ( downloadedRelease = = null ) {
prop . put ( "candeploy_downloadError" , "1" ) ;
prop . putHTML ( "candeploy_downloadError_releasedownload" , release ) ;
}
} catch ( final IOException e ) {
ConcurrentLog . logException ( e ) ;
prop . put ( "candeploy_downloadError" , "1" ) ;
prop . putHTML ( "candeploy_downloadError_releasedownload" , release ) ;
}
}
}
if ( post . containsKey ( "checkRelease" ) ) {
yacyRelease . allReleases ( true , false ) ;
}
if ( post . containsKey ( "deleteRelease" ) ) {
final String release = post . get ( "releaseinstall" , "" ) ;
if ( ! release . isEmpty ( ) ) {
try {
// only delete files from RELEASE directory
if ( FileUtils . isInDirectory ( new File ( sb . releasePath , release ) , sb . releasePath ) ) {
FileUtils . deletedelete ( new File ( sb . releasePath , release ) ) ;
FileUtils . deletedelete ( new File ( sb . releasePath , release + ".sig" ) ) ;
} else {
sb . getLog ( ) . severe ( "AUTO-UPDATE: could not delete " + release + ": file not in release directory." ) ;
}
} catch ( final NullPointerException e ) {
sb . getLog ( ) . severe ( "AUTO-UPDATE: could not delete release " + release + ": " + e . getMessage ( ) ) ;
}
}
}
if ( post . containsKey ( "autoUpdate" ) ) {
final yacyRelease updateVersion = yacyRelease . rulebasedUpdateInfo ( true ) ;
if ( updateVersion = = null ) {
prop . put ( "candeploy_autoUpdate" , "2" ) ; // no more recent release found
} else {
// there is a version that is more recent. Load it and re-start with it
sb . getLog ( ) . info ( "AUTO-UPDATE: downloading more recent release " + updateVersion . getUrl ( ) ) ;
final File downloaded = updateVersion . downloadRelease ( ) ;
prop . putHTML ( "candeploy_autoUpdate_downloadedRelease" , updateVersion . getName ( ) ) ;
final boolean devenvironment = new File ( sb . getAppPath ( ) , ".git" ) . exists ( ) ;
if ( devenvironment ) {
sb . getLog ( ) . info ( "AUTO-UPDATE: omitting update because this is a development environment" ) ;
prop . put ( "candeploy_autoUpdate" , "3" ) ;
} else if ( ( downloaded = = null ) | | ( ! downloaded . exists ( ) ) | | ( downloaded . length ( ) = = 0 ) ) {
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 {
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" ) ;
}
}
}
}
if ( post . containsKey ( "configSubmit" ) ) {
prop . put ( "candeploy_configCommit" , "1" ) ;
sb . setConfig ( "update.process" , ( "manual" . equals ( post . get ( "updateMode" , "manual" ) ) ) ? "manual" : "auto" ) ;
sb . setConfig ( "update.cycle" , Math . max ( 12 , post . getLong ( "cycle" , 168 ) ) ) ;
sb . setConfig ( "update.blacklist" , post . get ( "blacklist" , "" ) ) ;
sb . setConfig ( "update.concept" , ( "any" . equals ( post . get ( "releaseType" , "any" ) ) ) ? "any" : "main" ) ;
sb . setConfig ( "update.onlySignedFiles" , ( post . getBoolean ( "onlySignedFiles" ) ) ? "1" : "0" ) ;
}
}
// version information
final String versionstring = yacyBuildProperties . getVersion ( ) + "/" + yacyBuildProperties . getSVNRevision ( ) ;
prop . putHTML ( "candeploy_versionpp" , versionstring ) ;
final boolean devenvironment = new File ( sb . getAppPath ( ) , ".git" ) . exists ( ) ;
float thisVersion = Float . parseFloat ( yacyBuildProperties . getVersion ( ) ) ;
// cut off the SVN Rev in the Version
try {
thisVersion = ( float ) ( Math . round ( thisVersion * 1000.0 ) / 1000.0 ) ;
} catch ( final NumberFormatException e ) { }
// list downloaded releases
final File [ ] downloadedFiles = sb . releasePath . listFiles ( ) ;
// list can be null if RELEASE directory has been deleted manually
final int downloadedFilesNum = ( downloadedFiles = = null ) ? 0 : downloadedFiles . length ;
prop . put ( "candeploy_deployenabled" , ( downloadedFilesNum = = 0 ) ? "0" : ( ( devenvironment ) ? "1" : "2" ) ) ; // prevent that a developer-version is over-deployed
final NavigableSet < yacyRelease > downloadedReleases = new TreeSet < yacyRelease > ( ) ;
for ( final File downloaded : downloadedFiles ) {
try {
final yacyRelease release = new yacyRelease ( downloaded ) ;
downloadedReleases . add ( release ) ;
} catch ( final RuntimeException e ) {
// not a valid release
// can be also a restart- or deploy-file
final File invalid = downloaded ;
if ( ! ( invalid . getName ( ) . endsWith ( ".bat" ) | | invalid . getName ( ) . endsWith ( ".sh" ) | | invalid . getName ( ) . endsWith ( ".sig" ) ) ) { // Windows & Linux don't like deleted scripts while execution!
invalid . deleteOnExit ( ) ;
}
}
}
// latest downloaded release
final yacyVersion dflt = ( downloadedReleases . isEmpty ( ) ) ? null : downloadedReleases . last ( ) ;
// check if there are any downloaded releases and if there are enable the update buttons
prop . put ( "candeploy_downloadsAvailable" , ( downloadedReleases . isEmpty ( ) ) ? "0" : "1" ) ;
prop . put ( "candeploy_deployenabled_buttonsActive" , ( downloadedReleases . isEmpty ( ) | | devenvironment ) ? "0" : "1" ) ;
/* Acquire a transaction token for the update operation */
prop . put ( "candeploy_deployenabled_" + TransactionManager . TRANSACTION_TOKEN_PARAM , TransactionManager . getTransactionToken ( header , "/Steering.html" ) ) ;
int relcount = 0 ;
for ( final yacyRelease release : downloadedReleases ) {
prop . put ( "candeploy_downloadedreleases_" + relcount + "_name" , ( ( release . isMainRelease ( ) ) ? "main" : "dev" ) + " " + release . getReleaseNr ( ) + "/" + release . getSvn ( ) ) ;
prop . put ( "candeploy_downloadedreleases_" + relcount + "_signature" , ( release . getSignatureFile ( ) . exists ( ) ? "1" : "0" ) ) ;
prop . putHTML ( "candeploy_downloadedreleases_" + relcount + "_file" , release . getName ( ) ) ;
prop . put ( "candeploy_downloadedreleases_" + relcount + "_selected" , ( release = = dflt ) ? "1" : "0" ) ;
relcount + + ;
}
prop . put ( "candeploy_downloadedreleases" , relcount ) ;
// list remotely available releases
final yacyRelease . DevAndMainVersions releasess = yacyRelease . allReleases ( false , false ) ;
relcount = 0 ;
final ArrayList < yacyRelease > rlist = new ArrayList < yacyRelease > ( ) ;
final Set < yacyRelease > remoteDevReleases = releasess . dev ;
remoteDevReleases . removeAll ( downloadedReleases ) ;
for ( final yacyRelease release : remoteDevReleases ) {
rlist . add ( release ) ;
}
final Set < yacyRelease > remoteMainReleases = releasess . main ;
remoteMainReleases . removeAll ( downloadedReleases ) ;
for ( final yacyRelease release : remoteMainReleases ) {
rlist . add ( release ) ;
}
yacyRelease release ;
for ( int i = rlist . size ( ) - 1 ; i > = 0 ; i - - ) {
release = rlist . get ( i ) ;
prop . put ( "candeploy_availreleases_" + relcount + "_name" , ( ( release . isMainRelease ( ) ) ? "main" : "dev" ) + " " + release . getReleaseNr ( ) + "/" + release . getSvn ( ) ) ;
prop . put ( "candeploy_availreleases_" + relcount + "_url" , release . getUrl ( ) . toNormalform ( false ) ) ;
prop . put ( "candeploy_availreleases_" + relcount + "_signatures" , ( release . getPublicKey ( ) ! = null ? "1" : "0" ) ) ;
prop . put ( "candeploy_availreleases_" + relcount + "_selected" , ( relcount = = 0 ) ? "1" : "0" ) ;
relcount + + ;
}
prop . put ( "candeploy_availreleases" , relcount ) ;
// properties for automated system update
prop . put ( "candeploy_manualUpdateChecked" , ( "manual" . equals ( sb . getConfig ( "update.process" , "manual" ) ) ) ? "1" : "0" ) ;
prop . put ( "candeploy_autoUpdateChecked" , ( "auto" . equals ( sb . getConfig ( "update.process" , "manual" ) ) ) ? "1" : "0" ) ;
prop . put ( "candeploy_cycle" , sb . getConfigLong ( "update.cycle" , 168 ) ) ;
prop . putHTML ( "candeploy_blacklist" , sb . getConfig ( "update.blacklist" , "" ) ) ;
prop . put ( "candeploy_releaseTypeMainChecked" , ( "any" . equals ( sb . getConfig ( "update.concept" , "any" ) ) ) ? "0" : "1" ) ;
prop . put ( "candeploy_releaseTypeAnyChecked" , ( "any" . equals ( sb . getConfig ( "update.concept" , "any" ) ) ) ? "1" : "0" ) ;
prop . put ( "candeploy_lastlookup" , ( sb . getConfigLong ( "update.time.lookup" , 0 ) = = 0 ) ? "0" : "1" ) ;
prop . put ( "candeploy_lastlookup_time" , new Date ( sb . getConfigLong ( "update.time.lookup" , 0 ) ) . toString ( ) ) ;
prop . put ( "candeploy_lastdownload" , ( sb . getConfigLong ( "update.time.download" , 0 ) = = 0 ) ? "0" : "1" ) ;
prop . put ( "candeploy_lastdownload_time" , new Date ( sb . getConfigLong ( "update.time.download" , 0 ) ) . toString ( ) ) ;
prop . put ( "candeploy_lastdeploy" , ( sb . getConfigLong ( "update.time.deploy" , 0 ) = = 0 ) ? "0" : "1" ) ;
prop . put ( "candeploy_lastdeploy_time" , new Date ( sb . getConfigLong ( "update.time.deploy" , 0 ) ) . toString ( ) ) ;
prop . put ( "candeploy_onlySignedFiles" , ( "1" . equals ( sb . getConfig ( "update.onlySignedFiles" , "1" ) ) ) ? "1" : "0" ) ;
/ *
if ( ( adminaccess ) & & ( yacyVersion . latestRelease > = ( thisVersion + 0.01 ) ) ) { // only new Versions(not new SVN)
if ( ( yacyVersion . latestMainRelease ! = null ) | |
( yacyVersion . latestDevRelease ! = null ) ) {
prop . put ( "hintVersionDownload" , 1 ) ;
} else if ( ( post ! = null ) & & ( post . containsKey ( "aquirerelease" ) ) ) {
yacyVersion . aquireLatestReleaseInfo ( ) ;
prop . put ( "hintVersionDownload" , 1 ) ;
} else {
prop . put ( "hintVersionAvailable" , 1 ) ;
}
}
prop . put ( "hintVersionAvailable" , 1 ) ; // for testing
prop . putASIS ( "hintVersionDownload_versionResMain" , ( yacyVersion . latestMainRelease = = null ) ? "-" : yacyVersion . latestMainRelease . toAnchor ( ) ) ;
prop . putASIS ( "hintVersionDownload_versionResDev" , ( yacyVersion . latestDevRelease = = null ) ? "-" : yacyVersion . latestDevRelease . toAnchor ( ) ) ;
prop . put ( "hintVersionAvailable_latestVersion" , Float . toString ( yacyVersion . latestRelease ) ) ;
* /
return prop ;
}
}