diff --git a/docker/kubernetes-agent-tentacle/Dockerfile b/docker/kubernetes-agent-tentacle/Dockerfile index 1de5854ed..46b1ddce7 100644 --- a/docker/kubernetes-agent-tentacle/Dockerfile +++ b/docker/kubernetes-agent-tentacle/Dockerfile @@ -6,12 +6,17 @@ FROM golang:1.22 as bootstrapRunnerBuilder ARG TARGETARCH ARG TARGETOS +ARG architectures="amd64 arm64 386 arm" + COPY docker/kubernetes-agent-tentacle/bootstrapRunner/* /bootstrapRunner/ WORKDIR /bootstrapRunner -# Note: the given ldflags remove debug symbols -RUN go build -ldflags "-s -w" -o "bin/bootstrapRunner" +# Create bin directory for multiple architectures +RUN mkdir -p bin +RUN for arch in $architectures; do \ + GOOS=linux GOARCH=$arch go build -ldflags "-s -w" -o "bin/bootstrapRunner-linux-$arch"; \ + done FROM mcr.microsoft.com/dotnet/runtime-deps:$RuntimeDepsTag @@ -31,9 +36,13 @@ RUN groupadd -g 999 octopus \ EXPOSE 10933 COPY docker/kubernetes-agent-tentacle/scripts/* /scripts/ -COPY --from=bootstrapRunnerBuilder bootstrapRunner/bin/bootstrapRunner /bootstrapRunner +COPY --from=bootstrapRunnerBuilder bootstrapRunner/bin/* /bootstrapRunner/ RUN chmod +x /scripts/*.sh +# Copy the architecture detection script from source and make it executable +COPY docker/kubernetes-agent-tentacle/bootstrapRunner/execute-bootstrapRunner.sh /bootstrapRunner/ +RUN chmod +x /bootstrapRunner/execute-bootstrapRunner.sh + WORKDIR /tmp # Install Tentacle @@ -67,7 +76,7 @@ RUN chgrp -R 0 /opt /usr /.dotnet && \ RUN chgrp 0 /etc /etc/ssl/certs && \ chmod g=u /etc /etc/ssl/certs -ENV BOOTSTRAPRUNNEREXECUTABLEPATH=/bootstrapRunner +ENV BOOTSTRAPRUNNEREXECUTABLEDIRECTORY=/bootstrapRunner/ ENV OCTOPUS_RUNNING_IN_CONTAINER=Y ENV ACCEPT_EULA=N ENV CustomPublicHostName="" diff --git a/docker/kubernetes-agent-tentacle/bootstrapRunner/execute-bootstrapRunner.sh b/docker/kubernetes-agent-tentacle/bootstrapRunner/execute-bootstrapRunner.sh new file mode 100755 index 000000000..bc71c3579 --- /dev/null +++ b/docker/kubernetes-agent-tentacle/bootstrapRunner/execute-bootstrapRunner.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -eu + +# Architecture detection and bootstrap runner selection script +# This script automatically detects the runtime architecture and selects +# the appropriate bootstrapRunner binary for execution. + +# Detect the current architecture +ARCH=$(uname -m) + +# Map architecture names to Go architecture naming +case "$ARCH" in + x86_64) + GO_ARCH="amd64" + ;; + aarch64|arm64) + GO_ARCH="arm64" + ;; + i386|i686) + GO_ARCH="386" + ;; + armv7l|armv6l) + GO_ARCH="arm" + ;; + *) + echo "Error: Unsupported architecture: $ARCH" >&2 + echo "Supported architectures: x86_64, aarch64, arm64, i386, i686, armv7l, armv6l" >&2 + exit 1 + ;; +esac + +# Construct binary name +BINARY_NAME="bootstrapRunner-linux-${GO_ARCH}" + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" + +# Execute the appropriate binary with all arguments passed through +exec "$SCRIPT_DIR/$BINARY_NAME" "$@" \ No newline at end of file diff --git a/docker/kubernetes-agent-tentacle/dev/Dockerfile b/docker/kubernetes-agent-tentacle/dev/Dockerfile index 73fac5398..58c458825 100644 --- a/docker/kubernetes-agent-tentacle/dev/Dockerfile +++ b/docker/kubernetes-agent-tentacle/dev/Dockerfile @@ -6,11 +6,17 @@ FROM golang:1.22 as bootstrapRunnerBuilder ARG TARGETARCH ARG TARGETOS +ARG architectures="amd64 arm64 386 arm" + COPY docker/kubernetes-agent-tentacle/bootstrapRunner/* /bootstrapRunner/ WORKDIR /bootstrapRunner -# Note: the given ldflags remove debug symbols -RUN go build -ldflags "-s -w" -o "bin/bootstrapRunner" +# Create bin directory for multiple architectures +RUN mkdir -p bin + +RUN for arch in $architectures; do \ + GOOS=linux GOARCH=$arch go build -ldflags "-s -w" -o "bin/bootstrapRunner-linux-$arch"; \ + done FROM mcr.microsoft.com/dotnet/runtime-deps:$RuntimeDepsTag @@ -28,9 +34,13 @@ EXPOSE 10933 EXPOSE 7777 COPY docker/kubernetes-agent-tentacle/scripts/* /scripts/ -COPY --from=bootstrapRunnerBuilder bootstrapRunner/bin/bootstrapRunner /bootstrapRunner +COPY --from=bootstrapRunnerBuilder bootstrapRunner/bin/* /bootstrapRunner/ RUN chmod +x /scripts/*.sh +# Copy the architecture detection script from source and make it executable +COPY docker/kubernetes-agent-tentacle/bootstrapRunner/execute-bootstrapRunner.sh /bootstrapRunner/ +RUN chmod +x /bootstrapRunner/execute-bootstrapRunner.sh + COPY docker/kubernetes-agent-tentacle/dev/scripts/* /dev-scripts/ RUN chmod +x /dev-scripts/*.sh @@ -54,7 +64,7 @@ RUN \ # We know this won't reduce the image size at all. It's just to make the filesystem a little tidier. RUN rm -rf /tmp/* -ENV BOOTSTRAPRUNNEREXECUTABLEPATH=/bootstrapRunner +ENV BOOTSTRAPRUNNEREXECUTABLEDIRECTORY=/bootstrapRunner/ ENV OCTOPUS_RUNNING_IN_CONTAINER=Y ENV ACCEPT_EULA=N ENV CustomPublicHostName="" diff --git a/source/Octopus.Tentacle/Kubernetes/KubernetesConfig.cs b/source/Octopus.Tentacle/Kubernetes/KubernetesConfig.cs index 9ea9cdc17..efcb7e521 100644 --- a/source/Octopus.Tentacle/Kubernetes/KubernetesConfig.cs +++ b/source/Octopus.Tentacle/Kubernetes/KubernetesConfig.cs @@ -38,7 +38,7 @@ public static class KubernetesConfig public static string KubernetesMonitorEnabledVariableName => $"{EnvVarPrefix}__KUBERNETESMONITORENABLED"; public static string? KubernetesMonitorEnabled => Environment.GetEnvironmentVariable(KubernetesMonitorEnabledVariableName); - public static string BootstrapRunnerExecutablePath => GetRequiredEnvVar("BOOTSTRAPRUNNEREXECUTABLEPATH", "Unable to determine Bootstrap Runner Executable Path"); + public static string BootstrapRunnerExecutableDirectory => GetRequiredEnvVar("BOOTSTRAPRUNNEREXECUTABLEDIRECTORY", "Unable to determine Bootstrap Runner Executable Directory"); public static string PersistentVolumeSizeVariableName => $"{EnvVarPrefix}__PERSISTENTVOLUMESIZE"; public static string PersistentVolumeSize => GetRequiredEnvVar(PersistentVolumeSizeVariableName, "Unable to determine Persistent Volume Size"); diff --git a/source/Octopus.Tentacle/Kubernetes/KubernetesScriptPodCreator.cs b/source/Octopus.Tentacle/Kubernetes/KubernetesScriptPodCreator.cs index 9309b8b7f..291d78020 100644 --- a/source/Octopus.Tentacle/Kubernetes/KubernetesScriptPodCreator.cs +++ b/source/Octopus.Tentacle/Kubernetes/KubernetesScriptPodCreator.cs @@ -179,8 +179,12 @@ async Task CreatePod(StartKubernetesScriptCommandV1 command, IScriptWorkspace wo LogVerboseToBothLogs($"Creating Kubernetes Pod '{podName}'.", tentacleScriptLog); - workspace.CopyFile(KubernetesConfig.BootstrapRunnerExecutablePath, "bootstrapRunner", true); - + foreach(var file in kubernetesPhysicalFileSystem.EnumerateFiles(KubernetesConfig.BootstrapRunnerExecutableDirectory)) + { + var baseName = Path.GetFileName(file); + workspace.CopyFile(file, baseName, true); + } + var scriptName = Path.GetFileName(workspace.BootstrapScriptFilePath); var workspacePath = Path.Combine("Work", workspace.ScriptTicket.TaskId); @@ -297,10 +301,10 @@ void LogVerboseToBothLogs(string message, InMemoryTentacleScriptLog tentacleScri protected async Task CreateScriptContainer(StartKubernetesScriptCommandV1 command, string podName, string scriptName, string homeDir, string workspacePath, string[]? scriptArguments, InMemoryTentacleScriptLog tentacleScriptLog, V1Container? containerSpec) { var spaceInformation = kubernetesPhysicalFileSystem.GetStorageInformation(); - + var commandString = string.Join(" ", new[] { - $"{homeDir}/Work/{command.ScriptTicket.TaskId}/bootstrapRunner", + $"{homeDir}/Work/{command.ScriptTicket.TaskId}/execute-bootstrapRunner.sh", Path.Combine(homeDir, workspacePath), Path.Combine(homeDir, workspacePath, scriptName) }.Concat(scriptArguments ?? Array.Empty())