Skip to content

Commit

Permalink
Add base64 file name also on KanikoFramework
Browse files Browse the repository at this point in the history
  • Loading branch information
trubbio83 committed Jul 9, 2024
1 parent 25d9064 commit 6dad82d
Showing 1 changed file with 95 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import it.smartcommunitylabdhub.framework.k8s.objects.CoreVolume;
import it.smartcommunitylabdhub.framework.kaniko.runnables.K8sKanikoRunnable;
import jakarta.validation.constraints.NotNull;

import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
Expand All @@ -38,6 +39,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
Expand All @@ -50,8 +52,9 @@ public class K8sKanikoFramework extends K8sBaseFramework<K8sKanikoRunnable, V1Jo
public static final String FRAMEWORK = "k8sbuild";
public static final int DEADLINE_SECONDS = 3600 * 24 * 3; //3 days
private static final TypeReference<HashMap<String, Serializable>> typeRef = new TypeReference<
HashMap<String, Serializable>
>() {};
HashMap<String, Serializable>
>() {
};

private final BatchV1Api batchV1Api;

Expand Down Expand Up @@ -102,44 +105,49 @@ public K8sKanikoRunnable run(K8sKanikoRunnable runnable) throws K8sFrameworkExce
Optional<List<ContextRef>> contextRefsOpt = Optional.ofNullable(runnable.getContextRefs());
Optional<List<ContextSource>> contextSourcesOpt = Optional.ofNullable(runnable.getContextSources());
V1ConfigMap configMap = new V1ConfigMap()
.metadata(new V1ObjectMeta().name("init-config-map-" + runnable.getId()).labels(buildLabels(runnable)))
.data(
MapUtils.mergeMultipleMaps(
//dockerfile
Map.of("Dockerfile", runnable.getDockerFile()),
// Generate context-refs.txt if exist
contextRefsOpt
.map(contextRefsList ->
Map.of(
"context-refs.txt",
contextRefsList
.stream()
.map(v ->
v.getProtocol() + "," + v.getDestination() + "," + v.getSource() + "\n"
)
.collect(Collectors.joining(""))
)
)
.orElseGet(Map::of),
// Generate context-sources.txt if exist
contextSourcesOpt
.map(contextSources ->
contextSources
.stream()
.collect(
Collectors.toMap(
ContextSource::getName,
c ->
new String(
Base64.getDecoder().decode(c.getBase64()),
StandardCharsets.UTF_8
)
)
)
.metadata(new V1ObjectMeta().name("init-config-map-" + runnable.getId()).labels(buildLabels(runnable)))
.data(
MapUtils.mergeMultipleMaps(
//dockerfile
Map.of("Dockerfile", runnable.getDockerFile()),
// Generate context-refs.txt if exist
contextRefsOpt
.map(contextRefsList ->
Map.of(
"context-refs.txt",
contextRefsList
.stream()
.map(v ->
v.getProtocol() + "," + v.getDestination() + "," + v.getSource() + "\n"
)
.collect(Collectors.joining(""))
)
)
.orElseGet(Map::of),
// Generate context-sources.txt if exist
contextSourcesOpt
.map(contextSources ->
contextSources
.stream()
.collect(
Collectors.toMap(
c -> Base64.getUrlEncoder().withoutPadding().encodeToString(c.getName().getBytes()),
c -> new String(
Base64.getDecoder().decode(c.getBase64()),
StandardCharsets.UTF_8
)
)
)
)
.orElseGet(Map::of),
contextSourcesOpt
.map(contextSources -> Map.of("context-sources-map.txt",
contextSources.stream()
.map(c -> Base64.getUrlEncoder().withoutPadding().encodeToString(c.getName().getBytes()) + "," + c.getName() + "\n")
.collect(Collectors.joining(""))
)).orElseGet(Map::of)
)
.orElseGet(Map::of)
)
);
);

coreV1Api.createNamespacedConfigMap(namespace, configMap, null, null, null, null);
} catch (ApiException | NullPointerException e) {
Expand Down Expand Up @@ -230,17 +238,17 @@ public V1Job build(K8sKanikoRunnable runnable) throws K8sFrameworkException {
// Generate jobName and ContainerName
String jobName = k8sBuilderHelper.getJobName(runnable.getRuntime(), runnable.getTask(), runnable.getId());
String containerName = k8sBuilderHelper.getContainerName(
runnable.getRuntime(),
runnable.getTask(),
runnable.getId()
runnable.getRuntime(),
runnable.getTask(),
runnable.getId()
);

log.debug("build k8s job for {}", jobName);

//build destination image name and set to runnable
String prefix =
(StringUtils.hasText(imageRegistry) ? imageRegistry + "/" : "") +
(StringUtils.hasText(imagePrefix) ? imagePrefix + "-" : "");
(StringUtils.hasText(imageRegistry) ? imageRegistry + "/" : "") +
(StringUtils.hasText(imagePrefix) ? imagePrefix + "-" : "");
// workaround: update image name only first time
String imageName = runnable.getImage();
if (StringUtils.hasText(prefix) && !runnable.getImage().startsWith(prefix)) {
Expand All @@ -256,10 +264,10 @@ public V1Job build(K8sKanikoRunnable runnable) throws K8sFrameworkException {

// Create sharedVolume
CoreVolume sharedVolume = new CoreVolume(
CoreVolume.VolumeType.empty_dir,
"/shared",
"shared-dir",
Map.of("sizeLimit", "100Mi")
CoreVolume.VolumeType.empty_dir,
"/shared",
"shared-dir",
Map.of("sizeLimit", "100Mi")
);

List<CoreVolume> coreVolumes = new ArrayList<>();
Expand All @@ -271,32 +279,32 @@ public V1Job build(K8sKanikoRunnable runnable) throws K8sFrameworkException {

// Create config map volume
CoreVolume configMapVolume = new CoreVolume(
CoreVolume.VolumeType.config_map,
"/init-config-map",
"init-config-map",
Map.of("name", "init-config-map-" + runnable.getId())
CoreVolume.VolumeType.config_map,
"/init-config-map",
"init-config-map",
Map.of("name", "init-config-map-" + runnable.getId())
);
coreVolumes.add(configMapVolume);

// Add secret for kaniko
if (StringUtils.hasText(kanikoSecret)) {
CoreVolume secretVolume = new CoreVolume(
CoreVolume.VolumeType.secret,
"/kaniko/.docker",
kanikoSecret,
Map.of("items", CoreItems.builder().keyToPath(Map.of(".dockerconfigjson", "config.json")).build())
CoreVolume.VolumeType.secret,
"/kaniko/.docker",
kanikoSecret,
Map.of("items", CoreItems.builder().keyToPath(Map.of(".dockerconfigjson", "config.json")).build())
);
if (runnableVolumesOpt.stream().noneMatch(v -> kanikoSecret.equals(v.getName()))) {
coreVolumes.add(secretVolume);
}
}
//Add all volumes
Optional
.ofNullable(runnable.getVolumes())
.ifPresentOrElse(coreVolumes::addAll, () -> runnable.setVolumes(coreVolumes));
.ofNullable(runnable.getVolumes())
.ifPresentOrElse(coreVolumes::addAll, () -> runnable.setVolumes(coreVolumes));

List<String> kanikoArgsAll = new ArrayList<>(
List.of("--dockerfile=/init-config-map/Dockerfile", "--context=/shared", "--destination=" + imageName)
List.of("--dockerfile=/init-config-map/Dockerfile", "--context=/shared", "--destination=" + imageName)
);
// Add Kaniko args
kanikoArgsAll.addAll(kanikoArgs);
Expand All @@ -314,39 +322,39 @@ public V1Job build(K8sKanikoRunnable runnable) throws K8sFrameworkException {

// Build Container
V1Container container = new V1Container()
.name(containerName)
.image(kanikoImage)
.imagePullPolicy("Always")
.imagePullPolicy("IfNotPresent")
.args(kanikoArgsAll)
.resources(resources)
.volumeMounts(volumeMounts)
.envFrom(envFrom)
.env(env);
.name(containerName)
.image(kanikoImage)
.imagePullPolicy("Always")
.imagePullPolicy("IfNotPresent")
.args(kanikoArgsAll)
.resources(resources)
.volumeMounts(volumeMounts)
.envFrom(envFrom)
.env(env);

// Create a PodSpec for the container
V1PodSpec podSpec = new V1PodSpec()
.containers(Collections.singletonList(container))
.nodeSelector(buildNodeSelector(runnable))
.affinity(runnable.getAffinity())
.tolerations(buildTolerations(runnable))
.volumes(volumes)
.restartPolicy("Never");
.containers(Collections.singletonList(container))
.nodeSelector(buildNodeSelector(runnable))
.affinity(runnable.getAffinity())
.tolerations(buildTolerations(runnable))
.volumes(volumes)
.restartPolicy("Never");

// Create a PodTemplateSpec with the PodSpec
V1PodTemplateSpec podTemplateSpec = new V1PodTemplateSpec().metadata(metadata).spec(podSpec);

// Add Init container to the PodTemplateSpec
// Build the Init Container
V1Container initContainer = new V1Container()
.name("init-container-" + runnable.getId())
.image(initImage)
.volumeMounts(volumeMounts)
.resources(resources)
.env(env)
.envFrom(envFrom)
//TODO below execute a command that is a Go script
.command(List.of("/bin/bash", "-c", "/app/builder-tool.sh"));
.name("init-container-" + runnable.getId())
.image(initImage)
.volumeMounts(volumeMounts)
.resources(resources)
.env(env)
.envFrom(envFrom)
//TODO below execute a command that is a Go script
.command(List.of("/bin/bash", "-c", "/app/builder-tool.sh"));

// Set initContainer as first container in the PodSpec
podSpec.setInitContainers(Collections.singletonList(initContainer));
Expand All @@ -355,11 +363,11 @@ public V1Job build(K8sKanikoRunnable runnable) throws K8sFrameworkException {

// Create the JobSpec with the PodTemplateSpec
V1JobSpec jobSpec = new V1JobSpec()
.activeDeadlineSeconds(Long.valueOf(activeDeadlineSeconds))
.parallelism(1)
.completions(1)
.backoffLimit(backoffLimit)
.template(podTemplateSpec);
.activeDeadlineSeconds(Long.valueOf(activeDeadlineSeconds))
.parallelism(1)
.completions(1)
.backoffLimit(backoffLimit)
.template(podTemplateSpec);

// Return a new job with metadata and jobSpec
return new V1Job().metadata(metadata).spec(jobSpec);
Expand Down

0 comments on commit 6dad82d

Please sign in to comment.