Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed permissions on items in the context tar sent to docker daemon t… #477

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package io.fabric8.maven.docker.assembly;

import java.io.File;
import java.io.IOException;
import java.util.*;

import io.fabric8.maven.docker.config.*;
import io.fabric8.maven.docker.util.Logger;
import io.fabric8.maven.docker.util.MojoParameters;
Expand All @@ -18,7 +14,9 @@
import org.apache.maven.plugin.assembly.model.Assembly;
import org.apache.maven.shared.utils.PathTool;
import org.apache.maven.shared.utils.io.FileUtils;
import org.codehaus.plexus.archiver.ArchiveEntry;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ResourceIterator;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.codehaus.plexus.archiver.tar.TarArchiver;
Expand All @@ -27,6 +25,15 @@
import org.codehaus.plexus.archiver.util.DefaultFileSet;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
* Tool for creating a docker image tar ball including a Dockerfile for building
Expand Down Expand Up @@ -65,15 +72,19 @@ public class DockerAssemblyManager {
* @param imageName Name of the image to create (used for creating build directories)
* @param params Mojos parameters (used for finding the directories)
* @param buildConfig configuration for how to build the image
* @param log Logger used to display warning if permissions are to be normalized
* @return file holding the path to the created assembly tar file
* @throws MojoExecutionException
*/
public File createDockerTarArchive(String imageName, MojoParameters params, BuildImageConfiguration buildConfig)
public File createDockerTarArchive(String imageName, MojoParameters params, BuildImageConfiguration buildConfig, Logger log)
throws MojoExecutionException {
BuildDirs buildDirs = createBuildDirs(imageName, params);

AssemblyConfiguration assemblyConfig = buildConfig.getAssemblyConfiguration();
AssemblyMode assemblyMode = (assemblyConfig == null) ? AssemblyMode.dir : assemblyConfig.getMode();
boolean normalizePermissions = (assemblyConfig == null)
? AssemblyConfiguration.isWindows()
: assemblyConfig.isNormalizePermissions();

// Build up assembly
if (hasAssemblyConfiguration(assemblyConfig)) {
Expand All @@ -92,10 +103,11 @@ public File createDockerTarArchive(String imageName, MojoParameters params, Buil
// User dedicated Dockerfile from extra
customizer = new ArchiverCustomizer() {
@Override
public void customize(TarArchiver archiver) throws IOException {
public TarArchiver customize(TarArchiver archiver) throws IOException {
DefaultFileSet fileSet = DefaultFileSet.fileSet(dockerFile.getParentFile());
addDockerIgnoreIfPresent(fileSet);
archiver.addFileSet(fileSet);
return archiver;
}
};
} else {
Expand All @@ -106,12 +118,17 @@ public void customize(TarArchiver archiver) throws IOException {
final File dockerFile = new File(buildDirs.getOutputDirectory(),"Dockerfile");
customizer = new ArchiverCustomizer() {
@Override
public void customize(TarArchiver archiver) throws IOException {
public TarArchiver customize(TarArchiver archiver) throws IOException {
archiver.addFile(dockerFile, "Dockerfile");
return archiver;
}
};
}

if (normalizePermissions) {
customizer = new TarPermissionsNormalizer(customizer, log);
}

return createBuildTarBall(buildDirs, customizer, assemblyMode, buildConfig.getCompression());

} catch (IOException e) {
Expand Down Expand Up @@ -186,9 +203,9 @@ private File createBuildTarBall(BuildDirs buildDirs, ArchiverCustomizer archiver
File archive = new File(buildDirs.getTemporaryRootDirectory(), "docker-build." + compression.getFileSuffix());
try {
TarArchiver archiver = createBuildArchiver(buildDirs.getOutputDirectory(), archive, buildMode);
archiverCustomizer.customize(archiver);
archiver.createArchive();
archiver = archiverCustomizer.customize(archiver);
archiver.setCompression(compression.getTarCompressionMethod());
archiver.createArchive();
return archive;
} catch (NoSuchArchiverException e) {
throw new MojoExecutionException("No archiver for type 'tar' found", e);
Expand Down Expand Up @@ -365,10 +382,61 @@ private Assembly extractAssembly(AssemblerConfigurationSource config) throws Moj
}
}



// Archiver used to adapt for customizations
private interface ArchiverCustomizer {
void customize(TarArchiver archiver) throws IOException;
TarArchiver customize(TarArchiver archiver) throws IOException;
}

private class TarPermissionsNormalizer implements ArchiverCustomizer {
private ArchiverCustomizer innerCustomizer;
private Logger log;

public TarPermissionsNormalizer(ArchiverCustomizer inner, Logger logger) {
innerCustomizer = inner;
this.log = logger;
}

@Override
public TarArchiver customize(TarArchiver archiver) throws IOException {
log.warn("/--------------------- SECURITY WARNING ---------------------\\");
log.warn("|You are building a Docker image with normalized permissions.|");
log.warn("|All files and directories added to build context will have |");
log.warn("|'-rwxr-xr-x' permissions. It is recommended to double check |");
log.warn("|and reset permissions for sensitive files and directories. |");
log.warn("\\------------------------------------------------------------/");

if (innerCustomizer != null) {
archiver = innerCustomizer.customize(archiver);
}

TarArchiver newArchiver = new TarArchiver();
newArchiver.setDestFile(archiver.getDestFile());
newArchiver.setLongfile(TarLongFileMode.posix);

ResourceIterator resources = archiver.getResources();
while (resources.hasNext()) {
ArchiveEntry ae = resources.next();
String fileName = ae.getName();
PlexusIoResource resource = ae.getResource();
String name = StringUtils.replace(fileName, File.separatorChar, '/');

// See docker source:
// https://github.com/docker/docker/blob/3d13fddd2bc4d679f0eaa68b0be877e5a816ad53/pkg/archive/archive_windows.go#L45
int mode = ae.getMode() & 0777;
int newMode = mode;
newMode &= 0755;
newMode |= 0111;

if (newMode != mode) {
log.debug("Changing permissions of '%s' from %o to %o.", name, mode, newMode);
}

newArchiver.addResource(resource, name, newMode);
}

archiver = newArchiver;

return archiver;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public class AssemblyConfiguration {
*/
private String user;

/**
* @parameter default-value="auto"
*/
private String normalizePermissions;

public Boolean exportBasedir() {
return exportBasedir;
}
Expand Down Expand Up @@ -88,6 +93,25 @@ public AssemblyMode getMode() {
public Boolean isIgnorePermissions() {
return (ignorePermissions != null) ? ignorePermissions : Boolean.FALSE;
}

public Boolean isNormalizePermissions() {
if (normalizePermissions == null) {
normalizePermissions = "auto";
}

switch (normalizePermissions.toLowerCase()) {
case "true":
return true;
case "false":
return false;
default:
return isWindows();
}
}

public static boolean isWindows() {
return System.getProperty("os.name").toLowerCase().contains("windows");
}

public static class Builder {

Expand Down Expand Up @@ -133,6 +157,11 @@ public Builder ignorePermissions(Boolean ignorePermissions) {
return this;
}

public Builder normalizePermissions(String normalizePermissions) {
config.normalizePermissions = set(normalizePermissions);
return this;
}

public Builder user(String user) {
config.user = set(user);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@
* limitations under the License.
*/

import java.io.File;
import java.util.List;

import io.fabric8.maven.docker.assembly.AssemblyFiles;
import io.fabric8.maven.docker.assembly.DockerAssemblyManager;
import io.fabric8.maven.docker.config.BuildImageConfiguration;
import io.fabric8.maven.docker.config.ImageConfiguration;
import io.fabric8.maven.docker.util.Logger;
import io.fabric8.maven.docker.util.MojoParameters;
import io.fabric8.maven.docker.config.ImageConfiguration;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.assembly.InvalidAssemblerConfigurationException;
import org.apache.maven.plugin.assembly.archive.ArchiveCreationException;
import org.apache.maven.plugin.assembly.format.AssemblyFormattingException;

import java.io.File;
import java.util.List;

/**
* @author roland
* @since 30/11/15
Expand Down Expand Up @@ -56,7 +56,7 @@ public ArchiveService(DockerAssemblyManager dockerAssemblyManager,Logger log) {
*/
public File createDockerBuildArchive(ImageConfiguration imageConfig, MojoParameters params)
throws MojoExecutionException {
File ret = createArchive(imageConfig.getName(), imageConfig.getBuildConfiguration(), params);
File ret = createArchive(imageConfig.getName(), imageConfig.getBuildConfiguration(), params, log);
log.info("%s: Created docker source tar %s",imageConfig.getDescription(), ret);
return ret;
}
Expand Down Expand Up @@ -97,8 +97,8 @@ public File createChangedFilesArchive(List<AssemblyFiles.Entry> entries, File as

// =============================================

File createArchive(String imageName, BuildImageConfiguration buildConfig, MojoParameters params)
File createArchive(String imageName, BuildImageConfiguration buildConfig, MojoParameters params, Logger log)
throws MojoExecutionException {
return dockerAssemblyManager.createDockerTarArchive(imageName, params, buildConfig);
return dockerAssemblyManager.createDockerTarArchive(imageName, params, buildConfig, log);
}
}
13 changes: 8 additions & 5 deletions src/main/java/io/fabric8/maven/docker/service/BuildService.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package io.fabric8.maven.docker.service;

import java.io.File;
import java.util.Map;

import com.google.common.collect.ImmutableMap;
import io.fabric8.maven.docker.access.DockerAccess;
import io.fabric8.maven.docker.access.DockerAccessException;
import io.fabric8.maven.docker.config.BuildImageConfiguration;
import io.fabric8.maven.docker.config.CleanupMode;
import io.fabric8.maven.docker.config.ImageConfiguration;
import io.fabric8.maven.docker.util.*;
import io.fabric8.maven.docker.util.EnvUtil;
import io.fabric8.maven.docker.util.ImageName;
import io.fabric8.maven.docker.util.Logger;
import io.fabric8.maven.docker.util.MojoParameters;
import org.apache.maven.plugin.MojoExecutionException;

import java.io.File;
import java.util.Map;

public class BuildService {

private final DockerAccess docker;
Expand Down Expand Up @@ -52,7 +55,7 @@ public void buildImage(ImageConfiguration imageConfig, MojoParameters params, bo
}

long time = System.currentTimeMillis();
File dockerArchive = archiveService.createArchive(imageName, buildConfig, params);
File dockerArchive = archiveService.createArchive(imageName, buildConfig, params, log);
log.info("%s: Created %s in %s", dockerArchive.getName(), imageConfig.getDescription(), EnvUtil.formatDurationTill(time));

Map<String, String> mergedBuildMap = prepareBuildArgs(buildArgs, buildConfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public class BuildServiceTest {
@Before
public void setup() throws Exception {
new Expectations() {{
archiveService.createArchive(anyString, (BuildImageConfiguration) any, (MojoParameters) any);
archiveService.createArchive(anyString, (BuildImageConfiguration) any, (MojoParameters) any, log);
result = new File("docker-build.tar");
}};
}
Expand Down