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

Add ability to update and track operator auto-instrumentation images #917

Merged
merged 5 commits into from
Sep 19, 2023
Merged
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
28 changes: 27 additions & 1 deletion .github/workflows/update_chart_dependencies.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
name: Check for new chart dependency updates

# Description:
# This workflow automates the process of checking for and updating Helm chart dependencies.
# Specifically, it:
# 1. Checks for new versions of (subchart) dependencies listed in chart.yaml.
# 2. Updates chart.yaml with new versions where applicable.
# 3. If the 'opentelemetry-operator' subchart is updated in chart.yaml, it also updates related
# image tags in values.yaml.

on:
schedule:
# Run every Monday at noon.
- cron: "0 12 * * 1"
workflow_dispatch:
inputs:
DEBUG_MODE:
description: 'Enable debug mode'
required: false
default: 'false'

env:
CHART_YAML: helm-charts/splunk-otel-collector/Chart.yaml
Expand All @@ -21,7 +34,15 @@ jobs:
- name: Update Chart
id: update_chart
run: |
# Run make repo-update to ensure repositories are up-to-date
echo "Update dependencies for Helm chart"

# Set debug argument if DEBUG_MODE is true
DEBUG_ARG=""
if [ "${{ github.event.inputs.DEBUG_MODE }}" == "true" ]; then
DEBUG_ARG="--debug"
fi

# Ensure repositories are up-to-date
make repo-update

# Fetch the latest version using helm search repo
Expand All @@ -44,6 +65,11 @@ jobs:
DEP_LINE=$(yq eval ".dependencies | keys | map(tonumber) | map(select(. != null)) | map(select(. < 10000)) | map(. + 1)" $CHART_YAML | jq ".[] | select(.[\"name\"] == \"${{ matrix.repo }}\")")
sed -i "${DEP_LINE}s/$DEP_PATH/$LATEST_VER/" $CHART_YAML

if [ ${{ matrix.repo }} == "opentelemetry-operator" ]; then
echo "Update Splunk Operator Instrumentation Images if Needed"
./ci_scripts/update-images-operator-otel.sh ${{ matrix.language }} $DEBUG_ARG || exit 1
fi

echo Updating rendered examples
make render

Expand Down
60 changes: 31 additions & 29 deletions .github/workflows/update_instrumentation_dependencies.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
name: Check for new instrumentation versions

# Description:
# This workflow is responsible for checking for new versions of Splunk instrumentation libraries
# used in operator based auto-instrumentation and updating the values.yaml if necessary.

on:
schedule:
# Run every 12th hour at minute 45 past.
- cron: "45 */12 * * *"
workflow_dispatch:
inputs:
DEBUG_MODE:
description: 'Enable debug mode'
required: false
default: 'false'

env:
VALUES_YAML: helm-charts/splunk-otel-collector/values.yaml
Expand All @@ -15,43 +24,36 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
# Currently this workflow will update the listed operator instrumentation dependencies in values.yaml
language: ['java'] # Add other languages here
# Add languages that require version updates here
language: ['java']
steps:
- uses: actions/checkout@v4
- name: swizzle version

- name: Update Version
id: swizzle_version
run: |
REPO=ghcr.io/signalfx/splunk-otel-${{ matrix.language }}/splunk-otel-${{ matrix.language }}
LOCAL_VER=$(grep $REPO $VALUES_YAML | awk -F: '{print $2}' | tr -d ' "')
LATEST_VER=$(curl -qs -H "Accept: application/vnd.github+json" $(echo $LATEST_API | sed "s/{lang}/${{ matrix.language }}/g") | jq -r .tag_name)
echo "LATEST_VER=$LATEST_VER" >> $GITHUB_OUTPUT
echo "Current version of ${{ matrix.language }} is $LOCAL_VER, latest is $LATEST_VER"
echo "Update Splunk Operator Instrumentation for ${{ matrix.language }}"

if [ "$LATEST_VER" == "$LOCAL_VER" ]; then
echo We are already up to date. Nothing else to do.
else
echo 'Verifying that the image is pullable...'
echo '(If this fails, the image version is out of sync with ghcr version)'
docker pull $REPO:$LATEST_VER
echo 'Looks like we are good to update...'
echo Updating to new version in values.yaml
echo "NEED_UPDATE=1" >> $GITHUB_OUTPUT
VLINE=$(grep -n "${REPO}" $VALUES_YAML | cut -f1 -d:)
echo "Line number for ${REPO} in ${VALUES_YAML} is: ${VLINE}"
OLD_VER=$(sed -n "${VLINE}p" $VALUES_YAML | grep -oP 'v\K[0-9.]+')
echo "Old version number is: ${OLD_VER}"
NEW_VER=${LATEST_VER#v} # removes 'v' from the start of the string
echo "New version number is: ${NEW_VER}"
echo "sed: ${VLINE}s/${OLD_VER}/${NEW_VER}/"
sed -i "${VLINE}s/${OLD_VER}/${NEW_VER}/" $VALUES_YAML
# Set debug argument if DEBUG_MODE is true
DEBUG_ARG=""
if [ "${{ github.event.inputs.DEBUG_MODE }}" == "true" ]; then
DEBUG_ARG="--debug"
fi

echo Render chart template
make render
# Run the update script and handle errors
./ci_scripts/update-images-operator-splunk.sh ${{ matrix.language }} $DEBUG_ARG || exit 1

echo "Current git diff:"
git --no-pager diff
# Check if an update is needed
if [ "$NEED_UPDATE" -eq 0 ]; then
echo "No updates detected. Exiting."
exit 0
fi

echo "Rendering chart template..."
make render

echo "Displaying current git diff..."
git --no-pager diff
- name: PR the new version
if: ${{ steps.swizzle_version.outputs.NEED_UPDATE == 1 }}
uses: peter-evans/create-pull-request@v5
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed

- Update Splunk Fluend HEC docker image to v1.3.3 [#924](https://github.com/signalfx/splunk-otel-collector-chart/pull/924)
- Add ability to update and track operator auto-instrumentation images [#917](https://github.com/signalfx/splunk-otel-collector-chart/pull/917)
- [BREAKING CHANGE] Refactored auto-instrumentation image definition from operator.instrumentation.spec.{library}.image
to operator.instrumentation.spec.{library}.repository and operator.instrumentation.spec.{library}.tag.
See [upgrade guidelines](https://github.com/signalfx/splunk-otel-collector-chart/blob/main/UPGRADING.md#0840-0850)

## [0.84.0] - 2023-09-11

Expand Down
31 changes: 31 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# Upgrade guidelines

## 0.84.0 to 0.85.0

The format for defining auto-instrumentation images has been refactored. Previously, the image was
defined using the `operator.instrumentation.spec.{library}.image` format. This has been changed to
separate the repository and tag into two distinct fields: `operator.instrumentation.spec.{library}.repository`
and `operator.instrumentation.spec.{library}.tag`.

If you were defining a custom image under `operator.instrumentation.spec.{library}.image`, update
your `values.yaml` to accommodate this change.

- Before:

```yaml
operator:
instrumentation:
spec:
java:
image: ghcr.io/custom-owner/splunk-otel-java/custom-splunk-otel-java:v1.27.0
```

- After:

```yaml
operator:
instrumentation:
spec:
java:
repository: ghcr.io/custom-owner/splunk-otel-java/custom-splunk-otel-java
tag: v1.27.0
```

## 0.67.0 to 0.68.0

There is a new receiver: [Kubernetes Objects Receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/k8sobjectsreceiver) that can pull or watch any object from Kubernetes API server.
Expand Down
92 changes: 92 additions & 0 deletions ci_scripts/base_util.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/bin/bash
# Base Utility Functions Library For CI/CD
# This script provides a set of utility functions for debugging, variable setting,
# and common CI/CD operations. It's designed to be sourced by other scripts to
# provide a standardized way of setting variables, debugging, and handling common
# tasks like fetching Helm chart resources.

# Note: This utility sets "set -e", which will cause any script that sources it
# to exit if any command fails. Make sure your script is compatible with this behavior.
set -e

# Paths for the Helm chart resources
CHART_FILE_PATH="$SCRIPT_DIR/../helm-charts/splunk-otel-collector/Chart.yaml"
VALUES_FILE_PATH="$SCRIPT_DIR/../helm-charts/splunk-otel-collector/values.yaml"

# Set default OWNER to "signalfx" if not already set
: "${OWNER:=signalfx}" # Sets OWNER to "signalfx" if it is not already set

# Debug mode is off by default but can be enabled with --debug
: "${DEBUG_MODE:=0}" # Sets DEBUG_MODE to 0 if it is not already set

# Iterate over all arguments of the calling script
for arg in "$@"; do
if [[ "$arg" == "--debug" ]]; then
DEBUG_MODE=1 # Enable debug mode
# Remove --debug from arguments
for index in "${!@}"; do
if [[ "${!index}" == "--debug" ]]; then
unset "$index"
break
fi
done
# Re-index the arguments array
set -- "${@}"
fi
done

# ---- Debug Methods ----
# These methods provide functions for setting and debugging variables.
# To use this utility, source it in your script as shown in the example below:
#
# Example:
# ```bash
# #!/bin/bash
# # Source the utility script to get access to its functions and variables
# source /path/to/base_util.sh
#
# # Now you can use the utility functions and variables in this script
# DEBUG_MODE=1 # Turn on debug mode
# setd "my_var" "Hello, World!"
# debug "a string value"
# debug "$TEMP_FILE_WITH_CONTENT_PATH"
# ```

# Function: setd
# Description: Sets a variable and outputs a debug message.
# Usage: setd "variable_name" "value"
setd() {
eval "$1=\"$2\"" # Set a variable with the given name and value
debug "$1" # Call the debug function to output the variable
}

# Function: debug
# Description: Outputs debug information based on the DEBUG_MODE setting.
# Supports variables, strings, and file paths for file content.
# Usage: debug "variable_name"
debug() {
if [[ $DEBUG_MODE -eq 1 ]]; then
local var_name="$1"
local var_value="${!var_name}" # Indirect reference to get the value
if [[ -f "$var_value" ]]; then
echo "[DEBUG] $var_name: Content of file $var_value:"
cat "$var_value"
else
echo "[DEBUG] $var_name: $var_value"
fi
fi
}

# Function: emit_output
# Description: Outputs a given environment variable either to GitHub output or stdout.
# Usage: emit_output "VAR_NAME"
emit_output() {
local var_name="$1"
local var_value="${!var_name}" # Indirect reference to get the value

if [ -n "$GITHUB_OUTPUT" ]; then
echo "${var_name}=${var_value}" >> "$GITHUB_OUTPUT"
else
echo "${var_name}=${var_value}"
fi
}
98 changes: 98 additions & 0 deletions ci_scripts/update-images-operator-otel.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/bin/bash
# Purpose: Updates OpenTelemetry and Splunk images for auto-instrumentation.
# Notes:
# - OpenTelemetry images are centralized and may change with operator subchart updates.
# - Splunk images are decentralized and have a separate update mechanism and release cadence.
#
# Example Usage:
# ./update-images-operator-otel.sh
# ./update-images-operator-otel.sh --debug

# Include the base utility functions for setting and debugging variables
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "$SCRIPT_DIR/base_util.sh"

# ---- Initialize Temporary Files ----
# Create a temporary file to hold a subsection of the values.yaml file
setd "TEMP_VALUES_FILE" "$SCRIPT_DIR/temp_values_subsection.yaml"
# Create a temporary file to store version information
setd "TEMP_VERSIONS" "$SCRIPT_DIR/versions.txt"

# ---- Operator Subchart Version Extraction ----
# Extract the version of the opentelemetry-operator subchart from the main Chart.yaml
# This version helps us fetch the corresponding appVersion and image versions.
SUBCHART_VERSION=$(yq eval '.dependencies[] | select(.name == "opentelemetry-operator") | .version' "$CHART_FILE_PATH")
echo "Opentelemetry Operator Subchart Version: $SUBCHART_VERSION"

# ---- Fetching App Version ----
# Fetch the appVersion corresponding to the Operator subchart Version.
# This is extracted from the subchart's definition in the Chart.yaml file.
SUBCHART_URL="https://raw.githubusercontent.com/open-telemetry/opentelemetry-helm-charts/opentelemetry-operator-$SUBCHART_VERSION/charts/opentelemetry-operator/Chart.yaml"
debug "Fetching: $SUBCHART_URL"
APP_VERSION=$(curl -s "$SUBCHART_URL" | grep 'appVersion:' | awk '{print $2}')
debug "Operator App Version: $APP_VERSION"

# ---- Fetch Version Mapping ----
# Fetch the version mappings from versions.txt for the fetched appVersion.
# This gives us a mapping of image keys to their corresponding version tags.
VERSIONS_URL="https://raw.githubusercontent.com/open-telemetry/opentelemetry-operator/v$APP_VERSION/versions.txt"
debug "Fetching: $VERSIONS_URL"
curl -s "$VERSIONS_URL" > "$TEMP_VERSIONS"
debug "Values from Operator OpenTelemetry versions.txt file containing image tags"
debug "$TEMP_VERSIONS"

# ---- Extract Subsection for Update ----
# Extract the content between "# Auto-instrumentation Libraries (Start)" and "# Auto-instrumentation Libraries (End)"
awk '/# Auto-instrumentation Libraries \(Start\)/,/# Auto-instrumentation Libraries \(End\)/' "$VALUES_FILE_PATH" | grep -v "# Auto-instrumentation Libraries " > "$TEMP_VALUES_FILE"

# ---- Update Image Information ----
while IFS='=' read -r IMAGE_KEY VERSION; do
NEED_UPDATE="${NEED_UPDATE:-0}" # Sets NEED_UPDATE to its current value or 0 if not set
if [[ "$IMAGE_KEY" =~ ^autoinstrumentation-.* ]]; then
# Upstream Operator Values
setd "INST_LIB_NAME" "${IMAGE_KEY#autoinstrumentation-}"
setd "REPOSITORY_UPSTREAM" "ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-${INST_LIB_NAME}"
setd "TAG_UPSTREAM" "${VERSION}"

setd "REPOSITORY_LOCAL_PATH" "${INST_LIB_NAME}.repository"
setd "REPOSITORY_LOCAL" "$(yq eval ".${REPOSITORY_LOCAL_PATH}" "${TEMP_VALUES_FILE}")"

if [[ -z "${REPOSITORY_LOCAL}" || "${REPOSITORY_LOCAL}" != *"splunk"* ]]; then
yq eval -i ".${REPOSITORY_LOCAL_PATH} = \"${REPOSITORY_UPSTREAM}\"" "${TEMP_VALUES_FILE}"

setd "TAG_LOCAL_PATH" "${INST_LIB_NAME}.tag"
setd "TAG_LOCAL" "$(yq eval ".${TAG_LOCAL_PATH}" "${TEMP_VALUES_FILE}")"
if [[ -z "${TAG_LOCAL}" || "${TAG_LOCAL}" == "null" || "${TAG_LOCAL}" != "$TAG_UPSTREAM" ]]; then
debug "Upserting value for ${REPOSITORY_LOCAL}:${TAG_LOCAL}"
yq eval -i ".${TAG_LOCAL_PATH} = \"${TAG_UPSTREAM}\"" "${TEMP_VALUES_FILE}"
setd "NEED_UPDATE" 1
else
debug "Retaining existing value for ${REPOSITORY_LOCAL}:${TAG_LOCAL}"
fi
else
# Splunk instrumentation libraries are updated in a different workflow.
debug "Skipping updating ${REPOSITORY_LOCAL}:${TAG_LOCAL}"
fi
fi
done < "${TEMP_VERSIONS}"

# Emit the NEED_UPDATE variable to either GitHub output or stdout
emit_output "NEED_UPDATE"

# Merge the updated subsection back into values.yaml
# This approach specifically updates only the subsection between the start and end tokens.
# By doing so, we avoid reformatting the entire file, thus preserving the original structure and comments.
awk '
!p && !/# Auto-instrumentation Libraries \(Start\)/ && !/# Auto-instrumentation Libraries \(End\)/ { print $0; next }
/# Auto-instrumentation Libraries \(Start\)/ {p=1; print $0; next}
/# Auto-instrumentation Libraries \(End\)/ {p=0; while((getline line < "'$TEMP_VALUES_FILE'") > 0) printf " %s\n", line; print $0; next}
' "$VALUES_FILE_PATH" > "${VALUES_FILE_PATH}.updated"

# Replace the original values.yaml with the updated version
mv "${VALUES_FILE_PATH}.updated" "$VALUES_FILE_PATH"
# Cleanup temporary files
rm "$TEMP_VALUES_FILE"
rm "$TEMP_VERSIONS"

echo "Image update process completed successfully!"
exit 0
Loading
Loading