use of org.jvnet.solaris.libzfs.LibZFS in project hudson-2.x by hudson.
the class ZFSInstaller method migrate.
/**
* Migrates $HUDSON_HOME to a new ZFS file system.
*
* TODO: do this in a separate JVM to elevate the privilege.
*
* @param listener
* Log of migration goes here.
* @param target
* Dataset to move the data to.
* @return
* false if a migration failed.
*/
private static boolean migrate(TaskListener listener, String target) throws IOException, InterruptedException {
PrintStream out = listener.getLogger();
File home = Hudson.getInstance().getRootDir();
// do the migration
LibZFS zfs = new LibZFS();
ZFSFileSystem existing = zfs.getFileSystemByMountPoint(home);
if (existing != null) {
out.println(home + " is already on ZFS. Doing nothing");
return true;
}
File tmpDir = Util.createTempDir();
// mount a new file system to a temporary location
out.println("Opening " + target);
ZFSFileSystem hudson = zfs.open(target, ZFSFileSystem.class);
hudson.setMountPoint(tmpDir);
// mark this file system as "managed by Hudson"
hudson.setProperty("hudson:managed-by", "hudson");
hudson.mount();
// copy all the files
out.println("Copying all existing data files");
if (system(home, listener, "/usr/bin/cp", "-pR", ".", tmpDir.getAbsolutePath()) != 0) {
out.println("Failed to copy " + home + " to " + tmpDir);
return false;
}
// unmount
out.println("Unmounting " + target);
hudson.unmount(MountFlags.MS_FORCE);
// move the original directory to the side
File backup = new File(home.getPath() + ".backup");
out.println("Moving " + home + " to " + backup);
if (backup.exists())
Util.deleteRecursive(backup);
if (!home.renameTo(backup)) {
out.println("Failed to move your current data " + home + " out of the way");
}
// update the mount point
out.println("Creating a new mount point at " + home);
if (!home.mkdir())
throw new IOException("Failed to create mount point " + home);
out.println("Mounting " + target);
hudson.setMountPoint(home);
hudson.mount();
out.println("Sharing " + target);
try {
hudson.setProperty("sharesmb", "on");
hudson.setProperty("sharenfs", "on");
hudson.share();
} catch (ZFSException e) {
listener.error("Failed to share the file systems: " + e.getCode());
}
// delete back up
out.println("Deleting " + backup);
if (system(new File("/"), listener, "/usr/bin/rm", "-rf", backup.getAbsolutePath()) != 0) {
out.println("Failed to delete " + backup.getAbsolutePath());
return false;
}
out.println("Migration completed");
return true;
}
use of org.jvnet.solaris.libzfs.LibZFS in project hudson-2.x by hudson.
the class ZFSInstaller method shouldBeActive.
private boolean shouldBeActive() {
if (!System.getProperty("os.name").equals("SunOS") || disabled)
// on systems that don't have ZFS, we don't need this monitor
return false;
try {
LibZFS zfs = new LibZFS();
List<ZFSFileSystem> roots = zfs.roots();
if (roots.isEmpty())
// no active ZFS pool
return false;
// if we don't run on a ZFS file system, activate
ZFSFileSystem hudsonZfs = zfs.getFileSystemByMountPoint(Hudson.getInstance().getRootDir());
if (hudsonZfs != null)
// already on ZFS
return false;
// decide what file system we'll create
ZFSFileSystem pool = roots.get(0);
prospectiveZfsFileSystemName = computeHudsonFileSystemName(zfs, pool);
return true;
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Failed to detect whether Hudson is on ZFS", e);
return false;
} catch (LinkageError e) {
LOGGER.info("No ZFS available. If you believe this is an error, increase the logging level to get the stack trace");
LOGGER.log(Level.FINE, "Stack trace of failed ZFS load", e);
return false;
}
}
use of org.jvnet.solaris.libzfs.LibZFS in project hudson-2.x by hudson.
the class ZFSInstaller method createZfsFileSystem.
/**
* Creates a ZFS file system to migrate the data to.
*
* <p>
* This has to be done while we still have an interactive access with the user, since it involves the password.
*
* <p>
* An exception will be thrown if the operation fails. A normal completion means a success.
*
* @return
* The ZFS dataset name to migrate the data to.
*/
private String createZfsFileSystem(final TaskListener listener, String rootUsername, String rootPassword) throws IOException, InterruptedException, ZFSException {
// capture the UID that Hudson runs under
// so that we can allow this user to do everything on this new partition
final int uid = LIBC.geteuid();
final int gid = LIBC.getegid();
passwd pwd = LIBC.getpwuid(uid);
if (pwd == null)
throw new IOException("Failed to obtain the current user information for " + uid);
final String userName = pwd.pw_name;
final File home = Hudson.getInstance().getRootDir();
// return true indicating a success
return SU.execute(listener, rootUsername, rootPassword, new Callable<String, IOException>() {
public String call() throws IOException {
PrintStream out = listener.getLogger();
LibZFS zfs = new LibZFS();
ZFSFileSystem existing = zfs.getFileSystemByMountPoint(home);
if (existing != null) {
// no need for migration
out.println(home + " is already on ZFS. Doing nothing");
return existing.getName();
}
String name = computeHudsonFileSystemName(zfs, zfs.roots().get(0));
out.println("Creating " + name);
ZFSFileSystem hudson = zfs.create(name, ZFSFileSystem.class);
// mount temporarily to set the owner right
File dir = Util.createTempDir();
hudson.setMountPoint(dir);
hudson.mount();
if (LIBC.chown(dir.getPath(), uid, gid) != 0)
throw new IOException("Failed to chown " + dir);
hudson.unmount();
try {
// mark this file system as "managed by Hudson"
hudson.setProperty("hudson:managed-by", "hudson");
ACLBuilder acl = new ACLBuilder();
acl.user(userName).withEverything();
hudson.allow(acl);
} catch (ZFSException e) {
// revert the file system creation
try {
hudson.destory();
} catch (Exception _) {
// but ignore the error and let the original error thrown
}
throw e;
}
return hudson.getName();
}
});
}
Aggregations