diff options
author | Jeff Johnston | 2017-05-24 21:23:41 +0000 |
---|---|---|
committer | Jeff Johnston | 2017-05-25 15:49:51 +0000 |
commit | 0d2db2b85073909b0118d25d7478a3fbbdcd0ec9 (patch) | |
tree | b1dd51e97a297de76965c30e4b58f755cf44eb47 | |
parent | f8b74b799d6d85a488dc56305c41cb63dc0faa58 (diff) | |
download | org.eclipse.linuxtools-0d2db2b85073909b0118d25d7478a3fbbdcd0ec9.tar.gz org.eclipse.linuxtools-0d2db2b85073909b0118d25d7478a3fbbdcd0ec9.tar.xz org.eclipse.linuxtools-0d2db2b85073909b0118d25d7478a3fbbdcd0ec9.zip |
Bug 517223 - Add way to specify seccomp when running a container
- add new unconfined checkbox to ImageRunSelectionPage connected
to a new "unconfined" property in ImageRunSelectionModel
- change ImageRun to set the HostConfig securityOpt to
"seccomp:unconfined" when the unconfined property is set to true
- add new UnconfinedTest to docker integration tests
- modify MockContainerInfoFactory to set and return
securityOpt setting
- add new message to WizardMessages properties regarding
setting the unconfined option when running image
Change-Id: I65df4ea7897e26a2f1fe1e0eea7b20ee50307e6b
Reviewed-on: https://git.eclipse.org/r/97928
Tested-by: Hudson CI
Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
8 files changed, 151 insertions, 0 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.integration.tests/src/org/eclipse/linuxtools/docker/integration/tests/DockerAllBotTest.java b/containers/org.eclipse.linuxtools.docker.integration.tests/src/org/eclipse/linuxtools/docker/integration/tests/DockerAllBotTest.java index c77a614d8e..e88ee659a8 100644 --- a/containers/org.eclipse.linuxtools.docker.integration.tests/src/org/eclipse/linuxtools/docker/integration/tests/DockerAllBotTest.java +++ b/containers/org.eclipse.linuxtools.docker.integration.tests/src/org/eclipse/linuxtools/docker/integration/tests/DockerAllBotTest.java @@ -19,6 +19,7 @@ import org.eclipse.linuxtools.docker.integration.tests.container.ExposePortTest; import org.eclipse.linuxtools.docker.integration.tests.container.LabelsTest; import org.eclipse.linuxtools.docker.integration.tests.container.LinkContainersTest; import org.eclipse.linuxtools.docker.integration.tests.container.PrivilegedModeTest; +import org.eclipse.linuxtools.docker.integration.tests.container.UnconfinedTest; import org.eclipse.linuxtools.docker.integration.tests.container.VariablesTest; import org.eclipse.linuxtools.docker.integration.tests.container.VolumeMountTest; import org.eclipse.linuxtools.docker.integration.tests.image.BuildImageTest; @@ -57,6 +58,7 @@ import org.junit.runners.Suite; ContainerTabTest.class, VolumeMountTest.class, PrivilegedModeTest.class, + UnconfinedTest.class, VariablesTest.class, LinkContainersTest.class, DifferentRegistryTest.class, diff --git a/containers/org.eclipse.linuxtools.docker.integration.tests/src/org/eclipse/linuxtools/docker/integration/tests/container/UnconfinedTest.java b/containers/org.eclipse.linuxtools.docker.integration.tests/src/org/eclipse/linuxtools/docker/integration/tests/container/UnconfinedTest.java new file mode 100644 index 0000000000..a1ae72d81f --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.integration.tests/src/org/eclipse/linuxtools/docker/integration/tests/container/UnconfinedTest.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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 + * + * Contributor: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.linuxtools.docker.integration.tests.container; + +import static org.junit.Assert.assertTrue; + +import org.eclipse.linuxtools.docker.integration.tests.image.AbstractImageBotTest; +import org.eclipse.linuxtools.docker.integration.tests.mock.MockDockerConnectionManager; +import org.eclipse.linuxtools.docker.reddeer.condition.ContainerIsDeployedCondition; +import org.eclipse.linuxtools.docker.reddeer.core.ui.wizards.ImageRunSelectionPage; +import org.eclipse.linuxtools.docker.reddeer.ui.DockerImagesTab; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockContainerFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockContainerInfoFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerClientFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerConnectionFactory; +import org.eclipse.linuxtools.internal.docker.ui.testutils.MockImageFactory; +import org.jboss.reddeer.common.wait.WaitUntil; +import org.jboss.reddeer.common.wait.WaitWhile; +import org.jboss.reddeer.core.condition.JobIsRunning; +import org.jboss.reddeer.eclipse.ui.views.properties.PropertiesView; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.spotify.docker.client.DockerClient; +import com.spotify.docker.client.exceptions.DockerException; + +/** + * + * @author jkopriva@redhat.com + * @contributor adietish@redhat.com + * + */ +public class UnconfinedTest extends AbstractImageBotTest { + + private static final String IMAGE_NAME = IMAGE_BUSYBOX; + private static final String IMAGE_TAG = IMAGE_TAG_LATEST; + private static final String CONTAINER_NAME = "test_run_busybox"; + + @Before + public void before() throws DockerException, InterruptedException { + deleteAllConnections(); + getConnection(); + pullImage(IMAGE_NAME, IMAGE_TAG); + } + + @Test + public void testUnconfined() { + DockerImagesTab imagesTab = openDockerImagesTab(); + imagesTab.runImage(IMAGE_NAME + ":" + IMAGE_TAG); + ImageRunSelectionPage firstPage = new ImageRunSelectionPage(); + firstPage.setContainerName(CONTAINER_NAME); + firstPage.setAllocatePseudoTTY(); + firstPage.setKeepSTDINOpen(); + firstPage.setUnconfined(); + firstPage.finish(); + if (mockitoIsUsed()) { + runUnconfinedContainer(); + // MockDockerClientFactory.addContainer(this.client, + // this.createdContainer, this.containerInfo); + getConnection().refresh(); + new WaitUntil(new ContainerIsDeployedCondition(CONTAINER_NAME, getConnection())); + } + new WaitWhile(new JobIsRunning()); + PropertiesView propertiesView = openPropertiesTabForContainer("Inspect", CONTAINER_NAME); + String securityProp = propertiesView.getProperty("HostConfig", "SecurityOpt", "").getPropertyValue(); + assertTrue("Container is not running in seccomp:unconfined mode!", securityProp.equals("seccomp:unconfined")); + } + + @After + public void after() { + deleteContainerIfExists(CONTAINER_NAME); + } + + private void runUnconfinedContainer() { + final DockerClient client = MockDockerClientFactory + .container(MockContainerFactory.name(CONTAINER_NAME).status("Stopped").build(), + MockContainerInfoFactory.link(IMAGE_NAME + ":" + IMAGE_TAG_LATEST).securityOpt("seccomp:unconfined") + .id("TestTestTestTestTest").ipAddress("127.0.0.1").build()) + .image(MockImageFactory.id("987654321abcde").name(IMAGE_UHTTPD + ":" + IMAGE_TAG_LATEST).build()) + .build(); + final org.eclipse.linuxtools.internal.docker.core.DockerConnection dockerConnection = MockDockerConnectionFactory + .from(DEFAULT_CONNECTION_NAME, client).withDefaultTCPConnectionSettings(); + MockDockerConnectionManager.configureConnectionManager(dockerConnection); + } +}
\ No newline at end of file diff --git a/containers/org.eclipse.linuxtools.docker.reddeer/src/org/eclipse/linuxtools/docker/reddeer/core/ui/wizards/ImageRunSelectionPage.java b/containers/org.eclipse.linuxtools.docker.reddeer/src/org/eclipse/linuxtools/docker/reddeer/core/ui/wizards/ImageRunSelectionPage.java index 7c5f06b5cf..29bceb289d 100644 --- a/containers/org.eclipse.linuxtools.docker.reddeer/src/org/eclipse/linuxtools/docker/reddeer/core/ui/wizards/ImageRunSelectionPage.java +++ b/containers/org.eclipse.linuxtools.docker.reddeer/src/org/eclipse/linuxtools/docker/reddeer/core/ui/wizards/ImageRunSelectionPage.java @@ -104,6 +104,14 @@ public class ImageRunSelectionPage extends WizardPage { public void setGiveExtendedPrivileges() { setGiveExtendedPrivileges(true); } + + public void setUnconfined(boolean checked) { + new CheckBox("Use unconfined seccomp profile (--securityOpt seccomp=unconfined)").toggle(checked); + } + + public void setUnconfined() { + setUnconfined(true); + } public void addExposedPort(String containerPort, String hostAddress, String hostPort) { new PushButton(0, new WithTextMatcher("Add...")).click(); diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/MockContainerInfoFactory.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/MockContainerInfoFactory.java index bcb648f98e..4ed4d3f509 100644 --- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/MockContainerInfoFactory.java +++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/testutils/MockContainerInfoFactory.java @@ -66,6 +66,10 @@ public class MockContainerInfoFactory { return new Builder().privilegedMode(mode); } + public static Builder securityOpt(String profile) { + return new Builder().securityOpt(profile); + } + public static Builder labels(Map<String, String> labels) { return new Builder().labels(labels); } @@ -88,6 +92,8 @@ public class MockContainerInfoFactory { private Boolean privilegedMode; + private List<String> securityOpt; + private Builder() { this.containerInfo = Mockito.mock(ContainerInfo.class, Mockito.RETURNS_DEEP_STUBS); Mockito.when(this.containerInfo.created()).thenReturn(new Date()); @@ -139,6 +145,14 @@ public class MockContainerInfoFactory { return this; } + public Builder securityOpt(final String opt) { + if (this.securityOpt == null) { + this.securityOpt = new ArrayList<>(); + } + this.securityOpt.add(opt); + return this; + } + public Builder volume(final String volume) { if (this.volumes == null) { this.volumes = new ArrayList<>(); @@ -177,6 +191,7 @@ public class MockContainerInfoFactory { final HostConfig hostConfig = Mockito.mock(HostConfig.class); Mockito.when(this.containerInfo.hostConfig()).thenReturn(hostConfig); Mockito.when(hostConfig.links()).thenReturn(this.links); + Mockito.when(hostConfig.securityOpt()).thenReturn(this.securityOpt); Mockito.when(hostConfig.binds()).thenReturn(this.volumes); Mockito.when(hostConfig.networkMode()).thenReturn(this.networkMode); Mockito.when(hostConfig.privileged()).thenReturn(this.privilegedMode); diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java index fd88d41761..d8024673a0 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java @@ -199,6 +199,11 @@ public class ImageRun extends Wizard { hostConfigBuilder.binds(binds); hostConfigBuilder.volumesFrom(volumesFrom); hostConfigBuilder.privileged(selectionModel.isPrivileged()); + if (selectionModel.isUnconfined()) { + List<String> seccomp = new ArrayList<>(); + seccomp.add("seccomp:unconfined"); //$NON-NLS-1$ + hostConfigBuilder.securityOpt(seccomp); + } String networkMode = networkModel.getNetworkModeString(); // if network mode is not default, set it in host config if (networkMode != null diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionModel.java index cc31738035..0469d5d7aa 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionModel.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionModel.java @@ -69,6 +69,8 @@ public class ImageRunSelectionModel extends BaseDatabindingModel { public static final String PRIVILEGED = "privileged"; //$NON-NLS-1$ + public static final String UNCONFINED = "unconfined"; //$NON-NLS-1$ + private String selectedConnectionName = ""; private List<String> connectionNames; @@ -105,6 +107,8 @@ public class ImageRunSelectionModel extends BaseDatabindingModel { private boolean privileged = false; + private boolean unconfined = false; + public ImageRunSelectionModel( final IDockerConnection selectedConnection) { refreshConnectionNames(); @@ -409,6 +413,15 @@ public class ImageRunSelectionModel extends BaseDatabindingModel { this.privileged = privileged); } + public boolean isUnconfined() { + return unconfined; + } + + public void setUnconfined(boolean unconfined) { + firePropertyChange(UNCONFINED, this.unconfined, + this.unconfined = unconfined); + } + public static class ExposedPortModel extends BaseDatabindingModel implements Comparable<ExposedPortModel> { diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java index 44f129197a..e7f7d14a2a 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java @@ -687,6 +687,18 @@ public class ImageRunSelectionPage extends WizardPage { .value(ImageRunSelectionModel.class, ImageRunSelectionModel.PRIVILEGED) .observe(model)); + + // seccomp:unconfined + final Button unconfinedButton = new Button(container, SWT.CHECK); + unconfinedButton.setText( + WizardMessages.getString("ImageRunSelectionPage.unconfined")); //$NON-NLS-1$ + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) + .span(COLUMNS, 1).grab(true, false).applyTo(unconfinedButton); + dbc.bindValue(WidgetProperties.selection().observe(unconfinedButton), + BeanProperties + .value(ImageRunSelectionModel.class, + ImageRunSelectionModel.UNCONFINED) + .observe(model)); } /** diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties index 80998f2332..82819c8ea8 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties @@ -292,6 +292,7 @@ ImageRunSelectionPage.openStdin=Keep STDIN open to Console even if not attached ImageRunSelectionPage.tty=Allocate pseudo-TTY from Console (-t) ImageRunSelectionPage.autoRemove=Automatically remove the container when it exits (--rm) ImageRunSelectionPage.privileged=Give extended privileges to this container (--privileged) +ImageRunSelectionPage.unconfined=Use unconfined seccomp profile (--securityOpt seccomp=unconfined) ImageRunSelectionPage.pullingTask=Pulling image ''{0}'' ImageRunSelectionPage.specifyImageMsg=Please specify the image to run. ImageRunSelectionPage.imageNotFoundMessage=Image named ''{0}'' does not exist locally. Click on the link under the 'Image' combo to start pulling it. |