From 987b24cb9db2957d38b295cd8f3187cca23b728a Mon Sep 17 00:00:00 2001 From: Joe Lee Date: Mon, 23 Dec 2024 16:09:59 +0800 Subject: [PATCH] add install script (#5) * add install script * add hook --- README.md | 35 ++++++---- cmd/root.go | 9 ++- install-binary.sh | 162 ++++++++++++++++++++++++++++++++++++++++++++++ plugin.yaml | 3 + 4 files changed, 195 insertions(+), 14 deletions(-) create mode 100755 install-binary.sh diff --git a/README.md b/README.md index 1e3a0ab..7c9029a 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,21 @@ helm plugin install https://github.com/joelee2012/helm-clean/releases/download/v # Usage ``` -helm clean -h +# helm clean -h + +A helm plugin to clean release by date + Clean/List the release which was updated before duration Examples: # List all release which was updated before 240h helm clean -A -b 240h - # List release was create by chart-1 - helm clean -A -b 240h -f chart-1 + # List release which was created by chart that matched chart-1 + helm clean -A -b 240h -I chart-1 + + # List release was not created by chart that matched chart-1 + helm clean -A -b 240h -E chart-1 # Exclude namespace match pattern helm clean -A -b 240h -e kube-system @@ -33,14 +39,19 @@ Usage: clean [flags] Flags: - -A, --all-namespaces Check releases across all namespaces - -b, --before helm list The last updated time before now, eg: 8h, (default 0) equal helm list - -d, --dry-run Dry run mode only print the release info (default true) - -e, --exclude strings Regular expression ':', the matched - release and namespace will be excluded from the result (can specify multiple) - -f, --filter strings Regular expression, the chart of releases that matched the - expression will be included in the result only (can specify multiple) - -h, --help help for clean - -v, --version version for clean + -A, --all-namespaces Check releases across all namespaces + -b, --before helm list The last updated time before now, eg: 8h, (default 0) equal helm list + -d, --dry-run Dry run mode only print the release info (default true) + -e, --exclude strings Regular expression ':', the matched + release and namespace will be excluded from the result (can specify multiple) + -E, --exclude-chart strings Regular expression, the chart of releases that matched the + expression will be excluded from the result (can specify multiple) + -h, --help help for clean + -i, --include strings Regular expression ':', the matched + release and namespace will be included in result only (can specify multiple) + -I, --include-chart strings Regular expression, the chart of releases that matched the + expression will be included in the result only (can specify multiple) + -o, --output string prints the output in the specified format. Allowed values: table, csv (default "table") + -v, --version version for clean ``` diff --git a/cmd/root.go b/cmd/root.go index 3f482e6..f9d8f3e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -60,7 +60,7 @@ Examples: return nil }, } - rootCmd.Flags().DurationVarP(&clean.Before, "before", "b", 0, "The last updated time before now, eg: 8h, (default 0) equal `helm list`") + rootCmd.Flags().DurationVarP(&clean.Before, "before", "b", 0, "The last updated time before now, eg: 8h, (default 0) equal run 'helm list'") rootCmd.Flags().BoolVarP(&clean.DryRun, "dry-run", "d", true, "Dry run mode only print the release info") rootCmd.Flags().BoolVarP(&clean.AllNamespace, "all-namespaces", "A", false, "Check releases across all namespaces") rootCmd.Flags().StringVarP(&clean.Output, "output", "o", "table", "prints the output in the specified format. Allowed values: table, csv") @@ -107,6 +107,10 @@ func (c *Clean) ListRelease() (ReleaseList, error) { if c.AllNamespace { args = append(args, "-A") } + helm := os.Getenv("HELM_BIN") + if helm == "" { + return nil, fmt.Errorf("require environment variable HELM_BIN, but not found") + } out, err := exec.Command(os.Getenv("HELM_BIN"), args...).Output() if err != nil { return nil, err @@ -115,6 +119,7 @@ func (c *Clean) ListRelease() (ReleaseList, error) { if err := json.Unmarshal(out, &rList); err != nil { return nil, err } + now := time.Now() var result ReleaseList loc, err := time.LoadLocation("Local") @@ -167,7 +172,7 @@ func (c *Clean) Run(w io.Writer) error { } else { for _, release := range rList { - out, err := exec.Command(os.Getenv("HELM_BIN"), "uninstall", "-n", release.Namespace, release.Name).Output() + out, err := exec.Command(os.Getenv("HELM_BIN"), "uninstall", "-n", release.Namespace, release.Name).CombinedOutput() if err != nil { return err } diff --git a/install-binary.sh b/install-binary.sh new file mode 100755 index 0000000..78db13b --- /dev/null +++ b/install-binary.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env sh +# this was copied from git@github.com:databus23/helm-diff + +REPO_URL=$(git remote get-url origin) + +PROJECT_NAME=$(echo "${REPO_URL##*/}" | cut -d '.' -f1) +PROJECT_GH=$(echo "${REPO_URL##*:}" | cut -d '.' -f1) +export GREP_COLOR="never" + +# Convert HELM_BIN and HELM_PLUGIN_DIR to unix if cygpath is +# available. This is the case when using MSYS2 or Cygwin +# on Windows where helm returns a Windows path but we +# need a Unix path + +if command -v cygpath >/dev/null 2>&1; then + HELM_BIN="$(cygpath -u "${HELM_BIN}")" + HELM_PLUGIN_DIR="$(cygpath -u "${HELM_PLUGIN_DIR}")" +fi + +[ -z "$HELM_BIN" ] && HELM_BIN=$(command -v helm) + +[ -z "$HELM_HOME" ] && HELM_HOME=$($HELM_BIN env | grep 'HELM_DATA_HOME' | cut -d '=' -f2 | tr -d '"') + +mkdir -p "$HELM_HOME" + +: "${HELM_PLUGIN_DIR:="$HELM_HOME/plugins/${PROJECT_NAME}"}" + +if [ "$SKIP_BIN_INSTALL" = "1" ]; then + echo "Skipping binary install" + exit +fi + +# which mode is the common installer script running in +SCRIPT_MODE="install" +if [ "$1" = "-u" ]; then + SCRIPT_MODE="update" +fi + +# initArch discovers the architecture for this system. +initArch() { + ARCH=$(uname -m) + case $ARCH in + armv5*) ARCH="armv5" ;; + armv6*) ARCH="armv6" ;; + armv7*) ARCH="armv7" ;; + aarch64) ARCH="arm64" ;; + x86) ARCH="386" ;; + x86_64) ARCH="amd64" ;; + i686) ARCH="386" ;; + i386) ARCH="386" ;; + esac +} + +# initOS discovers the operating system for this system. +initOS() { + OS=$(uname -s) + + case "$OS" in + Windows_NT) OS='windows' ;; + # Msys support + MSYS*) OS='windows' ;; + # Minimalist GNU for Windows + MINGW*) OS='windows' ;; + CYGWIN*) OS='windows' ;; + Darwin) OS='macos' ;; + Linux) OS='linux' ;; + esac +} + +# verifySupported checks that the os/arch combination is supported for +# binary builds. +verifySupported() { + supported="linux-amd64\nlinux-arm64\nfreebsd-amd64\nmacos-amd64\nmacos-arm64\nwindows-amd64" + if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then + echo "No prebuild binary for ${OS}-${ARCH}." + exit 1 + fi + + if command -v curl >/dev/null 2>&1; then + DOWNLOAD_CMD="curl -sSf -L" + elif command -v wget >/dev/null 2>&1; then + DOWNLOAD_CMD="wget -q -O -" + else + echo "Either curl or wget is required" + exit 1 + fi +} + +# getDownloadURL checks the latest available version. +getDownloadURL() { + version=$(git -C "$HELM_PLUGIN_DIR" describe --tags --exact-match 2>/dev/null | sed 's/^v//g' || :) + if [ "$SCRIPT_MODE" = "install" ] && [ -n "$version" ]; then + DOWNLOAD_URL="https://github.com/$PROJECT_GH/releases/download/v$version/${PROJECT_NAME}_${version}_${OS}_${ARCH}.tar.gz" + else + version=$(curl -sL "https://api.github.com/repos/$PROJECT_GH/releases/latest" | grep tag_name | head -1 | sed -r 's/[^:]*: "v([^"]*).*/\1/g') + DOWNLOAD_URL="https://github.com/$PROJECT_GH/releases/download/v$version/${PROJECT_NAME}_${version}_${OS}_${ARCH}.tar.gz" + fi +} + +# Temporary dir +mkTempDir() { + HELM_TMP="$(mktemp -d -t "${PROJECT_NAME}-XXXXXX")" +} +rmTempDir() { + if [ -d "${HELM_TMP:-/tmp/${PROJECT_NAME}-tmp}" ]; then + rm -rf "${HELM_TMP:-/tmp/${PROJECT_NAME}-tmp}" + fi +} + +# downloadFile downloads the latest binary package and also the checksum +# for that binary. +downloadFile() { + PLUGIN_TMP_FILE="${HELM_TMP}/${PROJECT_NAME}.tgz" + echo "Downloading $DOWNLOAD_URL" + $DOWNLOAD_CMD "$DOWNLOAD_URL" >"$PLUGIN_TMP_FILE" +} + +# installFile verifies the SHA256 for the file, then unpacks and +# installs it. +installFile() { + tar xzf "$PLUGIN_TMP_FILE" -C "$HELM_TMP" + HELM_TMP_BIN="$HELM_TMP/${PROJECT_NAME}" + if [ "${OS}" = "windows" ]; then + HELM_TMP_BIN="${HELM_TMP_BIN}.exe" + fi + echo "Preparing to install into ${HELM_PLUGIN_DIR}" + cp "$HELM_TMP_BIN" "$HELM_PLUGIN_DIR/" + cp "$HELM_TMP/plugin.yaml" "$HELM_PLUGIN_DIR/" +} + +# exit_trap is executed if on exit (error or not). +exit_trap() { + result=$? + rmTempDir + if [ "$result" != "0" ]; then + echo "Failed to install $PROJECT_NAME" + printf '\tFor support, go to https://github.com/joelee2012/${PROJECT_NAME}.\n' + fi + exit $result +} + +# testVersion tests the installed client to make sure it is working. +testVersion() { + set +e + echo "$PROJECT_NAME installed into $HELM_PLUGIN_DIR/$PROJECT_NAME" + "$HELM_PLUGIN_DIR/$PROJECT_NAME" -h + set -e +} + +# Execution + +#Stop execution on any error +trap "exit_trap" EXIT +set -e +initArch +initOS +verifySupported +getDownloadURL +mkTempDir +downloadFile +installFile +testVersion diff --git a/plugin.yaml b/plugin.yaml index bc41ad2..366f20f 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -4,3 +4,6 @@ usage: "plugin to clean no updated release" description: "plugin to clean no updated release" useTunnel: true command: "$HELM_PLUGIN_DIR/helm-clean" +hooks: + install: "$HELM_PLUGIN_DIR/install-binary.sh" + update: "$HELM_PLUGIN_DIR/install-binary.sh -u"