Skip to content

Commit

Permalink
feat(packages): add image copy scripts
Browse files Browse the repository at this point in the history
Signed-off-by: wuhuizuo <[email protected]>
  • Loading branch information
wuhuizuo committed Feb 5, 2024
1 parent bc572fa commit 3efb89e
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 4 deletions.
11 changes: 7 additions & 4 deletions packages/delivery.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
# yaml-language-server: $schema=./delivery-schema.json
image_copy_rules:
hub.pingcap.net/pingcap/tidb/images/tidb-server: # source repository
hub.pingcap.net/pingcap/tidb/images/tidb-server:
- description: delivery the trunk branch images.
tags_regex: [^master$]
dest_repositories: # full repo url
- docker.io/pingcap/tidb
constant_tags: [master, nightly] # override dest tags.
- tags_regex: [^latest$]
constant_tags: [nightly] # add new tags.
- description: publish latest image
tags_regex: [^latest$]
dest_repositories: # full repo url
- docker.io/pingcap/tidb
hub.pingcap.net/pingcap/tiproxy/image:
- tags_regex:
- description: publish trunk and version images.
tags_regex:
- ^v\d+\.\d+\.\d
- ^(main|master)(-.+)?$
dest_repositories:
Expand Down
60 changes: 60 additions & 0 deletions packages/scripts/gen-delivery-image-commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { parse } from "https://deno.land/std/flags/mod.ts";
import * as yaml from "https://deno.land/[email protected]/yaml/mod.ts";

interface Rule {
description?: string;
tags_regex: string[];
dest_repositories: string[];
constant_tags?: string[];
}

interface Config {
[sourceRepo: string]: Rule[];
}

async function generateShellScript(imageUrlWithTag: string, yamlFile: string, outFile: string) {
// Extract image URL and tag
const [imageUrl, tag] = imageUrlWithTag.split(':');

// Read YAML config
yaml.par
const yamlConfig = await readYaml(yamlFile);
const config: Config = yamlConfig.image_copy_rules;

// Retrieve rules for the source repository from the YAML config
const rules = config[imageUrl] || [];

// Open output file
const file = await Deno.open(outFile, { create: true, write: true, truncate: true });

// Loop through rules
for (const rule of rules) {
const { description = "", tags_regex, dest_repositories, constant_tags = [] } = rule;

// Check if the tag matches the tags regex
const isMatch = tags_regex.some(regex => new RegExp(regex).test(tag));
if (isMatch) {
await file.write(new TextEncoder().encode(`# Matching rule found for image URL '${imageUrlWithTag}':\n`));
await file.write(new TextEncoder().encode(`# Description: ${description}\n`));
await file.write(new TextEncoder().encode(`# Source Repository: ${imageUrl}\n`));

// Copy image to destination repositories using crane copy command
for (const destRepo of dest_repositories) {
await file.write(new TextEncoder().encode(`# Destination Repository: ${destRepo}\n`));
await file.write(new TextEncoder().encode(`crane copy ${imageUrlWithTag} ${destRepo}:${tag}\n`));
for (const constTag of constant_tags) {
await file.write(new TextEncoder().encode(`crane tag ${destRepo}:${tag} ${constTag}\n`));
}
}
}
}

// Close output file
file.close();
}

// Parse command-line arguments
const { _: [imageUrlWithTag], yamlFile = "./delivery.yaml", outFile = "./delivery-images.sh" } = parse(Deno.args);

// Example usage
await generateShellScript(imageUrlWithTag, yamlFile, outFile);
56 changes: 56 additions & 0 deletions packages/scripts/gen-delivery-images-with-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -euo pipefail

RELEASE_SCRIPTS_DIR=$(dirname "$(readlink -f "$0")")
PROJECT_ROOT_DIR=$(realpath "${RELEASE_SCRIPTS_DIR}/../..")

# Function to copy container image to destination repositories based on rules defined in YAML config
main() {
local image_url_with_tag="$1"
local yaml_file="${2:-${PROJECT_ROOT_DIR}/packages/delivery.yaml}"
local out_file="${3:-${RELEASE_SCRIPTS_DIR}/delivery-images.sh}"
rm -rf $out_file

# Extract image URL and tag
local image_url=$(echo "$image_url_with_tag" | cut -d ':' -f1)
local tag=$(echo "$image_url_with_tag" | cut -d ':' -f2)

# Retrieve rules for the source repository from the YAML config
local rules=$(yq ".image_copy_rules[\"$image_url\"]" "$yaml_file")
local rule_count=$(yq ".image_copy_rules[\"$image_url\"] | length" "$yaml_file")
if [ $rule_count -eq 0 ]; then
echo "🤷 none rules found for image: $image_url"
exit 0
fi

# Loop through each rule for the source repository
for ri in $(seq 0 $((rule_count - 1))); do
echo $ri
local rule=$(yq ".image_copy_rules[\"$image_url\"][$ri]" "$yaml_file")
description=$(yq '.description' <<< "$rule")
dest_repos=$(yq '.dest_repositories[]' <<< "$rule")
dest_tags=

# Check if the tag matches the tags regex
if yq -e ".tags_regex[] | select(. | test \"$tag\")" 2>&1> /dev/null <<< "$rule" ; then
echo "Matching rule found for image URL '$image_url_with_tag':"
echo " Description: $description"
echo " Source Repository: $image_url"

# Copy image to destination repositories using crane copy command
for dest_repo in $dest_repos; do
echo " Destination Repository: $dest_repo"
echo "crane copy $image_url_with_tag $dest_repo:$tag" >> "$out_file"
for constant_tag in $(yq '.constant_tags[]' <<< "$rule"); do
echo "crane tag $dest_repo:$tag $constant_tag" >> "$out_file"
done
done
fi
done

if [ -f "$out_file" ]; then
echo "✅ Generated shell script: $out_file"
fi
}

main "$@"

0 comments on commit 3efb89e

Please sign in to comment.