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
1 change: 1 addition & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func NewCertManagerCtlCommand(ctx context.Context, in io.Reader, out, err io.Wri
return logf.ValidateAndApply(logOptions)
},
SilenceErrors: true, // Errors are already logged when calling cmd.Execute()
SilenceUsage: true, // Don't print usage when an error occurs
Copy link
Member Author

@inteon inteon Mar 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not want cobra to print the usage every time there is an error.

}
cmds.SetUsageTemplate(usageTemplate())

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ require (
github.com/fatih/camelcase v1.0.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
Expand Down
36 changes: 0 additions & 36 deletions internal/util/context.go

This file was deleted.

22 changes: 12 additions & 10 deletions internal/util/signal.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package util

import (
"context"
"fmt"
"os"
"os/signal"
"syscall"
Expand All @@ -40,35 +42,35 @@ const (
)

// SetupExitHandler:
// A stop channel is returned which is closed on receiving a shutdown signal (SIGTERM
// A context is returned which is canceled on receiving a shutdown signal (SIGTERM
// or SIGINT). If a second signal is caught, the program is terminated directly with
// exit code 130.
// SetupExitHandler also returns an exit function, this exit function calls os.Exit(...)
// if there is a exit code in the errorExitCodeChannel.
// The errorExitCodeChannel receives exit codes when SetExitCode is called or when
// a shutdown signal is received (only if exitBehavior is AlwaysErrCode).
func SetupExitHandler(exitBehavior ExitBehavior) (<-chan struct{}, func()) {
func SetupExitHandler(parentCtx context.Context, exitBehavior ExitBehavior) (context.Context, func()) {
close(onlyOneSignalHandler) // panics when called twice

stop := make(chan struct{})
ctx, cancel := context.WithCancelCause(parentCtx)
c := make(chan os.Signal, 2)
signal.Notify(c, shutdownSignals...)
go func() {
// first signal. Close stop chan and pass exit code to exitCodeChannel.
exitCode := 128 + int((<-c).(syscall.Signal))
// first signal. Cancel context and pass exit code to errorExitCodeChannel.
signalInt := int((<-c).(syscall.Signal))
if exitBehavior == AlwaysErrCode {
errorExitCodeChannel <- exitCode
errorExitCodeChannel <- signalInt
}
close(stop)
cancel(fmt.Errorf("received signal %d", signalInt))
// second signal. Exit directly.
<-c
os.Exit(130)
}()

return stop, func() {
return ctx, func() {
select {
case signal := <-errorExitCodeChannel:
os.Exit(signal)
case signalInt := <-errorExitCodeChannel:
os.Exit(128 + signalInt)
default:
// Do not exit, there are no exit codes in the channel,
// so just continue and let the main function go out of
Expand Down
8 changes: 5 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@ import (
"strings"

cmdutil "k8s.io/kubectl/pkg/cmd/util"
ctrl "sigs.k8s.io/controller-runtime"

logf "github.com/cert-manager/cert-manager/pkg/logs"
ctlcmd "github.com/cert-manager/cmctl/v2/cmd"
"github.com/cert-manager/cmctl/v2/internal/util"
)

func main() {
stopCh, exit := util.SetupExitHandler(util.AlwaysErrCode)
ctx, exit := util.SetupExitHandler(context.Background(), util.AlwaysErrCode)
defer exit() // This function might call os.Exit, so defer last

logf.InitLogs()
defer logf.FlushLogs()
ctrl.SetLogger(logf.Log)
ctx = logf.NewContext(ctx, logf.Log, "cmctl")

// In cmctl, we are using cmdutil.CheckErr, a kubectl utility function that creates human readable
// error messages from errors. By default, this function will call os.Exit(1) if it receives an error.
Expand All @@ -56,10 +59,9 @@ func main() {
runtime.Goexit() // Do soft exit (handle all defers, that should set correct exit code)
})

ctx := util.ContextWithStopCh(context.Background(), stopCh)
cmd := ctlcmd.NewCertManagerCtlCommand(ctx, os.Stdin, os.Stdout, os.Stderr)

if err := cmd.Execute(); err != nil {
if err := cmd.ExecuteContext(ctx); err != nil {
cmdutil.CheckErr(err)
}
}
15 changes: 8 additions & 7 deletions pkg/approve/approve.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"

Expand Down Expand Up @@ -68,18 +67,20 @@ func newOptions(ioStreams genericclioptions.IOStreams) *Options {
}
}

func NewCmdApprove(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdApprove(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := newOptions(ioStreams)

cmd := &cobra.Command{
Use: "approve",
Short: "Approve a CertificateRequest",
Long: `Mark a CertificateRequest as Approved, so it may be signed by a configured Issuer.`,
Example: example,
ValidArgsFunction: factory.ValidArgsListCertificateRequests(ctx, &o.Factory),
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Validate(args))
cmdutil.CheckErr(o.Run(ctx, args))
ValidArgsFunction: factory.ValidArgsListCertificateRequests(&o.Factory),
PreRunE: func(cmd *cobra.Command, args []string) error {
return o.Validate(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run(cmd.Context(), args)
},
}

Expand All @@ -88,7 +89,7 @@ func NewCmdApprove(ctx context.Context, ioStreams genericclioptions.IOStreams) *
cmd.Flags().StringVar(&o.Message, "message", fmt.Sprintf("manually approved by %q", build.Name()),
"The message to give as to why this CertificateRequest was approved.")

o.Factory = factory.New(ctx, cmd)
o.Factory = factory.New(cmd)

return cmd
}
Expand Down
13 changes: 7 additions & 6 deletions pkg/check/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/cli-runtime/pkg/genericclioptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"

Expand Down Expand Up @@ -83,22 +82,24 @@ func (o *Options) Complete() error {
}

// NewCmdCheckApi returns a cobra command for checking creating cert-manager resources against the K8S API server
func NewCmdCheckApi(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdCheckApi(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewOptions(ioStreams)

cmd := &cobra.Command{
Use: "api",
Short: "Check if the cert-manager API is ready",
Long: checkApiDesc,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete())
cmdutil.CheckErr(o.Run(ctx))
PreRunE: func(cmd *cobra.Command, args []string) error {
return o.Complete()
},
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run(cmd.Context())
},
}
cmd.Flags().DurationVar(&o.Wait, "wait", 0, "Wait until the cert-manager API is ready (default 0s = poll once)")
cmd.Flags().DurationVar(&o.Interval, "interval", 5*time.Second, "Time between checks when waiting, must include unit, e.g. 1m or 10m")

o.Factory = factory.New(ctx, cmd)
o.Factory = factory.New(cmd)

return cmd
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/check/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ import (
)

// NewCmdCheck returns a cobra command for checking cert-manager components.
func NewCmdCheck(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdCheck(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
cmds := NewCmdCreateBare()
cmds.AddCommand(api.NewCmdCheckApi(ctx, ioStreams))
cmds.AddCommand(api.NewCmdCheckApi(setupCtx, ioStreams))

return cmds
}
Expand Down
5 changes: 2 additions & 3 deletions pkg/completion/bash.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package completion
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/cert-manager/cmctl/v2/pkg/build"
)
Expand All @@ -39,8 +38,8 @@ Bash:
$ {{.BuildName}} completion bash > /usr/local/etc/bash_completion.d/{{.BuildName}}
`),
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
util.CheckErr(cmd.Root().GenBashCompletion(ioStreams.Out))
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Root().GenBashCompletion(ioStreams.Out)
},
}
}
2 changes: 1 addition & 1 deletion pkg/completion/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions"
)

func NewCmdCompletion(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdCompletion(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
cmds := &cobra.Command{
Use: "completion",
Short: "Generate completion scripts for the cert-manager CLI",
Expand Down
5 changes: 2 additions & 3 deletions pkg/completion/fish.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package completion
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/cert-manager/cmctl/v2/pkg/build"
)
Expand All @@ -35,8 +34,8 @@ func newCmdCompletionFish(ioStreams genericclioptions.IOStreams) *cobra.Command
$ {{.BuildName}} completion fish > ~/.config/fish/completions/{{.BuildName}}.fish
`),
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
util.CheckErr(cmd.Root().GenFishCompletion(ioStreams.Out, true))
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Root().GenFishCompletion(ioStreams.Out, true)
},
}
}
5 changes: 2 additions & 3 deletions pkg/completion/powershell.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package completion
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/cert-manager/cmctl/v2/pkg/build"
)
Expand All @@ -36,8 +35,8 @@ func newCmdCompletionPowerShell(ioStreams genericclioptions.IOStreams) *cobra.Co
# and source this file from your PowerShell profile.
`),
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
util.CheckErr(cmd.Root().GenPowerShellCompletion(ioStreams.Out))
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Root().GenPowerShellCompletion(ioStreams.Out)
},
}
}
5 changes: 2 additions & 3 deletions pkg/completion/zsh.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package completion
import (
"github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubectl/pkg/cmd/util"

"github.com/cert-manager/cmctl/v2/pkg/build"
)
Expand All @@ -38,8 +37,8 @@ func newCmdCompletionZSH(ioStreams genericclioptions.IOStreams) *cobra.Command {
# You will need to start a new shell for this setup to take effect.
`),
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
util.CheckErr(cmd.Root().GenZshCompletion(ioStreams.Out))
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Root().GenZshCompletion(ioStreams.Out)
},
}
}
10 changes: 6 additions & 4 deletions pkg/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func NewOptions(ioStreams genericclioptions.IOStreams) *Options {
}

// NewCmdConvert returns a cobra command for converting cert-manager resources
func NewCmdConvert(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdConvert(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewOptions(ioStreams)

cmd := &cobra.Command{
Expand All @@ -94,9 +94,11 @@ func NewCmdConvert(ctx context.Context, ioStreams genericclioptions.IOStreams) *
Long: longDesc,
Example: example,
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete())
cmdutil.CheckErr(o.Run())
PreRunE: func(cmd *cobra.Command, args []string) error {
return o.Complete()
},
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run()
},
}

Expand Down
15 changes: 8 additions & 7 deletions pkg/create/certificaterequest/certificaterequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"

Expand Down Expand Up @@ -103,7 +102,7 @@ func NewOptions(ioStreams genericclioptions.IOStreams) *Options {
}

// NewCmdCreateCR returns a cobra command for create CertificateRequest
func NewCmdCreateCR(ctx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
func NewCmdCreateCR(setupCtx context.Context, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewOptions(ioStreams)

cmd := &cobra.Command{
Expand All @@ -112,10 +111,12 @@ func NewCmdCreateCR(ctx context.Context, ioStreams genericclioptions.IOStreams)
Short: "Create a cert-manager CertificateRequest resource, using a Certificate resource as a template",
Long: long,
Example: example,
ValidArgsFunction: factory.ValidArgsListCertificateRequests(ctx, &o.Factory),
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Validate(args))
cmdutil.CheckErr(o.Run(ctx, args))
ValidArgsFunction: factory.ValidArgsListCertificateRequests(&o.Factory),
PreRunE: func(cmd *cobra.Command, args []string) error {
return o.Validate(args)
},
RunE: func(cmd *cobra.Command, args []string) error {
return o.Run(cmd.Context(), args)
},
}
cmd.Flags().StringVar(&o.InputFilename, "from-certificate-file", o.InputFilename,
Expand All @@ -129,7 +130,7 @@ func NewCmdCreateCR(ctx context.Context, ioStreams genericclioptions.IOStreams)
cmd.Flags().DurationVar(&o.Timeout, "timeout", 5*time.Minute,
"Time before timeout when waiting for CertificateRequest to be signed, must include unit, e.g. 10m or 1h")

o.Factory = factory.New(ctx, cmd)
o.Factory = factory.New(cmd)

return cmd
}
Expand Down
Loading