diff --git a/.goreleaser.yml b/.goreleaser.yml index 00cbe76..e1f515d 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,38 +1,61 @@ before: hooks: - - go mod download + - go mod download builds: -- main: ./cmd/kpexec/main.go - env: - - CGO_ENABLED=0 - goos: - - linux - - darwin - - windows - goarch: - - amd64 - - arm64 - ldflags: - - -X github.com/ssup2/kpexec/pkg/cmd/kpexec.version={{ .Tag }} + - id: kpexec + main: ./cmd/kpexec/main.go + binary: kpexec + env: + - CGO_ENABLED=0 + goos: + - linux + - darwin + - windows + goarch: + - amd64 + - arm64 + ldflags: + - -X github.com/ssup2/kpexec/pkg/cmd/kpexec.version={{ .Tag }} + - id: kubectl-pexec + main: ./cmd/kpexec/main.go + binary: kubectl-pexec + env: + - CGO_ENABLED=0 + goos: + - linux + - darwin + - windows + goarch: + - amd64 + - arm64 + ldflags: + - -X github.com/ssup2/kpexec/pkg/cmd/kpexec.version={{ .Tag }} + - -X github.com/ssup2/kpexec/pkg/cmd/kpexec.build=kubectlPlugin archives: -- replacements: - darwin: Darwin - linux: Linux - windows: Windows + - id: kpexec + builds: + - kpexec + name_template: "kpexec_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}" + replacements: + darwin: Darwin + linux: Linux + windows: Windows + - id: kubectl-pexec + builds: + - kubectl-pexec + name_template: "kubectl_pexec_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}" + replacements: + darwin: Darwin + linux: Linux + windows: Windows checksum: name_template: checksums.txt changelog: sort: asc brews: - name: kpexec + ids: + - kpexec tap: owner: ssup2 name: homebrew-tap - commit_author: - name: ssup2 - email: supsup5642@gmail.com - homepage: https://github.com/ssup2/kpexec - description: Execute a commad in a running container with privilege - license: MIT - install: | - bin.install "kpexec" diff --git a/Makefile b/Makefile index b7debf5..5aa04f5 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ all: test install image .PHONY: install install: - CGO_ENABLED=0 GO111MODULE=on go install -a -ldflags="-X 'github.com/ssup2/kpexec/pkg/cmd/kpexec.version=latest'" ./cmd/kpexec + CGO_ENABLED=0 GO111MODULE=on go build -a -ldflags="-X 'github.com/ssup2/kpexec/pkg/cmd/kpexec.version=latest'" -o ${GOBIN}/kpexec ./cmd/kpexec + CGO_ENABLED=0 GO111MODULE=on go build -a -ldflags="-X 'github.com/ssup2/kpexec/pkg/cmd/kpexec.version=latest' -X 'github.com/ssup2/kpexec/pkg/cmd/kpexec.build=kubectlPlugin'" -o ${GOBIN}/kubectl-pexec ./cmd/kpexec .PHONY: image image: diff --git a/pkg/cmd/kpexec/kpexec.go b/pkg/cmd/kpexec/kpexec.go index 6f63fa5..674557e 100644 --- a/pkg/cmd/kpexec/kpexec.go +++ b/pkg/cmd/kpexec/kpexec.go @@ -32,6 +32,11 @@ func init() { // Const const ( + buildStandAlone = "standAlone" + buildKubectlPlugin = "kubectlPlugin" + binaryStandAlone = "kpexec" + binaryKubectlPlugin = "kubectl pexec" + cnsPodDefaultTimeout = 30 cnsPodLabelKey = "kpexec.ssup2" cnsPodLabelValue = "cnsenter" @@ -53,45 +58,62 @@ const ( contRootDockerVolume = "container-docker-root" contRootDockerPath = "/var/lib/docker" - kpexecExample = ` + flagHelpTemplate = "help for {{.binary}}" + cmdUseTemplate = "{{.binary}} [-n NAMESPACE] POD [-c CONTAINER] -- COMMAND [args...]" + cmdExampleTemplate = ` # Get output from running 'date' command from pod mypod, using the first container by default - kpexec mypod -- date + {{.binary}} mypod -- date # Get output from running 'date' command in date-container from pod mypod and namespace mynamespace - kpexec -n mynamespace mypod -c date-container -- date + {{.binary}} -n mynamespace mypod -c date-container -- date # Switch to raw terminal mode, sends stdin to 'bash' in bash-container from pod mypod # and sends stdout/stderr from 'bash' back to the client - kpexec -it mypod -c bash-container -- bash + {{.binary}} -it mypod -c bash-container -- bash # Enable 'tools' mode - kpexec -it -T mypod -c bash-container -- bash + {{.binary}} -it -T mypod -c bash-container -- bash # Set cnsenter pod's image - kpexec -it -T --cnsenter-img=ssup2/my-cnsenter-tools:latest mypod -c golang-container -- bash + {{.binary}} -it -T --cnsenter-img=ssup2/my-cnsenter-tools:latest mypod -c golang-container -- bash # Run cnsenter pod garbage collector - kpexec --cnsenter-gc + {{.binary}} --cnsenter-gc ` ) // Var var ( version = "latest" + build = buildStandAlone ) // Cmd func New() *cobra.Command { + // Set help, use and command example + var flagHelp, cmdUse, cmdExample string + if build == buildStandAlone { + flagHelp = strings.ReplaceAll(flagHelpTemplate, "{{.binary}}", binaryStandAlone) + cmdUse = strings.ReplaceAll(cmdUseTemplate, "{{.binary}}", binaryStandAlone) + cmdExample = strings.ReplaceAll(cmdExampleTemplate, "{{.binary}}", binaryStandAlone) + } else { + flagHelp = strings.ReplaceAll(flagHelpTemplate, "{{.binary}}", binaryKubectlPlugin) + cmdUse = strings.ReplaceAll(cmdUseTemplate, "{{.binary}}", binaryKubectlPlugin) + cmdExample = strings.ReplaceAll(cmdExampleTemplate, "{{.binary}}", binaryKubectlPlugin) + } + // Get cobra cmd options := &Options{} cmd := &cobra.Command{ - Use: "kpexec [-n NAMESPACE] POD [-c CONTAINER] -- COMMAND [args...]", + Use: cmdUse, DisableFlagsInUseLine: true, Short: "Execute a command with privilige in a container.", Long: "Execute a command with privilige in a container.", - Example: kpexecExample, + Example: cmdExample, Run: func(cmd *cobra.Command, args []string) { - if options.version { + if options.help { + cmd.Help() + } else if options.version { fmt.Printf("version: %s\n", version) } else if len(options.completion) != 0 { if err := options.Complete(cmd, args); err != nil { @@ -125,9 +147,12 @@ func New() *cobra.Command { cmd.Flags().Int32Var(&options.cnsPodTimeout, "cnsenter-to", cnsPodDefaultTimeout, "Set cnsenter pod's creation timeout") cmd.Flags().BoolVar(&options.cnsPodGC, "cnsenter-gc", false, "Run cnsenter pod garbage collector") - cmd.Flags().StringVar(&options.kubeconfig, "kubeconfig", filepath.Join(homedir.HomeDir(), ".kube", "config"), "Absolute path to the kubeconfig file") - cmd.Flags().StringVar(&options.completion, "completion", "", "Output shell completion code for the specified shell (bash or zsh)") + cmd.Flags().BoolVarP(&options.help, "help", "h", false, flagHelp) cmd.Flags().BoolVarP(&options.version, "version", "v", false, "Show version") + cmd.Flags().StringVar(&options.kubeconfig, "kubeconfig", filepath.Join(homedir.HomeDir(), ".kube", "config"), "Absolute path to the kubeconfig file") + if build == buildStandAlone { + cmd.Flags().StringVar(&options.completion, "completion", "", "Output shell completion code for the specified shell (bash or zsh)") + } // Set bash completion flags for name, completion := range bashCompletionFlags { @@ -154,9 +179,10 @@ type Options struct { cnsPodTimeout int32 cnsPodGC bool + help bool + version bool kubeconfig string completion string - version bool } func (o *Options) Complete(cmd *cobra.Command, args []string) error {