Skip to content

Commit

Permalink
Merge branch 'master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
rohanKanojia committed Oct 20, 2021
2 parents 9324967 + edfce28 commit 6448f84
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 86 deletions.
3 changes: 3 additions & 0 deletions doc/changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# ChangeLog

* **0.37-SNAPSHOT**:
- Allow replacement in tags. Added a new replacement `%T` which always adds a timestamp. ([#1491](https://github.com/fabric8io/docker-maven-plugin/pull/1491))
- Only push the `latest` tag if no other tags where specified in docker mode. This can break your build, if you rely on the automatic `latest` tag. ([#1496](https://github.com/fabric8io/docker-maven-plugin/pull/1496))
- Only push the `latest` tag if no other tags where specified in jib mode. This can break your build, if you rely on the automatic `latest` tag. ([#1498](https://github.com/fabric8io/docker-maven-plugin/pull/1498))

* **0.37.0** (2021-08-15)
- Fix stop mojo by taking container name pattern into account (#1168)
Expand Down
5 changes: 5 additions & 0 deletions src/main/asciidoc/inc/image/_naming.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
## Image Names
When specifying the image name in the configuration with the `<name>` field you can use several placeholders which are replaced during runtime by this plugin. In addition you can use regular Maven properties which are resolved by Maven itself.

Replacements can also be used in `<tag>` fields within the the tags of any build configuration.

[cols="1,5"]
|===
| Placeholder | Description
Expand All @@ -20,6 +22,9 @@ When specifying the image name in the configuration with the `<name>` field you

| *%t*
| If the project version ends with `-SNAPSHOT` this placeholder resolves to `snapshot-<timestamp>` where timestamp has the date format `yyMMdd-HHmmss-SSSS` (eg `snapshot-`). This feature is especially useful during development in oder to avoid conflicts when images are to be updated which are still in use. You need to take care yourself of cleaning up old images afterwards, though.

| *%T*
| Timestamp with the format `yyMMdd-HHmmss-SSSS`.
|===

ifeval::["{plugin}" == "docker"]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
package io.fabric8.maven.docker.config;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;

import io.fabric8.maven.docker.util.DeepCopy;
import io.fabric8.maven.docker.util.EnvUtil;
import io.fabric8.maven.docker.util.Logger;
import io.fabric8.maven.docker.util.MojoParameters;
import org.apache.maven.plugins.annotations.Parameter;

import javax.annotation.Nonnull;
import java.io.File;
import java.io.Serializable;
import java.util.*;

/**
* @author roland
* @since 02.09.14
Expand Down Expand Up @@ -432,6 +442,12 @@ public File getAbsoluteDockerTarPath(MojoParameters mojoParams) {
return EnvUtil.prepareAbsoluteSourceDirPath(mojoParams, getDockerArchive().getPath());
}

public void initTags(ConfigHelper.NameFormatter nameFormatter) {
if (tags != null) {
tags = tags.stream().map(nameFormatter::format).collect(Collectors.toList());
}
}

public static class Builder {
private final BuildImageConfiguration config;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public String initAndValidate(ConfigHelper.NameFormatter nameFormatter, Logger l
String minimalApiVersion = null;
if (build != null) {
minimalApiVersion = build.initAndValidate(log);
build.initTags(nameFormatter);
}
if (run != null) {
minimalApiVersion = EnvUtil.extractLargerVersion(minimalApiVersion, run.initAndValidate());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void push(Collection<ImageConfiguration> imageConfigs, int retries, Regis
JibServiceUtil.jibPush(
imageConfiguration,
getRegistryCredentials(registryConfig, true, imageConfiguration, log),
getBuildTarArchive(imageConfiguration, mojoParameters),
getBuildTarArchive(imageConfiguration, mojoParameters), skipTag,
log
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ public void pushImages(Collection<ImageConfiguration> imageConfigs,

AuthConfig authConfig = createAuthConfig(true, new ImageName(name).getUser(), configuredRegistry, registryConfig);

long start = System.currentTimeMillis();
docker.pushImage(name, authConfig, configuredRegistry, retries);
log.info("Pushed %s in %s", name, EnvUtil.formatDurationTill(start));

if (!skipTag) {
for (String tag : imageConfig.getBuildConfiguration().getTags()) {
if (!skipTag && !buildConfig.getTags().isEmpty()) {
for (String tag : buildConfig.getTags()) {
if (tag != null) {
docker.pushImage(new ImageName(name, tag).getFullName(), authConfig, configuredRegistry, retries);
}
}
} else {
long start = System.currentTimeMillis();
docker.pushImage(name, authConfig, configuredRegistry, retries);
log.info("Pushed %s in %s", name, EnvUtil.formatDurationTill(start));
}
}
}
Expand Down
55 changes: 29 additions & 26 deletions src/main/java/io/fabric8/maven/docker/util/DockerFileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
*/
public class DockerFileUtil {

private static final String ARG_PATTERN_REGEX = "\\$(?:\\{(.*)\\}|(.*))";
private static final String ARG_PATTERN_REGEX = "\\$([\\w|\\-|\\.]+)|\\$\\{([\\w|\\-|\\.]+)\\}";

private DockerFileUtil() {}

Expand Down Expand Up @@ -169,35 +169,29 @@ static Map<String, String> extractArgsFromLines(List<String[]> argLines, Map<Str
return result;
}

static String resolveArgValueFromStrContainingArgKey(String argString, Map<String, String> args) {
Pattern argPattern = Pattern.compile(ARG_PATTERN_REGEX);
Matcher matcher = argPattern.matcher(argString);
if (matcher.matches()) {
if (matcher.group(1) != null) {
return args.get(matcher.group(1));
} else if (matcher.group(2) != null) {
return args.get(matcher.group(2));
static String resolveImageTagFromArgs(String imageTagString, Map<String, String> args) {
String resolvedImageString = imageTagString;
Set<String> foundArgs = findAllArgs(imageTagString);
for (String foundArg : foundArgs) {
if (args.containsKey(foundArg)) {
resolvedImageString = resolvedImageString.replaceFirst(String.format("\\$\\{*%s\\}*", foundArg),
args.get(foundArg));
}
}
return null;
return resolvedImageString;
}

private static String resolveImageTagFromArgs(String imageTagString, Map<String, String> args) {
if (imageTagString.startsWith("$")) { // FROM $IMAGE
String resolvedVal = resolveArgValueFromStrContainingArgKey(imageTagString, args);
if (resolvedVal != null) {
return resolvedVal;
}
} else { // FROM image:$TAG_ARG
String[] imageTagArr = imageTagString.split(":");
if (imageTagArr.length > 1) {
String tag = resolveArgValueFromStrContainingArgKey(imageTagArr[1], args);
if (tag != null) {
return imageTagArr[0] + ":" + tag;
}
static Set<String> findAllArgs(String imageTagString) {
Matcher m = Pattern.compile(ARG_PATTERN_REGEX).matcher(imageTagString);
Set<String> args = new HashSet<>();
while(m.find()){
if(m.group(1)!=null){
args.add(m.group(1));
}else if(m.group(2)!=null){
args.add(m.group(2));
}
}
return imageTagString;
return args;
}

private static Reader getFileReaderFromDir(File file) {
Expand Down Expand Up @@ -257,20 +251,29 @@ private static File getHomeDir() {
private static void updateMapWithArgValue(Map<String, String> result, Map<String, String> args, String argString) {
if (argString.contains("=") || argString.contains(":")) {
String[] argStringParts = argString.split("[=:]");
String argStringValue = argString.substring(argStringParts[0].length() + 1);
String argStringKey = argStringParts[0];
String argStringValue = determineFinalArgValue(argString, argStringParts, args);
if (argStringValue.startsWith("\"") || argStringValue.startsWith("'")) {
// Replaces surrounding quotes
argStringValue = argStringValue.replaceAll("^\"|\"|'|'$", "");
} else {
validateArgValue(argStringValue);
}
result.put(argStringParts[0], argStringValue);
result.put(argStringKey, argStringValue);
} else {
validateArgValue(argString);
result.putAll(fetchArgsFromBuildConfiguration(argString, args));
}
}

private static String determineFinalArgValue(String argString, String[] argStringParts, Map<String, String> args) {
String argStringValue = argString.substring(argStringParts[0].length() + 1);
if(args == null){
return argStringValue;
}
return args.getOrDefault(argStringParts[0], argStringValue);
}

private static Map<String, String> fetchArgsFromBuildConfiguration(String argString, Map<String, String> args) {
Map<String, String> argFromBuildConfig = new HashMap<>();
if (args != null) {
Expand Down
25 changes: 22 additions & 3 deletions src/main/java/io/fabric8/maven/docker/util/ImageNameFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
*/
public class ImageNameFormatter implements ConfigHelper.NameFormatter {

public static final String TIMESTAMP_FORMAT = "yyMMdd-HHmmss-SSSS";

private final FormatParameterReplacer formatParamReplacer;

Expand Down Expand Up @@ -70,6 +71,9 @@ private Map<String, FormatParameterReplacer.Lookup> initLookups(final MavenProje
lookups.put("v", new DefaultTagLookup(project, DefaultTagLookup.Mode.PLAIN, now));
lookups.put("t", new DefaultTagLookup(project, DefaultTagLookup.Mode.SNAPSHOT_WITH_TIMESTAMP, now));
lookups.put("l", new DefaultTagLookup(project, DefaultTagLookup.Mode.SNAPSHOT_LATEST, now));

// Simple Timestamp
lookups.put("T", new DefaultTimestampLookup(project, now));
return lookups;
}

Expand Down Expand Up @@ -107,7 +111,7 @@ public String lookup() {
}
String groupId = project.getGroupId();
while (groupId.endsWith(".")) {
groupId = groupId.substring(0,groupId.length() - 1);
groupId = groupId.substring(0, groupId.length() - 1);
}
int idx = groupId.lastIndexOf(".");
return sanitizeName(groupId.substring(idx != -1 ? idx + 1 : 0));
Expand Down Expand Up @@ -150,7 +154,7 @@ public String doTransform(String tag, Date now) {
SNAPSHOT_WITH_TIMESTAMP('t') {
public String doTransform(String tag, Date now) {
if (tag.endsWith("-SNAPSHOT")) {
return "snapshot-" + new SimpleDateFormat("yyMMdd-HHmmss-SSSS").format(now);
return "snapshot-" + new SimpleDateFormat(TIMESTAMP_FORMAT).format(now);
}
return tag;
}
Expand All @@ -175,7 +179,7 @@ public String doTransform(String tag, Date now) {
public String transform(MavenProject project, String tag, Date now) {
// In case the Maven property is also a placeholder, replace it as well
if (Strings.isNullOrEmpty(tag) || tag.equals("%" + letter)) {
tag = project.getVersion();
tag = project.getVersion();
}
return doTransform(tag, now);
}
Expand All @@ -193,6 +197,21 @@ public String lookup() {
}
}

private static class DefaultTimestampLookup extends AbstractLookup {
// timestamp indicating now
private final Date now;


private DefaultTimestampLookup(MavenProject project, Date now) {
super(project);
this.now = now;
}

public String lookup() {
return new SimpleDateFormat(TIMESTAMP_FORMAT).format(now);
}
}

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

// See also ImageConfiguration#doValidate()
Expand Down
27 changes: 11 additions & 16 deletions src/main/java/io/fabric8/maven/docker/util/JibServiceUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,18 @@ public static String getFullImageName(ImageConfiguration imageConfiguration, Str
* @param tarArchive tar archive built during build goal
* @param log Logger
*/
public static void jibPush(ImageConfiguration imageConfiguration, Credential pushCredentials, File tarArchive, Logger log) {
BuildImageConfiguration buildImageConfiguration = imageConfiguration.getBuildConfiguration();
String imageName = getFullImageName(imageConfiguration, null);
public static void jibPush(ImageConfiguration imageConfiguration, Credential pushCredentials, File tarArchive, boolean skipTag, Logger log) {
BuildImageConfiguration buildConfig = imageConfiguration.getBuildConfiguration();
try {
for (String tag : getAllImageTags(buildImageConfiguration.getTags(), imageName)) {
String imageNameWithTag = getFullImageName(imageConfiguration, tag);
log.info("Pushing image: %s", imageNameWithTag);
pushImage(TarImage.at(tarArchive.toPath()), imageNameWithTag, pushCredentials, log);
if (!skipTag && !buildConfig.getTags().isEmpty()) {
for (String tag : buildConfig.getTags()) {
String imageNameWithTag = getFullImageName(imageConfiguration, tag);
log.info("Pushing image: %s", imageNameWithTag);
pushImage(TarImage.at(tarArchive.toPath()), imageNameWithTag, pushCredentials, log);
}
} else {
String imageName = getFullImageName(imageConfiguration, null);
pushImage(TarImage.at(tarArchive.toPath()), imageName, pushCredentials, log);
}
} catch (IllegalStateException e) {
log.error("Exception occurred while pushing the image: %s", imageConfiguration.getName());
Expand Down Expand Up @@ -194,15 +198,6 @@ private static JibContainerBuilder populateContainerBuilderFromImageConfiguratio
return containerBuilder;
}

static Set<String> getAllImageTags(List<String> tags, String imageName) {
ImageName tempImage = new ImageName(imageName);
Set<String> tagSet = tags.stream().filter(Objects::nonNull).collect(Collectors.toSet());
if (!tempImage.getTag().isEmpty()) {
tagSet.add(tempImage.getTag());
}
return tagSet;
}

static ImageFormat getImageFormat(String jibImageFormat) {
if (jibImageFormat != null && jibImageFormat.toLowerCase().equalsIgnoreCase("oci")) {
return ImageFormat.OCI;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public void testPushWithNoConfigurations(@Mocked JibServiceUtil jibServiceUtil)
// Then
// @formatter:off
new Verifications() {{
JibServiceUtil.jibPush((ImageConfiguration) any, (Credential) any, (File) any, logger); times = 0;
JibServiceUtil.jibPush((ImageConfiguration) any, (Credential) any, (File) any, false, logger); times = 0;
}};
// @formatter:on
}
Expand All @@ -164,6 +164,7 @@ public void testPushWithConfiguration(@Mocked JibServiceUtil jibServiceUtil) thr
imageConfiguration,
Credential.from("testuserpush", "testpass"),
(File)any,
false,
logger);
times = 1;
}};
Expand Down

0 comments on commit 6448f84

Please sign in to comment.