init: Don't write files unless changed

If the configuration file hasn't been modified by the init program,
don't attempt to write it out to disk.  Do the same for gerrit.sh
and also the mail templates.

Change-Id: I7eca3f654a7504b990da8a386e6a6d568caa9ac8
Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
Shawn O. Pearce
2010-08-28 17:56:57 -07:00
parent f4363c43cb
commit 9b01cefd53
2 changed files with 99 additions and 37 deletions

View File

@@ -14,7 +14,6 @@
package com.google.gerrit.pgm.init;
import static com.google.gerrit.pgm.init.InitUtil.copy;
import static com.google.gerrit.pgm.init.InitUtil.die;
import static com.google.gerrit.pgm.init.InitUtil.username;
@@ -24,10 +23,14 @@ import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.storage.file.LockFile;
import org.eclipse.jgit.util.FS;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
/** Initialize the {@code container} configuration section. */
@Singleton
@@ -84,7 +87,39 @@ class InitContainer implements InitStep {
System.err.format("Copying gerrit.war to %s", siteWar.getPath());
System.err.println();
}
copy(siteWar, new FileInputStream(myWar));
FileInputStream in = new FileInputStream(myWar);
try {
siteWar.getParentFile().mkdirs();
LockFile lf = new LockFile(siteWar, FS.DETECTED);
if (!lf.lock()) {
throw new IOException("Cannot lock " + siteWar);
}
try {
final OutputStream out = lf.getOutputStream();
try {
final byte[] tmp = new byte[4096];
for (;;) {
int n = in.read(tmp);
if (n < 0) {
break;
}
out.write(tmp, 0, n);
}
} finally {
out.close();
}
if (!lf.commit()) {
throw new IOException("Cannot commit " + siteWar);
}
} finally {
lf.unlock();
}
} finally {
in.close();
}
}
}
}

View File

@@ -20,6 +20,7 @@ import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.storage.file.LockFile;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.SystemReader;
import java.io.File;
@@ -31,6 +32,8 @@ import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Arrays;
/** Utility functions to help initialize a site. */
class InitUtil {
@@ -43,27 +46,43 @@ class InitUtil {
}
static void savePublic(final FileBasedConfig sec) throws IOException {
sec.save();
if (modified(sec)) {
sec.save();
}
}
static void saveSecure(final FileBasedConfig sec) throws IOException {
final byte[] out = Constants.encode(sec.toText());
final File path = sec.getFile();
final LockFile lf = new LockFile(path, FS.DETECTED);
if (!lf.lock()) {
throw new IOException("Cannot lock " + path);
}
try {
chmod(0600, new File(path.getParentFile(), path.getName() + ".lock"));
lf.write(out);
if (!lf.commit()) {
throw new IOException("Cannot commit write to " + path);
if (modified(sec)) {
final byte[] out = Constants.encode(sec.toText());
final File path = sec.getFile();
final LockFile lf = new LockFile(path, FS.DETECTED);
if (!lf.lock()) {
throw new IOException("Cannot lock " + path);
}
try {
chmod(0600, new File(path.getParentFile(), path.getName() + ".lock"));
lf.write(out);
if (!lf.commit()) {
throw new IOException("Cannot commit write to " + path);
}
} finally {
lf.unlock();
}
} finally {
lf.unlock();
}
}
private static boolean modified(FileBasedConfig cfg) throws IOException {
byte[] curVers;
try {
curVers = IO.readFully(cfg.getFile());
} catch (FileNotFoundException notFound) {
return true;
}
byte[] newVers = Constants.encode(cfg.toText());
return !Arrays.equals(curVers, newVers);
}
static void mkdir(final File path) {
if (!path.isDirectory() && !path.mkdir()) {
throw die("Cannot make directory " + path);
@@ -145,7 +164,8 @@ class InitUtil {
final String name) throws IOException {
final InputStream in = open(sibling, name);
if (in != null) {
copy(dst, in);
ByteBuffer buf = IO.readWholeStream(in, 8192);
copy(dst, buf);
}
}
@@ -166,34 +186,41 @@ class InitUtil {
return in;
}
static void copy(final File dst, final InputStream in)
static void copy(final File dst, final ByteBuffer buf)
throws FileNotFoundException, IOException {
// If the file already has the content we want to put there,
// don't attempt to overwrite the file.
//
try {
dst.getParentFile().mkdirs();
LockFile lf = new LockFile(dst, FS.DETECTED);
if (!lf.lock()) {
throw new IOException("Cannot lock " + dst);
if (buf.equals(ByteBuffer.wrap(IO.readFully(dst)))) {
return;
}
try {
} catch (FileNotFoundException notFound) {
// Fall through and write the file.
}
final OutputStream out = lf.getOutputStream();
try {
final byte[] buf = new byte[4096];
int n;
while (0 < (n = in.read(buf))) {
out.write(buf, 0, n);
}
} finally {
out.close();
}
if (!lf.commit()) {
throw new IOException("Cannot commit " + dst);
dst.getParentFile().mkdirs();
LockFile lf = new LockFile(dst, FS.DETECTED);
if (!lf.lock()) {
throw new IOException("Cannot lock " + dst);
}
try {
final OutputStream out = lf.getOutputStream();
try {
final byte[] tmp = new byte[4096];
while (0 < buf.remaining()) {
int n = Math.min(buf.remaining(), tmp.length);
buf.get(tmp, 0, n);
out.write(tmp, 0, n);
}
} finally {
lf.unlock();
out.close();
}
if (!lf.commit()) {
throw new IOException("Cannot commit " + dst);
}
} finally {
in.close();
lf.unlock();
}
}