blob: 8a1dd5c36a78d6b929722f34f643b5ca93f72af7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2018 Red Hat Inc. and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat - Initial Contribution
*******************************************************************************/
package org.eclipse.linuxtools.internal.docker.ui.commands;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.linuxtools.docker.core.DockerException;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerContainer;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.linuxtools.docker.ui.wizards.ImageSearch;
import org.eclipse.linuxtools.internal.docker.core.DockerConnection;
import org.eclipse.linuxtools.internal.docker.ui.wizards.ContainerCopyTo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;
/**
* Command handler that opens the {@link ImageSearch} wizard and pulls the
* selected image in background on completion.
*
*/
public class CopyToContainerCommandHandler extends AbstractHandler {
private static final String ERROR_COPYING_TO_CONTAINER_NO_CONNECTION = "command.copytocontainer.failure.no_connection"; //$NON-NLS-1$
private static final String MISSING_CONNECTION = "missing_connection"; //$NON-NLS-1$
private static final String ERROR_COPYING_TO_CONTAINER = "command.copytocontainer.error.msg"; //$NON-NLS-1$
private static final String COPY_TO_CONTAINER_JOB_TASK = "command.copytocontainer.job.task"; //$NON-NLS-1$
private static final String COPY_TO_CONTAINER_JOB_TITLE = "command.copytocontainer.job.title"; //$NON-NLS-1$
private static final String COPY_TO_CONTAINER_JOB_SUBTASK = "command.copytocontainer.job.subtask"; //$NON-NLS-1$
@Override
public Object execute(final ExecutionEvent event) {
final IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
final IDockerConnection connection = CommandUtils
.getCurrentConnection(activePart);
final List<IDockerContainer> selectedContainers = CommandUtils
.getSelectedContainers(activePart);
if (selectedContainers.size() != 1) {
return null;
}
final IDockerContainer container = selectedContainers.get(0);
if (connection == null) {
MessageDialog.openError(
PlatformUI.getWorkbench().getActiveWorkbenchWindow()
.getShell(),
CommandMessages.getString(MISSING_CONNECTION),
CommandMessages
.getString(
ERROR_COPYING_TO_CONTAINER_NO_CONNECTION));
} else {
final ContainerCopyTo wizard = new ContainerCopyTo(connection,
container);
final boolean copyToContainer = CommandUtils.openWizard(wizard,
HandlerUtil.getActiveShell(event));
if (copyToContainer) {
performCopyToContainer(connection, container,
wizard.getTarget(), wizard.getSources());
}
}
return null;
}
private void performCopyToContainer(final IDockerConnection connection,
final IDockerContainer container, final String target,
final List<Object> files) {
final Job copyToContainerJob = new Job(
CommandMessages.getFormattedString(
COPY_TO_CONTAINER_JOB_TITLE, container.name())) {
@Override
protected IStatus run(final IProgressMonitor monitor) {
monitor.beginTask(
CommandMessages.getString(COPY_TO_CONTAINER_JOB_TASK),
files.size() + 1);
java.nio.file.Path tmpDir = null;
try (Closeable token = ((DockerConnection) connection)
.getOperationToken()) {
for (Object proxy : files) {
File file = (File) proxy;
if (monitor.isCanceled()) {
monitor.done();
return Status.CANCEL_STATUS;
}
try {
monitor.setTaskName(
CommandMessages.getFormattedString(
COPY_TO_CONTAINER_JOB_SUBTASK,
proxy.toString()));
monitor.worked(1);
// we can only copy from a directory so copy the
// files to a temporary directory
if (tmpDir == null) {
tmpDir = Files.createTempDirectory(
Activator.PLUGIN_ID);
}
if (file.isDirectory()) {
java.nio.file.Path sourcePath = FileSystems
.getDefault()
.getPath(file.getAbsolutePath());
final java.nio.file.Path target = tmpDir
.resolve(sourcePath.getFileName());
Files.createDirectory(target);
Files.walkFileTree(sourcePath,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(
final Path dir,
final BasicFileAttributes attrs)
throws IOException {
java.nio.file.Path targetPath = target
.resolve(sourcePath
.relativize(
dir));
Files.createDirectories(
targetPath);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(
final Path file,
final BasicFileAttributes attrs)
throws IOException {
monitor.setTaskName(
CommandMessages
.getFormattedString(
COPY_TO_CONTAINER_JOB_SUBTASK,
file.toString()));
Files.copy(file, target.resolve(
sourcePath.relativize(
file)));
return FileVisitResult.CONTINUE;
}
});
} else {
monitor.worked(1);
java.nio.file.Path sourcePath = FileSystems
.getDefault()
.getPath(file.getAbsolutePath());
java.nio.file.Path targetPath = tmpDir
.resolve(sourcePath.getFileName());
Files.copy(sourcePath,
targetPath,
StandardCopyOption.REPLACE_EXISTING);
}
} catch (final IOException e) {
Display.getDefault()
.syncExec(() -> MessageDialog.openError(
PlatformUI.getWorkbench()
.getActiveWorkbenchWindow()
.getShell(),
CommandMessages.getFormattedString(
ERROR_COPYING_TO_CONTAINER,
proxy.toString(),
container.name()),
e.getMessage()));
}
}
// copy any individual files picked to Container
// via the temporary directory
try {
((DockerConnection) connection).copyToContainer(
token, tmpDir.toString(), container.id(),
target);
deleteTmpDir(tmpDir);
} catch (final DockerException | IOException e) {
Display.getDefault()
.syncExec(() -> MessageDialog.openError(
PlatformUI.getWorkbench()
.getActiveWorkbenchWindow()
.getShell(),
CommandMessages.getFormattedString(
ERROR_COPYING_TO_CONTAINER,
target, container.name()),
e.getCause() != null
? e.getCause().getMessage()
: e.getMessage()));
}
} catch (InterruptedException e) {
// do nothing
} catch (IOException e1) {
Activator.log(e1);
} catch (DockerException e1) {
Activator.log(e1);
} finally {
monitor.done();
}
return Status.OK_STATUS;
}
};
copyToContainerJob.schedule();
}
private void deleteTmpDir(java.nio.file.Path tmpPath) {
File tmpDir = tmpPath.toFile();
for (File f : tmpDir.listFiles()) {
f.delete();
}
tmpDir.delete();
}
}