Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion scripts/release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,6 @@ HELM_DEP_UPDATE=${HELM_DEP_UPDATE:-"false"}
binaries_check "${COMMON_BINS[@]}"
helm_check

cd "$SCRIPT_DIR/.."
cd "$PARENT_ROOT"

trap cleanup_tars EXIT
201 changes: 201 additions & 0 deletions scripts/staging/kubectl-oci.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#!/usr/bin/env bash
# Manage kubectl plugin binaries as OCI artifacts.
# Supports both pushing and pulling operations.
# Usage:
# Push: ./kubectl-oci.sh push --tag <tag> --namespace <namespace> [--username <user> --password <token>]
# Pull: ./kubectl-oci.sh pull --tag <tag> --namespace <namespace> [--username <user> --password <token>]

set -euo pipefail

SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]:-"$0"}")")"
ROOT_DIR="$SCRIPT_DIR/../"

# shellcheck source=../utils/log.sh
source "$ROOT_DIR/utils/log.sh"

ACTION=""
TAG=""
NAMESPACE=""
USERNAME=""
PASSWORD=""
REGISTRY="ghcr.io"
PLUGIN="${PLUGIN:-"mayastor"}"
NO_LOGIN=false

usage() {
cat << EOF
Usage: $0 <action> [options]

Actions:
push Push kubectl binaries to $REGISTRY as OCI artifacts
pull Pull kubectl binaries from $REGISTRY OCI artifacts

Options:
--tag <tag> Release tag (required)
--registry <registry> The registry to push/pull from [default=$REGISTRY]
--namespace <namespace> Namespace path (required)
--username <username> Registry username (optional if already logged in)
--password <password> Registry token/password (optional if already logged in)
--no-login Skip login check (useful for CI/CD with pre-auth)
-h, --help Show this help message

Examples:
$0 push --tag v1.0.0 --namespace $PLUGIN/dev --username user --password token
$0 pull --tag v1.0.0 --namespace $PLUGIN/dev
EOF
}

parse_args() {
if [[ $# -lt 1 ]]; then
usage
log_fatal "Error: Action required (push or pull)"
fi

ACTION="$1"
shift

case "$ACTION" in
push|pull)
;;
*)
usage
log_fatal "Error: Invalid action '$ACTION'. Must be 'push' or 'pull'"
;;
esac

while [[ $# -gt 0 ]]; do
case $1 in
--tag)
TAG="$2"
shift 2
;;
--namespace)
NAMESPACE="$2"
shift 2
;;
--registry)
REGISTRY="$2"
shift 2
;;
--username)
USERNAME="$2"
shift 2
;;
--password)
PASSWORD="$2"
shift 2
;;
--no-login)
NO_LOGIN=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
usage
log_fatal "Unknown option: $1"
;;
esac
done

if [[ -z "$TAG" ]] || [[ -z "$NAMESPACE" ]]; then
usage
log_fatal "Error: --tag and --namespace are required"
fi

if [[ -z "${USERNAME:-}" || -z "${PASSWORD:-}" ]]; then
echo "⚠️ No username/password provided — will attempt to use existing oras login session for ${REGISTRY}"
fi

REPOSITORY="${REGISTRY}/${NAMESPACE}/kubectl-${PLUGIN}"
}

# Login to registry (only if needed)
login_registry() {
echo "Checking login status for ${REGISTRY}..."

if oras login "${REGISTRY}" --get >/dev/null 2>&1; then
echo "Already logged in to ${REGISTRY}"
return 0
fi

if [[ -z "${USERNAME:-}" || -z "${PASSWORD:-}" ]]; then
log_fatal "Error: Not logged in to ${REGISTRY} and no credentials provided. Use --username and --password."
fi

echo "Logging in to ${REGISTRY}..."
echo "${PASSWORD}" | oras login "${REGISTRY}" --username "${USERNAME}" --password-stdin
}

# Push kubectl binaries to registry
push_artifacts() {
echo "Pushing kubectl binaries to ${REPOSITORY} with tag ${TAG}"

# Check if artifacts directory exists
if [[ ! -d "artifacts" ]]; then
log_fatal "Error: artifacts directory not found"
fi

# Create a combined tarball of all kubectl binaries
echo "Creating combined tarball of all kubectl binaries..."
local combined_tar="kubectl-$PLUGIN-all-platforms-${TAG}.tar.gz"

tar -czf "${combined_tar}" -C artifacts .

echo "Pushing combined tarball to ${REPOSITORY}:${TAG}"

oras push "${REPOSITORY}:${TAG}" \
--artifact-type application/vnd.$PLUGIN.kubectl.bundle.v1+tar+gzip \
"${combined_tar}"

rm -f "${combined_tar}"

echo "All kubectl binaries pushed successfully as a single bundle!"
echo "Bundle available at: ${REPOSITORY}:${TAG}"
}

# Pull kubectl binaries from registry
pull_artifacts() {
echo "Pulling kubectl binaries bundle from ${REPOSITORY} for release ${TAG}"

echo "Pulling kubectl bundle..."
oras pull "${REPOSITORY}:${TAG}"

local bundle_tar="kubectl-$PLUGIN-all-platforms-${TAG}.tar.gz"

if [[ ! -f "$bundle_tar" ]]; then
log_fatal "Error: Could not find kubectl bundle tarball"
fi

echo "Extracting bundle to artifacts directory"

mkdir -p artifacts/
tar -xzf "$bundle_tar" -C artifacts/
rm -f "$bundle_tar"

echo "Contents of artifacts directory after extraction:"
ls -la artifacts/

echo "All kubectl binaries pulled successfully!"
}

main() {
parse_args "$@"

if [[ "$NO_LOGIN" == false ]]; then
login_registry
fi

case "$ACTION" in
push)
push_artifacts
;;
pull)
pull_artifacts
;;
esac
}

main "$@"
61 changes: 61 additions & 0 deletions scripts/staging/mirror-images.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash

# Mirror container images from source registry to target registry using crane.
# Preserves multi-platform support and image digests.

set -euo pipefail

SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]:-"$0"}")")"
ROOT_DIR="${SCRIPT_DIR}/../.."

# if PARENT_ROOT_DIR is not defined use the one below
: "${PARENT_ROOT_DIR:=$ROOT_DIR}"

source "$ROOT_DIR/scripts/utils/log.sh"
NO_RUN=true . "$PARENT_ROOT_DIR/scripts/release.sh"

IMAGES=()
for name in $DEFAULT_IMAGES; do
image=$($NIX_EVAL -f "$PARENT_ROOT_DIR" "images.$BUILD_TYPE.$name.imageName" --raw --quiet --argstr product_prefix "$PRODUCT_PREFIX")
IMAGES+=("${image##*/}")
done

SOURCE=""
TARGET=""
TAG=""

while [[ $# -gt 0 ]]; do
case $1 in
--source)
SOURCE="$2"
shift 2
;;
--target)
TARGET="$2"
shift 2
;;
--tag)
TAG="$2"
shift 2
;;
*)
log_fatal "Unknown option: $1"
;;
esac
done

if [[ -z "$SOURCE" ]] || [[ -z "$TARGET" ]] || [[ -z "$TAG" ]]; then
log_fatal "Usage: $0 --source <source> --target <target> --tag <tag>"
fi

echo "Mirroring images from ${SOURCE} to ${TARGET} with tag ${TAG}"

for IMAGE in "${IMAGES[@]}"; do
echo "Mirroring ${IMAGE}:${TAG}..."

SRC="${SOURCE}/${IMAGE}:${TAG}"
DEST="${TARGET}/${IMAGE}:${TAG}"
crane copy --platform all "${SRC}" "${DEST}"

echo "✓ Successfully mirrored ${IMAGE}:${TAG}"
done
20 changes: 20 additions & 0 deletions scripts/staging/shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{ pkgs ? import (import ../../nix/sources.nix).nixpkgs {
overlays = [ (_: _: { inherit (import ../../nix/sources.nix); }) (import ../../nix/overlay.nix { }) ];
}
}:
pkgs.mkShellNoCC {
name = "staging-shell";
buildInputs = with pkgs; [
oras
crane
yq-go
jq
] ++ pkgs.lib.optional (builtins.getEnv "IN_NIX_SHELL" == "pure" && pkgs.system != "aarch64-darwin") [
docker
git
curl
nix
kubernetes-helm-wrapped
cacert
];
}
Loading