view src/luan/host/Backup.java @ 1187:83c8a5a47f70

fixes for luanhost
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 22 Feb 2018 18:38:45 -0700
parents 94cf2576a922
children d41997776788
line wrap: on
line source

package luan.host;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Map;
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();
				WebHandler.initLuan( luan, from.toString(), from.getName() );
				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.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);
	}
}