blob: 987eaf22ea223438f696b4681221b5e5ce35dc7d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015, 2016 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat - Initial Contribution
*******************************************************************************/
package org.eclipse.linuxtools.internal.docker.ui.launch;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.IValueChangeListener;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.fieldassist.ContentProposal;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.linuxtools.docker.core.AbstractRegistry;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerContainer;
import org.eclipse.linuxtools.docker.core.IDockerImage;
import org.eclipse.linuxtools.docker.core.IDockerImageInfo;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.linuxtools.docker.ui.wizards.ImageSearch;
import org.eclipse.linuxtools.internal.docker.core.RegistryInfo;
import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
import org.eclipse.linuxtools.internal.docker.ui.commands.CommandUtils;
import org.eclipse.linuxtools.internal.docker.ui.utils.IRunnableWithResult;
import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageNameValidator;
import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumesVariablesModel;
import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel;
import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ExposedPortModel;
import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
public class RunImageMainTab extends AbstractLaunchConfigurationTab {
private static final String TAB_NAME = "RunMainTab.name"; //$NON-NLS-1$
// private static final String ERROR_PULLING_IMAGE = "ImagePullError.msg";
// //$NON-NLS-1$
private static final int COLUMNS = 3;
private final DataBindingContext dbc = new DataBindingContext();
private final ImageRunSelectionModel model;
private final ImageRunResourceVolumesVariablesModel volumesModel;
public RunImageMainTab(ImageRunSelectionModel model,
ImageRunResourceVolumesVariablesModel volumesModel) {
this.model = model;
this.volumesModel = volumesModel;
}
public ImageRunSelectionModel getModel() {
return model;
}
@Override
public String getName() {
return LaunchMessages.getString(TAB_NAME);
}
@Override
public void createControl(Composite parent) {
final Composite container = new Composite(parent, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(1, 1)
.grab(true, false).applyTo(container);
GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
.applyTo(container);
if (model == null) {
setErrorMessage(LaunchMessages.getString("NoConnectionError.msg"));
return;
} else {
setErrorMessage(null);
setDefaultValues();
createImageSettingsSection(container);
createSectionSeparator(container, true);
createRunOptionsSection(container);
final IObservableValue connectionSelectionObservable = BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.SELECTED_CONNECTION_NAME)
.observe(model);
connectionSelectionObservable
.addValueChangeListener(onConnectionSelectionChange());
final IObservableValue imageSelectionObservable = BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.SELECTED_IMAGE_NAME)
.observe(model);
imageSelectionObservable
.addValueChangeListener(onImageSelectionChange());
}
setControl(container);
}
private void setDefaultValues() {
final IDockerImage selectedImage = model.getSelectedImage();
if (selectedImage == null) {
return;
}
findImageInfo(selectedImage);
}
private void createSectionSeparator(final Composite container,
final boolean separator) {
final int SECTION_INDENT = 10;
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.span(COLUMNS, 1).grab(true, false)
.indent(SWT.DEFAULT, SECTION_INDENT)
.applyTo(new Label(container, separator
? (SWT.SEPARATOR | SWT.HORIZONTAL) : SWT.NONE));
}
/**
* Creates the {@link Composite} container that will display widgets to
* select an {@link IDockerImage}, name it and specify the command to run.
*
* @param container
* the parent {@link Composite}
*/
private void createImageSettingsSection(final Composite container) {
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).span(3, 1)
.applyTo(new Label(container, SWT.NONE));
final Label connectionSelectionLabel = new Label(container, SWT.NONE);
connectionSelectionLabel
.setText(WizardMessages.getString("Connection.label")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(connectionSelectionLabel);
final Combo connectionSelectionCombo = new Combo(container, SWT.BORDER);
connectionSelectionCombo.setToolTipText(
LaunchMessages.getString("RunMainTabSelectConnection.tooltip")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).span(1, 1).applyTo(connectionSelectionCombo);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).span(1, 1)
.applyTo(new Label(container, SWT.NONE));
new ControlDecoration(connectionSelectionCombo, SWT.TOP | SWT.LEFT);
final ComboViewer connectionSelectionComboViewer = new ComboViewer(
connectionSelectionCombo);
connectionSelectionComboViewer
.setContentProvider(new ArrayContentProvider());
connectionSelectionComboViewer.setInput(DockerConnectionManager
.getInstance().getConnectionNames().toArray());
dbc.bindValue(
WidgetProperties.selection().observe(connectionSelectionCombo),
BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.SELECTED_CONNECTION_NAME)
.observe(model));
// Image selection name
final Label imageSelectionLabel = new Label(container, SWT.NONE);
imageSelectionLabel.setText(WizardMessages.getString("Image.label")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(imageSelectionLabel);
final Combo imageSelectionCombo = new Combo(container, SWT.BORDER);
final ComboViewer imageSelectionComboViewer = new ComboViewer(
imageSelectionCombo);
imageSelectionCombo.setToolTipText(WizardMessages
.getString("ImageRunSelectionPage.selectTooltip")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).span(1, 1).applyTo(imageSelectionCombo);
new ControlDecoration(imageSelectionCombo, SWT.TOP | SWT.LEFT);
new ContentProposalAdapter(imageSelectionCombo,
new ComboContentAdapter() {
@Override
public void insertControlContents(Control control,
String text, int cursorPosition) {
final Combo combo = (Combo) control;
final Point selection = combo.getSelection();
combo.setText(text);
selection.x = text.length();
selection.y = selection.x;
combo.setSelection(selection);
}
}, getImageNameContentProposalProvider(imageSelectionCombo),
null, null);
// image search
final Button searchImageButton = new Button(container, SWT.NONE);
searchImageButton.setText(
WizardMessages.getString("ImageRunSelectionPage.search")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).span(1, 1)
.hint(LaunchConfigurationUtils
.getButtonWidthHint(searchImageButton), SWT.DEFAULT)
.applyTo(searchImageButton);
searchImageButton.addSelectionListener(onSearchImage());
imageSelectionComboViewer
.setContentProvider(new ObservableListContentProvider());
dbc.bindList(WidgetProperties.items().observe(imageSelectionCombo),
BeanProperties
.list(ImageRunSelectionModel.class,
ImageRunSelectionModel.IMAGE_NAMES)
.observe(model));
dbc.bindValue(WidgetProperties.selection().observe(imageSelectionCombo),
BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.SELECTED_IMAGE_NAME)
.observe(model));
// Container name (optional)
final Label containerNameLabel = new Label(container, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(imageSelectionLabel);
containerNameLabel.setText("Name:"); //$NON-NLS-1$
final Text containerNameText = new Text(container, SWT.BORDER);
containerNameText.setToolTipText(WizardMessages
.getString("ImageRunSelectionPage.containerTooltip")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).span(1, 1).applyTo(containerNameText);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).span(1, 1)
.applyTo(new Label(container, SWT.NONE));
dbc.bindValue(
WidgetProperties.text(SWT.Modify).observe(containerNameText),
BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.CONTAINER_NAME)
.observe(model));
// EntryPoint (optional)
final Label entrypointLabel = new Label(container, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(imageSelectionLabel);
entrypointLabel.setText(
WizardMessages.getString("ImageRunSelectionPage.entrypoint")); //$NON-NLS-1$
// TODO: include SWT.SEARCH | SWT.ICON_SEARCH to support value reset
final Text entrypointText = new Text(container, SWT.BORDER);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).span(1, 1).applyTo(entrypointText);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).span(1, 1)
.applyTo(new Label(container, SWT.NONE));
dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(entrypointText),
BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.ENTRYPOINT)
.observe(model));
// Command (optional)
final Label commandLabel = new Label(container, SWT.NONE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(imageSelectionLabel);
commandLabel.setText(
WizardMessages.getString("ImageRunSelectionPage.command")); //$NON-NLS-1$
final Text commandText = new Text(container, SWT.BORDER);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false).span(1, 1).applyTo(commandText);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).span(1, 1)
.applyTo(new Label(container, SWT.NONE));
dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(commandText),
BeanProperties.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.COMMAND).observe(model));
}
/**
* Creates an {@link IContentProposalProvider} to propose
* {@link IDockerImage} names based on the current text.
*
* @param items
* @return
*/
private IContentProposalProvider getImageNameContentProposalProvider(
final Combo imageSelectionCombo) {
return (contents, position) -> {
final List<IContentProposal> proposals = new ArrayList<>();
for (String imageName : imageSelectionCombo.getItems()) {
if (imageName.contains(contents)) {
proposals.add(new ContentProposal(imageName, imageName,
imageName, position));
}
}
return proposals.toArray(new IContentProposal[0]);
};
}
private IValueChangeListener onImageSelectionChange() {
return event -> {
final IDockerImage selectedImage = model.getSelectedImage();
// skip if the selected image does not exist in the local Docker
// host
if (selectedImage == null) {
model.setExposedPorts(new ArrayList<ExposedPortModel>());
return;
}
findImageInfo(selectedImage);
volumesModel.setSelectedImage(selectedImage);
};
}
private IValueChangeListener onConnectionSelectionChange() {
return event -> {
IDockerImage selectedImage = model.getSelectedImage();
// skip if the selected image does not exist in the local Docker
// host
if (selectedImage == null) {
List<String> imageNames = model.getImageNames();
if (imageNames.size() > 0) {
model.setSelectedImageName(imageNames.get(0));
selectedImage = model.getSelectedImage();
} else {
model.setExposedPorts(new ArrayList<ExposedPortModel>());
return;
}
}
findImageInfo(selectedImage);
volumesModel.setSelectedImage(selectedImage);
};
}
private static final class FindImageInfoRunnable
implements IRunnableWithResult<IDockerImageInfo> {
private final IDockerImage selectedImage;
private IDockerImageInfo selectedImageInfo;
private FindImageInfoRunnable(IDockerImage selectedImage) {
this.selectedImage = selectedImage;
}
@Override
public void run(final IProgressMonitor monitor) {
selectedImageInfo = selectedImage.getConnection()
.getImageInfo(selectedImage.id());
}
@Override
public IDockerImageInfo getResult() {
return selectedImageInfo;
}
}
private void findImageInfo(final IDockerImage selectedImage) {
try {
final FindImageInfoRunnable findImageInfoRunnable = new FindImageInfoRunnable(
selectedImage);
ProgressMonitorDialog dialog = new ProgressMonitorDialog(
this.getShell());
dialog.run(true, true, findImageInfoRunnable);
final IDockerImageInfo selectedImageInfo = findImageInfoRunnable
.getResult();
final Set<String> exposedPortInfos = selectedImageInfo.config()
.exposedPorts();
final List<ExposedPortModel> availablePorts = new ArrayList<>();
if (exposedPortInfos != null) {
for (String exposedPortInfo : exposedPortInfos) {
final String privatePort = exposedPortInfo.substring(0,
exposedPortInfo.indexOf('/'));
final String type = exposedPortInfo
.substring(exposedPortInfo.indexOf('/')); // $NON-NLS-1$
final ExposedPortModel exposedPort = new ExposedPortModel(
privatePort, type, "", privatePort);
availablePorts.add(exposedPort); // $NON-NLS-1$
}
}
model.setExposedPorts(availablePorts);
model.setEntrypoint(selectedImageInfo.config().entrypoint());
model.setCommand(selectedImageInfo.config().cmd());
} catch (InvocationTargetException | InterruptedException e) {
Activator.log(e);
}
}
private void createRunOptionsSection(final Composite container) {
// interactive/show in console mode
final Button interactiveButton = new Button(container, SWT.CHECK);
interactiveButton.setText(
WizardMessages.getString("ImageRunSelectionPage.openStdin")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.span(COLUMNS, 1).grab(true, false).applyTo(interactiveButton);
dbc.bindValue(WidgetProperties.selection().observe(interactiveButton),
BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.INTERACTIVE_MODE)
.observe(model));
// allocate pseudo-TTY
final Button allocatePseudoTTY = new Button(container, SWT.CHECK);
allocatePseudoTTY
.setText(WizardMessages.getString("ImageRunSelectionPage.tty")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.span(COLUMNS, 1).grab(true, false).applyTo(allocatePseudoTTY);
dbc.bindValue(WidgetProperties.selection().observe(allocatePseudoTTY),
BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.ALLOCATE_PSEUDO_TTY)
.observe(model));
// remove when exits
final Button removeWhenExitsButton = new Button(container, SWT.CHECK);
removeWhenExitsButton.setText(
WizardMessages.getString("ImageRunSelectionPage.autoRemove")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.span(COLUMNS, 1).grab(true, false)
.applyTo(removeWhenExitsButton);
dbc.bindValue(
WidgetProperties.selection().observe(removeWhenExitsButton),
BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.REMOVE_WHEN_EXITS)
.observe(model));
// privileged
final Button privilegedButton = new Button(container, SWT.CHECK);
privilegedButton.setText(
WizardMessages.getString("ImageRunSelectionPage.privileged")); //$NON-NLS-1$
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.span(COLUMNS, 1).grab(true, false).applyTo(privilegedButton);
dbc.bindValue(WidgetProperties.selection().observe(privilegedButton),
BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.PRIVILEGED)
.observe(model));
}
private SelectionListener onSearchImage() {
return new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
final ImageSearch imageSearchWizard = new ImageSearch(
RunImageMainTab.this.model.getSelectedConnection(),
RunImageMainTab.this.model.getSelectedImageName(),
new RegistryInfo(AbstractRegistry.DOCKERHUB_REGISTRY,
true));
final boolean completed = CommandUtils
.openWizard(imageSearchWizard, getShell());
if (completed) {
model.setSelectedImageName(
imageSearchWizard.getSelectedImage());
}
}
};
}
@Override
public Image getImage() {
return SWTImagesFactory.get(SWTImagesFactory.IMG_MAIN_TAB);
}
@Override
public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
}
@Override
public void initializeFrom(ILaunchConfiguration configuration) {
// Don't attempt to continue if model is null since it means there are
// no connections
if (model == null)
return;
try {
final String defaultConnectionName = DockerConnectionManager
.getInstance().getAllConnections().stream()
.filter(connection -> connection.isOpen())
.map(connection -> connection.getName()).findFirst()
.orElse(""); //$NON-NLS-1$
// Mark in error if there is no active connection
if (defaultConnectionName.equals("")) { //$NON-NLS-1$
setErrorMessage(WizardMessages
.getString("ErrorNoActiveConnection.msg")); //$NON-NLS-1$
}
String connectionName = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.CONNECTION_NAME,
defaultConnectionName);
model.setSelectedConnectionName(connectionName);
String imageName = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.IMAGE_NAME, ""); //$NON-NLS-1$
model.setSelectedImageName(imageName);
String entryPoint = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.ENTRYPOINT, ""); //$NON-NLS-1$
model.setEntrypoint(entryPoint);
String command = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.COMMAND, ""); //$NON-NLS-1$
model.setCommand(command);
String containerName = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.CONTAINER_NAME,
""); //$NON-NLS-1$
model.setContainerName(containerName);
boolean removeContainer = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.AUTO_REMOVE,
false);
model.setRemoveWhenExits(removeContainer);
boolean interactive = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.INTERACTIVE,
false);
model.setInteractiveMode(interactive);
boolean useTTY = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.ALLOCATE_PSEUDO_CONSOLE,
false);
model.setAllocatePseudoTTY(useTTY);
boolean privileged = configuration.getAttribute(
IRunDockerImageLaunchConfigurationConstants.PRIVILEGED,
false);
model.setPrivileged(privileged);
} catch (CoreException e) {
Activator.logErrorMessage(
LaunchMessages.getString(
"RunDockerImageLaunchConfiguration.load.failure"), //$NON-NLS-1$
e);
}
// update the underlying launch config working copy on model
// changes.
model.addPropertyChangeListener(
new LaunchConfigurationChangeListener());
}
@Override
public void performApply(ILaunchConfigurationWorkingCopy configuration) {
if (model == null)
return;
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.CONNECTION_NAME,
model.getSelectedConnectionName());
if (model.getSelectedImage() != null) {
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.IMAGE_ID,
model.getSelectedImage().id());
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.IMAGE_NAME,
model.getSelectedImageName());
}
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.COMMAND,
model.getCommand());
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.ENTRYPOINT,
"".equals(model.getEntrypoint()) ? null //$NON-NLS-1$
: model.getEntrypoint());
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.CONTAINER_NAME,
"".equals(model.getContainerName()) ? null //$NON-NLS-1$
: model.getContainerName());
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.ALLOCATE_PSEUDO_CONSOLE,
model.isAllocatePseudoTTY());
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.AUTO_REMOVE,
model.isRemoveWhenExits());
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.INTERACTIVE,
model.isInteractiveMode());
configuration.setAttribute(
IRunDockerImageLaunchConfigurationConstants.PRIVILEGED,
model.isPrivileged());
}
@Override
public boolean isValid(ILaunchConfiguration launchConfig) {
try {
if (model == null)
return false;
String connectionName = launchConfig.getAttribute(
IRunDockerImageLaunchConfigurationConstants.CONNECTION_NAME,
"");
if (connectionName.isEmpty()) {
return false;
} else {
// Verify Connection is active
IDockerConnection connection = DockerConnectionManager
.getInstance().findConnection(connectionName);
if (connection == null || !connection.isOpen()) {
setErrorMessage(WizardMessages
.getFormattedString("ErrorInactiveConnection.msg", //$NON-NLS-1$
connectionName));
return false;
}
}
final IStatus imageSelectionValidationStatus = new ImageSelectionValidator()
.validate(model.getSelectedImageName());
if (!imageSelectionValidationStatus.isOK()) {
setErrorMessage(imageSelectionValidationStatus.getMessage());
return false;
}
final IStatus imageNameValidationStatus = new ImageNameValidator()
.validate(model.getSelectedImageName());
if (!imageNameValidationStatus.isOK()) {
setErrorMessage(imageNameValidationStatus.getMessage());
return false;
}
final IStatus containerNameValidationStatus = new ContainerNameValidator()
.validate(model.getContainerName());
if (!containerNameValidationStatus.isOK()) {
setErrorMessage(containerNameValidationStatus.getMessage());
return false;
}
} catch (CoreException e) {
Activator.log(e);
}
setErrorMessage(null);
return true;
}
private class LaunchConfigurationChangeListener
implements PropertyChangeListener {
@Override
public void propertyChange(final PropertyChangeEvent evt) {
updateLaunchConfigurationDialog();
}
}
private class ImageSelectionValidator implements IValidator {
@Override
public IStatus validate(final Object value) {
final String selectedImageName = (String) value;
if (selectedImageName.isEmpty()) {
model.setSelectedImageNeedsPulling(false);
return ValidationStatus.error(WizardMessages
.getString("ImageRunSelectionPage.specifyImageMsg")); //$NON-NLS-1$
}
if (model.getSelectedImage() != null) {
model.setSelectedImageNeedsPulling(false);
return ValidationStatus.ok();
}
model.setSelectedImageNeedsPulling(true);
return ValidationStatus.warning(WizardMessages.getFormattedString(
"ImageRunSelectionPage.imageNotFoundMessage", //$NON-NLS-1$
selectedImageName));
}
}
private class ContainerNameValidator implements IValidator {
@Override
public IStatus validate(Object value) {
final String containerName = (String) value;
for (IDockerContainer container : model.getSelectedConnection()
.getContainers()) {
if (container.name().equals(containerName)) {
return ValidationStatus.error(WizardMessages.getString(
"ImageRunSelectionPage.containerWithSameName")); //$NON-NLS-1$
}
}
return ValidationStatus.ok();
}
}
}