use of org.eclipse.linuxtools.docker.core.DockerException in project linuxtools by eclipse.
the class ContainerLauncher method runCommand.
/**
* Create a Process to run an arbitrary command in a Container with uid of
* caller so any files created are accessible to user.
*
* @param connectionName
* - uri of connection to use
* @param imageName
* - name of image to use
* @param project
* - Eclipse project
* @param errMsgHolder
* - holder for any error messages
* @param cmdList
* - command to run as list of String
* @param workingDir
* - where to run command
* @param additionalDirs
* - additional directories to mount
* @param origEnv
* - original environment if we are appending to existing
* @param envMap
* - new environment
* @param supportStdin
* - support using stdin
* @param privilegedMode
* - run in privileged mode
* @param labels
* - labels to apply to Container
* @param keepContainer
* - boolean whether to keep Container when done
* @return Process that can be used to check for completion and for routing
* stdout/stderr
*
* @since 4.0
*/
public Process runCommand(String connectionName, String imageName, IProject project, IErrorMessageHolder errMsgHolder, List<String> cmdList, String workingDir, List<String> additionalDirs, Map<String, String> origEnv, Properties envMap, boolean supportStdin, boolean privilegedMode, HashMap<String, String> labels, boolean keepContainer) {
Integer uid = null;
Integer gid = null;
// For Unix, make sure that the user id is passed with the run
// so any output files are accessible by this end-user
// $NON-NLS-1$
String os = System.getProperty("os.name");
if (os.indexOf("nux") > 0) {
// $NON-NLS-1$
// first try and see if we have already run a command on this
// project
ID ugid = fidMap.get(project);
if (ugid == null) {
try {
uid = (Integer) Files.getAttribute(project.getLocation().toFile().toPath(), // $NON-NLS-1$
"unix:uid");
gid = (Integer) Files.getAttribute(project.getLocation().toFile().toPath(), // $NON-NLS-1$
"unix:gid");
ugid = new ID(uid, gid);
// store the uid for possible later usage
fidMap.put(project, ugid);
} catch (IOException e) {
// do nothing...leave as null
}
// $NON-NLS-1$
} else {
uid = ugid.getuid();
gid = ugid.getgid();
}
}
final List<String> env = new ArrayList<>();
env.addAll(toList(origEnv));
env.addAll(toList(envMap));
final Map<String, List<IDockerPortBinding>> portBindingsMap = new HashMap<>();
IDockerConnection[] connections = DockerConnectionManager.getInstance().getConnections();
if (connections == null || connections.length == 0) {
errMsgHolder.setErrorMessage(// $NON-NLS-1$
Messages.getString("ContainerLaunch.noConnections.error"));
return null;
}
IDockerConnection connection = null;
for (IDockerConnection c : connections) {
if (c.getUri().equals(connectionName)) {
connection = c;
break;
}
}
if (connection == null) {
errMsgHolder.setErrorMessage(Messages.getFormattedString(// $NON-NLS-1$
"ContainerLaunch.connectionNotFound.error", connectionName));
return null;
}
List<IDockerImage> images = connection.getImages();
if (images.isEmpty()) {
errMsgHolder.setErrorMessage(// $NON-NLS-1$
Messages.getString("ContainerLaunch.noImages.error"));
return null;
}
IDockerImageInfo info = connection.getImageInfo(imageName);
if (info == null) {
errMsgHolder.setErrorMessage(Messages.getFormattedString("ContainerLaunch.imageNotFound.error", // $NON-NLS-1$
imageName));
return null;
}
DockerContainerConfig.Builder builder = new DockerContainerConfig.Builder().openStdin(supportStdin).cmd(cmdList).image(imageName).workingDir(workingDir);
// switch to user id for Linux so output is accessible
if (uid != null) {
builder = builder.user(uid.toString());
}
// add any labels if specified
if (labels != null)
builder = builder.labels(labels);
DockerHostConfig.Builder hostBuilder = new DockerHostConfig.Builder().privileged(privilegedMode);
// Note we only pass volumes to the config if we have a
// remote daemon. Local mounted volumes are passed
// via the HostConfig binds setting
@SuppressWarnings("rawtypes") final Map<String, Map> remoteVolumes = new HashMap<>();
final Map<String, String> remoteDataVolumes = new HashMap<>();
final Set<String> readOnlyVolumes = new TreeSet<>();
if (!((DockerConnection) connection).isLocal()) {
// the host data over before starting.
if (additionalDirs != null) {
for (String dir : additionalDirs) {
IPath p = new Path(dir).removeTrailingSeparator();
remoteVolumes.put(p.toPortableString(), new HashMap<>());
remoteDataVolumes.put(p.toPortableString(), p.toPortableString());
if (dir.contains(":")) {
// $NON-NLS-1$
DataVolumeModel dvm = DataVolumeModel.parseString(dir);
switch(dvm.getMountType()) {
case HOST_FILE_SYSTEM:
dir = dvm.getHostPathMount();
remoteDataVolumes.put(dir, dvm.getContainerMount());
// back after command completion
if (dvm.isReadOnly()) {
readOnlyVolumes.add(dir);
}
break;
default:
continue;
}
}
}
}
if (workingDir != null) {
IPath p = new Path(workingDir).removeTrailingSeparator();
remoteVolumes.put(p.toPortableString(), new HashMap<>());
remoteDataVolumes.put(p.toPortableString(), p.toPortableString());
}
builder = builder.volumes(remoteVolumes);
} else {
// Running daemon on local host.
// Add mounts for any directories we need to run the executable.
// When we add mount points, we need entries of the form:
// hostname:mountname:Z.
// In our case, we want all directories mounted as-is so the
// executable will run as the user expects.
final Set<String> volumes = new TreeSet<>();
final List<String> volumesFrom = new ArrayList<>();
if (additionalDirs != null) {
for (String dir : additionalDirs) {
IPath p = new Path(dir).removeTrailingSeparator();
if (dir.contains(":")) {
// $NON-NLS-1$
DataVolumeModel dvm = DataVolumeModel.parseString(dir);
switch(dvm.getMountType()) {
case HOST_FILE_SYSTEM:
String bind = LaunchConfigurationUtils.convertToUnixPath(dvm.getHostPathMount()) + ':' + dvm.getContainerPath() + // $NON-NLS-1$ //$NON-NLS-2$
":Z";
if (dvm.isReadOnly()) {
// $NON-NLS-1$
bind += ",ro";
}
volumes.add(bind);
break;
case CONTAINER:
volumesFrom.add(dvm.getContainerMount());
break;
default:
break;
}
} else {
volumes.add(// $NON-NLS-1$
p.toPortableString() + ":" + p.toPortableString() + // $NON-NLS-1$
":Z");
}
}
}
if (workingDir != null) {
IPath p = new Path(workingDir).removeTrailingSeparator();
volumes.add(// $NON-NLS-1$
p.toPortableString() + ":" + p.toPortableString() + // $NON-NLS-1$
":Z");
}
List<String> volumeList = new ArrayList<>(volumes);
hostBuilder = hostBuilder.binds(volumeList);
if (!volumesFrom.isEmpty()) {
hostBuilder = hostBuilder.volumesFrom(volumesFrom);
}
}
final DockerContainerConfig config = builder.build();
// add any port bindings if specified
if (portBindingsMap.size() > 0)
hostBuilder = hostBuilder.portBindings(portBindingsMap);
final IDockerHostConfig hostConfig = hostBuilder.build();
// create the container
String containerId = null;
try {
containerId = ((DockerConnection) connection).createContainer(config, hostConfig, null);
} catch (DockerException | InterruptedException e) {
errMsgHolder.setErrorMessage(e.getMessage());
return null;
}
final String id = containerId;
final IDockerConnection conn = connection;
if (!((DockerConnection) conn).isLocal()) {
// data over from the host.
if (!remoteVolumes.isEmpty()) {
CopyVolumesJob job = new CopyVolumesJob(remoteDataVolumes, conn, id);
job.schedule();
try {
job.join();
} catch (InterruptedException e) {
// ignore
}
}
}
// volumes so they won't be copied back on command completion
for (String readonly : readOnlyVolumes) {
remoteDataVolumes.remove(readonly);
}
return new ContainerCommandProcess(connection, imageName, containerId, remoteDataVolumes, keepContainer);
}
use of org.eclipse.linuxtools.docker.core.DockerException in project linuxtools by eclipse.
the class BaseImagesCommandHandler method execute.
@Override
public Object execute(ExecutionEvent event) {
final IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
final List<IDockerImage> selectedImages = getSelectedImages(activePart);
final IDockerConnection connection = getCurrentConnection(activePart);
if (connection == null || selectedImages.isEmpty()) {
Activator.log(new DockerException(CommandMessages.getString(// $NON-NLS-1$
"Command.missing.selection.failure")));
return null;
}
final Job job = new Job(getJobName(selectedImages)) {
@Override
protected IStatus run(final IProgressMonitor monitor) {
if (confirmed(selectedImages)) {
monitor.beginTask(getJobName(selectedImages), selectedImages.size());
for (final IDockerImage image : selectedImages) {
monitor.setTaskName(getTaskName(image));
executeInJob(image, connection);
monitor.worked(1);
}
}
monitor.done();
return Status.OK_STATUS;
}
};
job.setPriority(Job.LONG);
job.setUser(true);
job.schedule();
return null;
}
use of org.eclipse.linuxtools.docker.core.DockerException in project linuxtools by eclipse.
the class CommitContainerCommandHandler method performCommitContainer.
private void performCommitContainer(final ContainerCommit wizard, final IDockerConnection connection, final IDockerContainer container) {
final Job commitContainerJob = new Job(DVMessages.getString(COMMIT_CONTAINER_JOB_TITLE)) {
@Override
protected IStatus run(final IProgressMonitor monitor) {
final String tag = wizard.getTag();
final String repo = wizard.getRepo();
final String author = wizard.getAuthor();
final String comment = wizard.getComment();
monitor.beginTask(DVMessages.getString(COMMIT_CONTAINER_MSG), 1);
// commit the Container and then update the list of Images
try {
((DockerConnection) connection).commitContainer(container.id(), repo, tag, comment, author);
monitor.worked(1);
} catch (DockerException e) {
Display.getDefault().syncExec(() -> MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), DVMessages.getFormattedString(ERROR_COMMITTING_CONTAINER, tag), e.getMessage()));
} finally {
monitor.done();
}
return Status.OK_STATUS;
}
};
commitContainerJob.schedule();
}
use of org.eclipse.linuxtools.docker.core.DockerException in project linuxtools by eclipse.
the class CopyFromContainerCommandHandler method performCopyFromContainer.
private void performCopyFromContainer(final IDockerConnection connection, final IDockerContainer container, final String target, final List<ContainerFileProxy> files) {
final Job copyFromContainerJob = new Job(CommandMessages.getFormattedString(COPY_FROM_CONTAINER_JOB_TITLE, container.name())) {
@Override
protected IStatus run(final IProgressMonitor monitor) {
monitor.beginTask(CommandMessages.getString(COPY_FROM_CONTAINER_JOB_TASK), files.size());
try (Closeable token = ((DockerConnection) connection).getOperationToken()) {
for (ContainerFileProxy proxy : files) {
if (monitor.isCanceled()) {
monitor.done();
return Status.CANCEL_STATUS;
}
try {
monitor.setTaskName(CommandMessages.getFormattedString(COPY_FROM_CONTAINER_JOB_SUBTASK, proxy.getFullPath()));
monitor.worked(1);
InputStream in = ((DockerConnection) connection).copyContainer(token, container.id(), proxy.getLink());
/*
* The input stream from copyContainer might be
* incomplete or non-blocking so we should wrap it
* in a stream that is guaranteed to block until
* data is available.
*/
TarArchiveInputStream k = new TarArchiveInputStream(new BlockingInputStream(in));
TarArchiveEntry te = null;
while ((te = k.getNextTarEntry()) != null) {
long size = te.getSize();
IPath path = new Path(target);
path = path.append(te.getName());
File f = new File(path.toOSString());
if (te.isDirectory()) {
f.mkdir();
continue;
} else {
f.createNewFile();
}
FileOutputStream os = new FileOutputStream(f);
int bufferSize = ((int) size > 4096 ? 4096 : (int) size);
byte[] barray = new byte[bufferSize];
int result = -1;
while ((result = k.read(barray, 0, bufferSize)) > -1) {
if (monitor.isCanceled()) {
monitor.done();
k.close();
os.close();
return Status.CANCEL_STATUS;
}
os.write(barray, 0, result);
}
os.close();
}
k.close();
} catch (final DockerException e) {
Display.getDefault().syncExec(() -> MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), CommandMessages.getFormattedString(ERROR_COPYING_FROM_CONTAINER, proxy.getLink(), container.name()), e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
}
}
} catch (InterruptedException e) {
// do nothing
} catch (IOException e) {
Activator.log(e);
} catch (DockerException e1) {
Activator.log(e1);
} finally {
monitor.done();
}
return Status.OK_STATUS;
}
};
copyFromContainerJob.schedule();
}
use of org.eclipse.linuxtools.docker.core.DockerException in project linuxtools by eclipse.
the class CopyToContainerCommandHandler method performCopyToContainer.
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);
// 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()));
}
}
// 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();
}
Aggregations