view src/luan/host/Backup.java @ 1321:307e76ccd0d6

generalize separate logging
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 05 Feb 2019 22:36:55 -0700
parents d41997776788
children f41919741100
line wrap: on
line source

package luan.host;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.lucene.index.SnapshotDeletionPolicy;
import org.apache.lucene.index.IndexCommit;
import org.apache.lucene.store.FSDirectory;
import luan.LuanState;
import luan.LuanTable;
import luan.LuanException;
import luan.modules.PackageLuan;
import luan.modules.lucene.LuceneIndex;
import luan.host.Log4j;


public final class Backup {
	private static final Logger logger = LoggerFactory.getLogger(Backup.class);

	private Backup() {}  // never

	private static void mkdir(File dir) {
		if( !dir.mkdirs() )
			throw new RuntimeException("couldn't make "+dir);
	}

	private static void link(File from,File to) throws IOException {
		Files.createLink( to.toPath(), from.toPath() );
	}

	private static void backupNonlocal(File from,File to) throws IOException {
		mkdir(to);
		for( File fromChild : from.listFiles() ) {
			File toChild = new File( to, fromChild.getName() );
			if( fromChild.isDirectory() ) {
				if( !fromChild.getName().equals("local") )
					backupNonlocal( fromChild, toChild );
			} else if( fromChild.isFile() ) {
				link( fromChild, toChild );
			} else {
				throw new RuntimeException(fromChild+" isn't dir or file");
			}
		}
	}

	private static final String getLucenes =
		"local Lucene = require 'luan:lucene/Lucene.luan'\n"
		+"local Table = require 'luan:Table.luan'\n"
		+"return Table.copy(Lucene.instances)\n"
	;

	private static void backupLucene(File from,File to) throws IOException {
		if( !new File(from,"site/init.luan").exists() ) {
			return;
		}
		String fromPath = from.getCanonicalPath() + "/";
		LuanTable luceneInstances;
		LuanState luan = null;
		try {
			if( WebHandler.isServing() ) {
				luceneInstances = (LuanTable)WebHandler.runLuan( from.getName(), getLucenes, "getLucenes" );
			} else {
				luan = new LuanState();
				luan.onClose = new LuanState.OnClose() {
					private final List<Closeable> onClose = new ArrayList<Closeable>();

					public void onClose(Closeable c) {
						onClose.add(c);
					}
				
					public void close() {
						for( Closeable c : onClose ) {
							try {
								c.close();
							} catch(IOException e) {
								logger.error(c.toString(),e);
							}
						}
						onClose.clear();
					}
				};
				WebHandler.initLuan( luan, from.toString(), from.getName(), false );
				PackageLuan.load(luan,"site:/init.luan");
				luceneInstances = (LuanTable)luan.eval(getLucenes);
			}
		} catch(LuanException e) {
			throw new RuntimeException(from.getName(),e);
		}
		for( Map.Entry entry : luceneInstances.rawIterable() ) {
			LuanTable tbl = (LuanTable)entry.getKey();
			LuceneIndex li = (LuceneIndex)tbl.rawGet("java");
			SnapshotDeletionPolicy snapshotDeletionPolicy = li.snapshotDeletionPolicy();
			IndexCommit ic = snapshotDeletionPolicy.snapshot();
			try {
				FSDirectory fsdir = (FSDirectory)ic.getDirectory();
				File dir = fsdir.getDirectory();
				String dirPath = dir.toString();
				if( !dirPath.startsWith(fromPath) )
					throw new RuntimeException(fromPath+" "+dirPath);
				File toDir = new File( to, dirPath.substring(fromPath.length()) );
				mkdir(toDir);
				for( String name : ic.getFileNames() ) {
					link( new File(dir,name), new File(toDir,name) );
				}
			} finally {
				snapshotDeletionPolicy.release(ic);
			}
		}
		if( luan != null )
			luan.onClose.close();
	}

	public static void backup(File sitesDir,File backupDir) throws IOException {
		mkdir(backupDir);
		for( File siteDir : sitesDir.listFiles() ) {
			File to = new File( backupDir, siteDir.getName() );
			backupNonlocal( siteDir, to );
			backupLucene( siteDir, to );
		}
	}

	public static void main(String[] args) throws Exception {
		Log4j.initForConsole();
		WebHandler.allowJavaFileName = args[2];
		backup( new File(args[0]), new File(args[1]) );
		System.exit(0);
	}
}