/*
* The MIT License
*
* Copyright (c) 2009-2010, Vincent Sellier, Manufacture Fran�aise des Pneumatiques Michelin, Romain Seguy
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jvnet.hudson.plugins.backup;
import hudson.Extension;
import hudson.model.Hudson;
import hudson.model.ManagementLink;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jvnet.hudson.plugins.backup.utils.BackupPluginTask;
import org.jvnet.hudson.plugins.backup.utils.BackupTask;
import org.jvnet.hudson.plugins.backup.utils.LastModifiedFileComparator;
import org.jvnet.hudson.plugins.backup.utils.RestoreTask;
import org.jvnet.hudson.plugins.backup.utils.compress.CompressionMethodEnum;
import org.jvnet.hudson.plugins.backup.utils.filename.FileNameManager;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.framework.io.LargeText;
@Extension
public class BackupLink extends ManagementLink {
private final static Logger LOGGER = Logger.getLogger(BackupLink.class
.getName());
private BackupPluginTask task;
private Boolean backupRunning = Boolean.FALSE;
public BackupConfig getConfiguration() {
return BackupPluginImpl.getInstance().getConfiguration();
}
@Override
public String getIconFileName() {
return "/plugin/backup/images/backup-48x48.png";
}
@Override
public String getUrlName() {
return "backup";
}
public String getDisplayName() {
return Messages.display_name();
}
@Override
public String getDescription() {
return Messages.description();
}
public List<String> getExtensions() {
List<String> extensions = new ArrayList();
for (CompressionMethodEnum method : CompressionMethodEnum.values()) {
if(method.isSupportedByPlatform()) { // HUDSON-5305
extensions.add(method.getCode());
}
}
return extensions;
}
public void doLaunchBackup(StaplerRequest req, StaplerResponse rsp) throws IOException {
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
if (task != null) {
if (!task.isFinished()) {
// redirect to observation page
rsp.sendRedirect("backup");
return;
}
}
BackupConfig configuration = getConfiguration();
String fileNameTemplate = configuration.getTargetDirectory() + File.separator + configuration.getFileNameTemplate();
String fileName = new FileNameManager().getFileName(fileNameTemplate, configuration);
LOGGER.info("backup file name = " + fileName + " (generated from template :" + fileNameTemplate + ")");
// configuring backup
task = new BackupTask(configuration, getRootDirectory(), fileName, getBackupLogFile().getAbsolutePath());
// Launching the task
Thread thread = Executors.defaultThreadFactory().newThread(task);
thread.start();
// redirect to observation page
rsp.sendRedirect("backup");
}
public void doRestoreFile(StaplerRequest res, StaplerResponse rsp,
@QueryParameter("file") String backupFile)
throws IOException {
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
BackupConfig configuration = getConfiguration();
String path = configuration.getTargetDirectory();
String filePath = path + File.separator + backupFile;
LOGGER.log(Level.INFO, "Selected file : {0}", backupFile);
task = new RestoreTask(configuration, Hudson.getInstance().getRootDir().getAbsolutePath(),
filePath, getRestoreLogFile().getAbsolutePath(), res.getServletContext());
// Launching the restoration
Thread thread = Executors.defaultThreadFactory().newThread(task);
thread.start();
// redirect to observation page
rsp.sendRedirect("restore");
}
/**
* search into the declared backup directory for backup archives
*/
public List<File> getFileList() throws IOException {
LOGGER.log(Level.INFO, "Listing files of {0}", getConfiguration().getTargetDirectory());
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
BackupConfig configuration = getConfiguration();
File backupDirectory = new File(configuration.getTargetDirectory());
File[] backupFiles = backupDirectory.listFiles();
List fileList;
if (backupFiles == null) {
fileList = new ArrayList();
} else {
fileList = Arrays.asList(backupFiles);
}
// Sort file list
Collections.sort(fileList, new LastModifiedFileComparator());
return fileList;
}
public void doSaveSettings(StaplerRequest res, StaplerResponse rsp,
@QueryParameter("backupDirectoryPath") String backupPath,
@QueryParameter("archive_format") String format,
@QueryParameter("customExclusionsString") String customExclusionsString,
@QueryParameter("verbose") boolean verbose,
@QueryParameter("fileNameTemplate") String fileNameTemplate,
@QueryParameter("keepWorkspaces") boolean keepWorkspaces,
@QueryParameter("keepFingerprints") boolean keepFingerprints,
@QueryParameter("keepBuilds") boolean keepBuilds,
@QueryParameter("keepArchives") boolean keepArchives,
@QueryParameter("jobIncludes") String jobIncludes,
@QueryParameter("jobExcludes") String jobExcludes,
@QueryParameter("caseSensitive") boolean caseSensitive)
throws IOException {
LOGGER.info("BackupLink.doSaveSetting");
Hudson.getInstance().checkPermission(Hudson.ADMINISTER);
BackupConfig configuration = new BackupConfig();
configuration.setTargetDirectory(backupPath);
configuration.setVerbose(verbose);
configuration.setFileNameTemplate(fileNameTemplate);
CompressionMethodEnum archiveType = CompressionMethodEnum.getFromCode(format);
configuration.setArchiveType(archiveType);
configuration.setCustomExclusionsString(customExclusionsString);
configuration.setKeepWorkspaces(keepWorkspaces);
configuration.setKeepFingerprints(keepFingerprints);
configuration.setKeepBuilds(keepBuilds);
configuration.setKeepArchives(keepArchives);
configuration.setJobIncludes(jobIncludes);
configuration.setJobExcludes(jobExcludes);
configuration.setCaseSensitive(caseSensitive);
BackupPluginImpl.getInstance().setConfiguration(configuration);
LOGGER.info("Backup configuration saved.");
rsp.sendRedirect(res.getContextPath() + "/backup");
}
public void doProgressiveBackupLog(StaplerRequest req, StaplerResponse rsp)
throws IOException {
doProgressiveLog(req, rsp, getBackupLogFile());
}
/**
* Show restore status.
* When restore is done, reload config from disk via {@link Hudson#doReload(StaplerRequest, StaplerResponse)}
*/
public void doProgressiveRestoreLog(StaplerRequest req, StaplerResponse rsp)
throws IOException {
doProgressiveLog(req, rsp, getRestoreLogFile());
}
private void doProgressiveLog(StaplerRequest req, StaplerResponse rsp, File file)
throws IOException {
boolean backupFinished = task.isFinished();
new LargeText(file, backupFinished).doProgressText(
req, rsp);
if (backupFinished) {
task = null;
}
}
public String getRootDirectory() {
return Hudson.getInstance().getRootDir().getAbsolutePath();
}
private File getBackupLogFile() {
return new File(Hudson.getInstance().getRootDir().getAbsolutePath(),
"/backup.log");
}
private File getRestoreLogFile() {
return new File(System.getProperty("java.io.tmpdir"), "/hudson_restore.log");
}
}