Skip to content
Open
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
56 changes: 56 additions & 0 deletions azure-pipelines/automation-agent-migration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
trigger: none
pr: none

parameters:
- name: POOL_MAPPING
type: string
default: 'sonicbld-1es:sonicso1ES-amd64 sonicbld-arm64:sonicso1ES-arm64 sonicbld-armhf:sonicso1ES-armhf sonic-common:sonictest ubuntu-20.02:ubuntu-latest'
- name: BRANCHES
type: string
default: 'master main 202511 202505 202411 202405 202311'
- name: SKIP_REPOS
type: string
default: 'none'
- name: TARGET_REPOS
type: string
default: 'sonic-net/sonic-swss-common sonic-net/sonic-linux-kernel sonic-net/sonic-sairedis sonic-net/sonic-swss sonic-net/sonic-dbsyncd sonic-net/sonic-py-swsssdk sonic-net/sonic-snmpagent p4lang/ptf sonic-net/sonic-utilities aristanetworks/sonic sonic-net/sonic-platform-common sonic-net/sonic-platform-daemons sonic-net/sonic-platform-pdk-pde sonic-net/sonic-frr p4lang/p4-hlir Mellanox/SAI-P4-BM Mellanox/hw-mgmt p/redis-dump-load secdev/scapy sonic-net/sonic-mgmt-framework sonic-net/sonic-ztp sonic-net/sonic-restapi sonic-net/sonic-mgmt-common sonic-net/sonic-wpa-supplicant sonic-net/saibcm-modules nokia/sonic-platform sonic-net/sonic-linkmgrd sonic-net/sonic-pins sonic-net/sonic-dhcp-relay sonic-net/sonic-host-services sonic-net/sonic-gnmi sonic-net/sonic-bmp sonic-net/sonic-genl-packet sonic-net/sonic-dhcpmon sonic-net/sonic-dash-api sonic-net/sonic-dash-ha sonic-net/sonic-stp Marvell-switching/sonic-platform-marvell sonic-net/sonic-platform-vpp Marvell-switching/mrvl-prestera Marvell-switching/sonic-platform-arm64 openconfig/gnoi Marvell-switching/mrvl-teralynx Supervisor/supervisor'

pool: sonic-ubuntu-1c
variables:
- group: sonicbld
steps:
- checkout: self
clean: true
- bash: |
set -ex
sudo apt update
sudo apt install gh jq -y
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
git config --global user.email "sonicbld@microsoft.com"
git config --global user.name "Sonic Automation"
git config --global pull.rebase false
echo $TOKEN | gh auth login --with-token
env:
TOKEN: $(GITHUB-TOKEN)
displayName: Setup env
- bash: |
if [ ! -f scripts/migrate_agent_pool.sh ]; then
echo "Migration script not found at scripts/migrate_agent_pool.sh"
ls -la
exit 1
fi
chmod +x scripts/migrate_agent_pool.sh
scripts/migrate_agent_pool.sh
env:
TOKEN: $(GITHUB-TOKEN)
GITHUB_USER: mssonicbld
POOL_MAPPING: ${{ parameters.POOL_MAPPING }}
BRANCHES: ${{ parameters.BRANCHES }}
SKIP_REPOS: ${{ parameters.SKIP_REPOS }}
TARGET_REPOS: ${{ parameters.TARGET_REPOS }}
displayName: Migrating Agent Pool
continueOnError: true
- bash: |
set -ex
[ -f /tmp/logs/migration_results.log ] && cat /tmp/logs/migration_results.log || echo "No results log found."
displayName: Show Results
149 changes: 149 additions & 0 deletions azure-pipelines/scripts/migrate_agent_pool.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/bin/bash

##########################################################
# Script to automate migration of agent pools across multiple git branches
# in all submodules of the sonic-buildimage repository.
# Usage: ./migrate_agent_pool.sh <source_pool:target_pool> <source_pool:target_pool>... <branch1> <branch2> ...
# Example: ./migrate_agent_pool.sh pool1:poolA pool2:poolB master 202505 202411
# Every argument with a colon (:) is treated as a pool replacement,
# and every other argument is treated as a branch name.
# This will create PRs in each submodule repository for the specified branches
# with the agent pool names replaced as specified.
##########################################################

set -e
mkdir -p /tmp/logs
TMP_DIR=$(mktemp -d)
git config --get advice.detachedHead false

GITHUB_USER="${GITHUB_USER:-mssonicbld}"
COMMIT_MSG="Automated agent pool migration"
PR_TITLE="Automated agent pool migration"
PR_BODY="This PR is created for automated agent pool migration across branches."

PR_BODY+="
Agent pools to be migrated:
"
echo "Agent pools to be migrated:"
for replacement in $POOL_MAPPING; do
OLD="${replacement%%:*}"
NEW="${replacement##*:}"
echo " - ${OLD} -> ${NEW}"
PR_BODY+="- ${OLD} -> ${NEW}"$'\n'
done

PR_BODY+="
Branches processed:
"
echo "Branches to be processed:"
for branch in $BRANCHES; do
echo " - ${branch}"
PR_BODY+="- ${branch}"$'\n'
done

# folders or files to check
FILE_TARGETS=("azure-pipelines" ".azure-pipelines" "azure-pipelines.yml" "azurepipeline.yml")

process_repo() {
local repo="$1"
REPO_BASENAME="${repo##*/}"

for skip in $SKIP_REPOS; do
if [ "${repo}" == "${skip}" ]; then
echo -e "\n============= Skipping repository: ${repo} ============="
return 0
fi
done

echo -e "\n============= Processing repository: ${repo} ============="

git clone https://github.com/$repo "${TMP_DIR}/${REPO_BASENAME}"
pushd "${TMP_DIR}/${REPO_BASENAME}"

if ! git remote | grep -q "mssonicbld"; then
git remote add mssonicbld https://mssonicbld:$TOKEN@github.com/mssonicbld/"${REPO_BASENAME}".git
fi
git fetch origin
git fetch mssonicbld 2>/dev/null || (gh repo fork "${repo}" --clone=false && git fetch mssonicbld)

echo "${repo}" >> /tmp/logs/migration_results.log

for branch in $BRANCHES; do

echo "=== Processing branch [${branch}] for ${repo} ==="

if git show-ref --verify --quiet "refs/remotes/origin/${branch}"; then
git checkout "origin/${branch}"
else
echo "Branch ${branch} does not exist in ${repo}, skipping."
continue
fi

NEW_BRANCH="migrate-agent-pool-${branch}"
if git show-ref --verify --quiet "refs/heads/${NEW_BRANCH}"; then
git branch -D "${NEW_BRANCH}"
fi
if git ls-remote --exit-code --heads mssonicbld "${NEW_BRANCH}" >/dev/null; then
git push mssonicbld --delete "${NEW_BRANCH}"
fi
git checkout -b "${NEW_BRANCH}" origin/"${branch}"

echo "Migrating agent pools in files under $repo"
for replacement in $POOL_MAPPING; do
OLD="${replacement%%:*}"
NEW="${replacement##*:}"
find ${FILE_TARGETS[@]} -type f 2>/dev/null | while read -r file; do
if grep -q "${OLD}" "$file"; then
if sed -i.bak "s/${OLD}/${NEW}/g" "$file"; then
rm -f "${file}.bak"
echo "Updated ${file}: ${OLD} -> ${NEW}"
else
echo "Failed to update ${file}: ${OLD} -> ${NEW}"
fi
fi
done
done

git -C "$repo_path" diff --name-only --diff-filter=M | xargs -r git -C "$repo_path" add
if [ -n "$(git -C "$repo_path" diff --cached --name-only)" ]; then

git commit -s -m "${COMMIT_MSG}"
git push -u mssonicbld "${NEW_BRANCH}"

echo "Creating PR for branch ${branch} in repository ${repo}"

if [ "$(gh pr list --repo "${repo}" --head "${NEW_BRANCH}" --base "${branch}" --json number --jq 'length')" -eq 0 ]; then
PR_TITLE_BRANCH="${PR_TITLE} for branch ${branch}"
PR_URL=$(gh pr create \
--repo "${repo}" \
--head "${GITHUB_USER}:${NEW_BRANCH}" \
--base "${branch}" \
--title "${PR_TITLE_BRANCH}" \
--body "${PR_BODY}" \
2>&1 | grep -Eo 'https://github\.com/[^ ]+')
echo "PR created for branch ${branch} in repository ${repo}: ${PR_URL}"
echo "[PR created][${branch}]: ${PR_URL}" >> /tmp/logs/migration_results.log
else
PR_URL=$(gh pr list --repo "${repo}" --head "${NEW_BRANCH}" --base "${branch}" --json url --jq '.[0].url')
echo "A PR already exists for branch ${NEW_BRANCH} in repository ${repo}. PR updated."
echo "[PR updated][${branch}]: ${PR_URL}" >> /tmp/logs/migration_results.log
fi
MODIFIED_REPOS+=("${repo}-${branch}")
else
echo "No changes detected in branch ${branch} of repository ${repo}"
fi
done

echo -e "========================================\n" >> /tmp/logs/migration_results.log
cd -
}

for repo in $TARGET_REPOS; do
process_repo "$repo"
done
echo "All repos processed."
echo "PRs created in the following repositories:"
for repo in "${MODIFIED_REPOS[@]}"; do
echo " - ${repo}"
done
rm -rf "$TMP_DIR"