Skip to content
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
126 changes: 121 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Variables
BINARY_NAME = kubectl-oadp
INSTALL_PATH ?= /usr/local/bin
INSTALL_PATH ?= $(HOME)/.local/bin
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")

# Centralized platform definitions to avoid duplication
Expand All @@ -30,6 +30,17 @@ help: ## Show this help message
@echo "Available targets:"
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
@echo ""
@echo "Installation options:"
@echo " \033[36mmake install\033[0m # Install to ~/.local/bin (recommended, no sudo)"
@echo " \033[36mmake install-user\033[0m # Same as install (legacy alias)"
@echo " \033[36mmake install-bin\033[0m # Install to ~/bin (alternative, no sudo)"
@echo " \033[36mmake install-system\033[0m # Install to /usr/local/bin (requires sudo)"
@echo ""
@echo "Uninstall options:"
@echo " \033[36mmake uninstall\033[0m # Remove from user locations (no sudo)"
@echo " \033[36mmake uninstall-system\033[0m # Remove from system locations (requires sudo)"
@echo " \033[36mmake uninstall-all\033[0m # Remove from all locations (user + system)"
@echo ""
@echo "Build with different platforms:"
@echo " make build PLATFORM=linux/amd64"
@echo " make build PLATFORM=linux/arm64"
Expand Down Expand Up @@ -59,11 +70,116 @@ build: ## Build the kubectl plugin binary (use PLATFORM=os/arch for cross-compil

# Installation targets
.PHONY: install
install: build ## Build and install the kubectl plugin
install: build ## Build and install the kubectl plugin to ~/.local/bin (no sudo required)
@echo "Installing $(BINARY_NAME) to $(INSTALL_PATH)..."
mv $(BINARY_NAME) $(INSTALL_PATH)/
@echo "✅ $(BINARY_NAME) installed successfully!"
@echo "You can now use: kubectl oadp --help"
@mkdir -p $(INSTALL_PATH)
cp $(BINARY_NAME) $(INSTALL_PATH)/
@echo "✅ Installed to $(INSTALL_PATH)"
@echo ""
@PATH_UPDATED=false; \
PATH_IN_CONFIG=false; \
if [[ ":$$PATH:" != *":$(INSTALL_PATH):"* ]]; then \
if [[ "$$SHELL" == */zsh* ]] && [[ -f "$$HOME/.zshrc" ]]; then \
if ! grep -q "/.local/bin" "$$HOME/.zshrc" 2>/dev/null; then \
echo 'export PATH="$$HOME/.local/bin:$$PATH"' >> "$$HOME/.zshrc"; \
echo "✅ Added to ~/.zshrc"; \
PATH_UPDATED=true; \
else \
echo "ℹ️ Already configured in ~/.zshrc"; \
PATH_IN_CONFIG=true; \
fi; \
elif [[ "$$SHELL" == */bash* ]] && [[ -f "$$HOME/.bashrc" ]]; then \
if ! grep -q "/.local/bin" "$$HOME/.bashrc" 2>/dev/null; then \
echo 'export PATH="$$HOME/.local/bin:$$PATH"' >> "$$HOME/.bashrc"; \
echo "✅ Added to ~/.bashrc"; \
PATH_UPDATED=true; \
else \
echo "ℹ️ Already configured in ~/.bashrc"; \
PATH_IN_CONFIG=true; \
fi; \
else \
echo "⚠️ Add to your shell config: export PATH=\"$(INSTALL_PATH):$$PATH\""; \
PATH_UPDATED=true; \
fi; \
else \
echo "✅ PATH already configured"; \
fi; \
echo ""; \
if [[ "$$PATH_UPDATED" == "true" ]] || [[ "$$PATH_IN_CONFIG" == "true" ]]; then \
echo "🔄 Restart terminal or run: source ~/.zshrc"; \
fi; \
echo "Test: kubectl oadp --help"

.PHONY: install-user
install-user: build ## Build and install the kubectl plugin to ~/.local/bin (no sudo required)
@echo "Installing $(BINARY_NAME) to ~/.local/bin..."
@mkdir -p ~/.local/bin
cp $(BINARY_NAME) ~/.local/bin/
@echo "✅ Installed to ~/.local/bin"
@echo "Add to PATH: export PATH=\"\$$HOME/.local/bin:\$$PATH\""
@echo "Test: kubectl oadp --help"

.PHONY: install-bin
install-bin: build ## Build and install the kubectl plugin to ~/bin (no sudo required)
@echo "Installing $(BINARY_NAME) to ~/bin..."
@mkdir -p ~/bin
cp $(BINARY_NAME) ~/bin/
@echo "✅ Installed to ~/bin"
@echo "Add to PATH: export PATH=\"\$$HOME/bin:\$$PATH\""
@echo "Test: kubectl oadp --help"

.PHONY: install-system
install-system: build ## Build and install the kubectl plugin to /usr/local/bin (requires sudo)
@echo "Installing $(BINARY_NAME) to /usr/local/bin..."
@sudo mv $(BINARY_NAME) /usr/local/bin/
@echo "✅ Installed to /usr/local/bin"
@echo "Test: kubectl oadp --help"

.PHONY: uninstall
uninstall: ## Uninstall the kubectl plugin from user locations
@echo "Removing $(BINARY_NAME) from user locations..."
@removed=false; \
if [ -f "$(INSTALL_PATH)/$(BINARY_NAME)" ]; then \
rm -f "$(INSTALL_PATH)/$(BINARY_NAME)"; \
echo "✅ Removed from $(INSTALL_PATH)"; \
removed=true; \
fi; \
if [ -f "$$HOME/.local/bin/$(BINARY_NAME)" ] && [ "$(INSTALL_PATH)" != "$$HOME/.local/bin" ]; then \
rm -f "$$HOME/.local/bin/$(BINARY_NAME)"; \
echo "✅ Removed from ~/.local/bin"; \
removed=true; \
fi; \
if [ -f "$$HOME/bin/$(BINARY_NAME)" ] && [ "$(INSTALL_PATH)" != "$$HOME/bin" ]; then \
rm -f "$$HOME/bin/$(BINARY_NAME)"; \
echo "✅ Removed from ~/bin"; \
removed=true; \
fi; \
if [ "$$removed" = "false" ]; then \
echo "⚠️ Not found in user locations"; \
fi

.PHONY: uninstall-system
uninstall-system: ## Uninstall the kubectl plugin from system locations (requires sudo)
@echo "Removing $(BINARY_NAME) from system locations..."
@removed=false; \
if [ -f "/usr/local/bin/$(BINARY_NAME)" ]; then \
sudo rm -f "/usr/local/bin/$(BINARY_NAME)"; \
echo "✅ Removed from /usr/local/bin"; \
removed=true; \
fi; \
if [ -f "/usr/bin/$(BINARY_NAME)" ]; then \
sudo rm -f "/usr/bin/$(BINARY_NAME)"; \
echo "✅ Removed from /usr/bin"; \
removed=true; \
fi; \
if [ "$$removed" = "false" ]; then \
echo "⚠️ Not found in system locations"; \
fi

.PHONY: uninstall-all
uninstall-all: ## Uninstall the kubectl plugin from all locations (user + system)
@make --no-print-directory uninstall
@make --no-print-directory uninstall-system

# Testing targets
.PHONY: test
Expand Down
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,22 @@ kubectl oadp --help
### Manual Build and Install

```sh
# Build and install directly
# Recommended: Rootless install (no sudo required)
make install

# Or build manually
make build
sudo mv kubectl-oadp /usr/local/bin/
# After install, refresh your terminal:
source ~/.zshrc # or ~/.bashrc
# OR restart your terminal

# Test the installation
kubectl oadp --help

# Alternative: System-wide install (requires sudo)
make install-system
```

**💡 Important:** After installation, you may need to refresh your terminal or run `source ~/.zshrc` (or `~/.bashrc`) for the `kubectl oadp` command to work.

## Usage Guide

### Non-Admin Backup Operations
Expand Down
35 changes: 33 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,48 @@ func NewVeleroRootCommand() *cobra.Command {
// This factory uses the current kubeconfig context namespace instead of hardcoded openshift-adp
nonAdminFactory := nonadmin.NewNonAdminFactory()

// Create the commands and modify their help text before adding them
backupCmd := backup.NewCommand(veleroFactory)
restoreCmd := restore.NewCommand(veleroFactory)

// Modify help text to replace "velero" with "oadp"
updateCommandHelpText(backupCmd, usagePrefix)
updateCommandHelpText(restoreCmd, usagePrefix)

// Add subcommands to the root command
rootCmd.AddCommand(version.NewCommand(veleroFactory))
rootCmd.AddCommand(backup.NewCommand(veleroFactory))
rootCmd.AddCommand(restore.NewCommand(veleroFactory))
rootCmd.AddCommand(backupCmd)
rootCmd.AddCommand(restoreCmd)

// Custom subcommands - use NonAdmin factory
rootCmd.AddCommand(nonadmin.NewNonAdminCommand(nonAdminFactory))

return rootCmd
}

// updateCommandHelpText recursively updates help text in commands and subcommands
func updateCommandHelpText(cmd *cobra.Command, usagePrefix string) {
// Update examples that contain "velero"
if strings.Contains(cmd.Example, "velero") {
cmd.Example = strings.ReplaceAll(cmd.Example, "velero", usagePrefix)
}

// Update long description if it contains "velero"
if strings.Contains(cmd.Long, "velero") {
cmd.Long = strings.ReplaceAll(cmd.Long, "velero", "oadp")
}

// Update short description if it contains "velero"
if strings.Contains(cmd.Short, "velero") {
cmd.Short = strings.ReplaceAll(cmd.Short, "velero", "oadp")
}

// Recursively update subcommands
for _, subCmd := range cmd.Commands() {
updateCommandHelpText(subCmd, usagePrefix)
}
}

func Execute() {
if err := NewVeleroRootCommand().Execute(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
Expand Down
Loading