Skip to content

Commit ca58cc6

Browse files
committed
cmd/catalog: Migrate to using cobra for CLI flag management
Update the cmd/catalog/main.go and use cobra's CLI library for managing CLI executables and parsing flags. Introduce cmd/catalog/start.go which is responsible for returning a populated command.Command structure that the main function can call and execute. Signed-off-by: timflannagan <[email protected]>
1 parent 26c36d7 commit ca58cc6

File tree

2 files changed

+133
-78
lines changed

2 files changed

+133
-78
lines changed

cmd/catalog/main.go

Lines changed: 49 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ package main
22

33
import (
44
"context"
5-
"flag"
65
"fmt"
76
"net/http"
87
"os"
98
"time"
109

1110
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
12-
log "github.com/sirupsen/logrus"
11+
"github.com/sirupsen/logrus"
1312
utilclock "k8s.io/apimachinery/pkg/util/clock"
1413
k8sscheme "k8s.io/client-go/kubernetes/scheme"
1514
"k8s.io/client-go/tools/clientcmd"
@@ -20,9 +19,7 @@ import (
2019
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
2120
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorstatus"
2221
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/server"
23-
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/signals"
2422
"github.com/operator-framework/operator-lifecycle-manager/pkg/metrics"
25-
olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version"
2623
)
2724

2825
const (
@@ -36,82 +33,34 @@ const (
3633
)
3734

3835
// config flags defined globally so that they appear on the test binary as well
39-
var (
40-
kubeConfigPath = flag.String(
41-
"kubeconfig", "", "absolute path to the kubeconfig file")
42-
43-
wakeupInterval = flag.Duration(
44-
"interval", defaultWakeupInterval, "wakeup interval")
45-
46-
catalogNamespace = flag.String(
47-
"namespace", defaultCatalogNamespace, "namespace where catalog will run and install catalog resources")
48-
49-
configmapServerImage = flag.String(
50-
"configmapServerImage", defaultConfigMapServerImage, "the image to use for serving the operator registry api for a configmap")
51-
52-
opmImage = flag.String(
53-
"opmImage", defaultOPMImage, "the image to use for unpacking bundle content with opm")
54-
55-
utilImage = flag.String(
56-
"util-image", defaultUtilImage, "an image containing custom olm utilities")
57-
58-
writeStatusName = flag.String(
59-
"writeStatusName", defaultOperatorName, "ClusterOperator name in which to write status, set to \"\" to disable.")
60-
61-
debug = flag.Bool(
62-
"debug", false, "use debug log level")
63-
64-
version = flag.Bool("version", false, "displays olm version")
65-
66-
tlsKeyPath = flag.String(
67-
"tls-key", "", "Path to use for private key (requires tls-cert)")
68-
69-
tlsCertPath = flag.String(
70-
"tls-cert", "", "Path to use for certificate key (requires tls-key)")
71-
72-
profiling = flag.Bool("profiling", false, "deprecated")
73-
74-
clientCAPath = flag.String("client-ca", "", "path to watch for client ca bundle")
75-
76-
installPlanTimeout = flag.Duration("install-plan-retry-timeout", 1*time.Minute, "time since first attempt at which plan execution errors are considered fatal")
77-
bundleUnpackTimeout = flag.Duration("bundle-unpack-timeout", 10*time.Minute, "The time limit for bundle unpacking, after which InstallPlan execution is considered to have failed. 0 is considered as having no timeout.")
78-
)
7936

8037
func init() {
8138
metrics.RegisterCatalog()
8239
}
8340

8441
func main() {
85-
// Get exit signal context
86-
ctx, cancel := context.WithCancel(signals.Context())
87-
defer cancel()
88-
89-
// Parse the command-line flags.
90-
flag.Parse()
91-
92-
// Check if version flag was set
93-
if *version {
94-
fmt.Print(olmversion.String())
95-
96-
// Exit early
97-
os.Exit(0)
98-
}
99-
100-
logger := log.New()
101-
if *debug {
102-
logger.SetLevel(log.DebugLevel)
42+
cmd := newRootCmd()
43+
if err := cmd.Execute(); err != nil {
44+
fmt.Fprintln(os.Stderr, err)
45+
os.Exit(1)
10346
}
104-
logger.Infof("log level %s", logger.Level)
47+
}
10548

49+
func (o *options) run(ctx context.Context, logger *logrus.Logger) error {
10650
// If the catalogNamespaceEnvVarName environment variable is set, then update the value of catalogNamespace.
10751
if catalogNamespaceEnvVarValue := os.Getenv(catalogNamespaceEnvVarName); catalogNamespaceEnvVarValue != "" {
10852
logger.Infof("%s environment variable is set. Updating Global Catalog Namespace to %s", catalogNamespaceEnvVarName, catalogNamespaceEnvVarValue)
109-
*catalogNamespace = catalogNamespaceEnvVarValue
53+
o.catalogNamespace = catalogNamespaceEnvVarValue
11054
}
11155

112-
listenAndServe, err := server.GetListenAndServeFunc(logger, tlsCertPath, tlsKeyPath, clientCAPath)
56+
listenAndServe, err := server.GetListenAndServeFunc(
57+
logger,
58+
&o.tlsCertPath,
59+
&o.tlsKeyPath,
60+
&o.clientCAPath,
61+
)
11362
if err != nil {
114-
logger.Fatal("Error setting up health/metric/pprof service: %v", err)
63+
return fmt.Errorf("error setting up health/metric/pprof service: %v", err)
11564
}
11665

11766
go func() {
@@ -121,29 +70,49 @@ func main() {
12170
}()
12271

12372
// create a config client for operator status
124-
config, err := clientcmd.BuildConfigFromFlags("", *kubeConfigPath)
73+
config, err := clientcmd.BuildConfigFromFlags("", o.kubeconfig)
12574
if err != nil {
126-
log.Fatalf("error configuring client: %s", err.Error())
75+
return fmt.Errorf("error configuring client: %s", err.Error())
12776
}
12877
configClient, err := configv1client.NewForConfig(config)
12978
if err != nil {
130-
log.Fatalf("error configuring client: %s", err.Error())
79+
return fmt.Errorf("error configuring client: %s", err.Error())
13180
}
132-
opClient := operatorclient.NewClientFromConfig(*kubeConfigPath, logger)
133-
crClient, err := client.NewClient(*kubeConfigPath)
81+
opClient := operatorclient.NewClientFromConfig(o.kubeconfig, logger)
82+
crClient, err := client.NewClient(o.kubeconfig)
13483
if err != nil {
135-
log.Fatalf("error configuring client: %s", err.Error())
84+
return fmt.Errorf("error configuring client: %s", err.Error())
13685
}
13786

87+
// TODO(tflannag): Use options pattern for catalog operator
13888
// Create a new instance of the operator.
139-
op, err := catalog.NewOperator(ctx, *kubeConfigPath, utilclock.RealClock{}, logger, *wakeupInterval, *configmapServerImage, *opmImage, *utilImage, *catalogNamespace, k8sscheme.Scheme, *installPlanTimeout, *bundleUnpackTimeout)
89+
op, err := catalog.NewOperator(
90+
ctx,
91+
o.kubeconfig,
92+
utilclock.RealClock{},
93+
logger,
94+
o.wakeupInterval,
95+
o.configMapServerImage,
96+
o.opmImage,
97+
o.utilImage,
98+
o.catalogNamespace,
99+
k8sscheme.Scheme,
100+
o.installPlanTimeout,
101+
o.bundleUnpackTimeout,
102+
)
140103
if err != nil {
141-
log.Panicf("error configuring catalog operator: %s", err.Error())
104+
return fmt.Errorf("error configuring catalog operator: %s", err.Error())
142105
}
143106

144-
opCatalogTemplate, err := catalogtemplate.NewOperator(ctx, *kubeConfigPath, logger, *wakeupInterval, *catalogNamespace)
107+
opCatalogTemplate, err := catalogtemplate.NewOperator(
108+
ctx,
109+
o.kubeconfig,
110+
logger,
111+
o.wakeupInterval,
112+
o.catalogNamespace,
113+
)
145114
if err != nil {
146-
log.Panicf("error configuring catalog template operator: %s", err.Error())
115+
return fmt.Errorf("error configuring catalog template operator: %s", err.Error())
147116
}
148117

149118
op.Run(ctx)
@@ -152,9 +121,11 @@ func main() {
152121
opCatalogTemplate.Run(ctx)
153122
<-opCatalogTemplate.Ready()
154123

155-
if *writeStatusName != "" {
156-
operatorstatus.MonitorClusterStatus(*writeStatusName, op.AtLevel(), op.Done(), opClient, configClient, crClient)
124+
if o.writeStatusName != "" {
125+
operatorstatus.MonitorClusterStatus(o.writeStatusName, op.AtLevel(), op.Done(), opClient, configClient, crClient)
157126
}
158127

159128
<-op.Done()
129+
130+
return nil
160131
}

cmd/catalog/start.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"time"
8+
9+
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/signals"
10+
olmversion "github.com/operator-framework/operator-lifecycle-manager/pkg/version"
11+
"github.com/sirupsen/logrus"
12+
"github.com/spf13/cobra"
13+
)
14+
15+
type options struct {
16+
kubeconfig string
17+
catalogNamespace string
18+
configMapServerImage string
19+
opmImage string
20+
utilImage string
21+
writeStatusName string
22+
debug bool
23+
version bool
24+
profiling bool
25+
tlsKeyPath string
26+
tlsCertPath string
27+
clientCAPath string
28+
29+
installPlanTimeout time.Duration
30+
bundleUnpackTimeout time.Duration
31+
wakeupInterval time.Duration
32+
}
33+
34+
func newRootCmd() *cobra.Command {
35+
o := options{}
36+
37+
cmd := &cobra.Command{
38+
Use: "Start",
39+
Short: "Starts the Catalog Operator",
40+
SilenceUsage: true,
41+
RunE: func(cmd *cobra.Command, args []string) error {
42+
if o.version {
43+
fmt.Print(olmversion.String())
44+
return nil
45+
}
46+
47+
logger := logrus.New()
48+
if o.debug {
49+
logger.SetLevel(logrus.DebugLevel)
50+
}
51+
logger.Infof("log level %s", logger.Level)
52+
53+
ctx, cancel := context.WithCancel(signals.Context())
54+
defer cancel()
55+
56+
if err := o.run(ctx, logger); err != nil {
57+
return err
58+
}
59+
return nil
60+
},
61+
}
62+
63+
cmd.Flags().StringVar(&o.kubeconfig, "kubeconfig", os.Getenv("KUBECONFIG"), "absolute path to the kubeconfig file")
64+
cmd.Flags().StringVar(&o.catalogNamespace, "namespace", defaultCatalogNamespace, "namespace where catalog will run and install catalog resources")
65+
cmd.Flags().StringVar(&o.configMapServerImage, "configmapServerImage", defaultConfigMapServerImage, "the image to use for serving the operator registry api for a configmap")
66+
cmd.Flags().StringVar(&o.opmImage, "opmImage", defaultOPMImage, "the image to use for unpacking bundle content with opm")
67+
cmd.Flags().StringVar(&o.utilImage, "util-image", defaultUtilImage, "an image containing custom olm utilities")
68+
cmd.Flags().StringVar(&o.writeStatusName, "writeStatusName", defaultOperatorName, "ClusterOperator name in which to write status, set to \"\" to disable.")
69+
70+
cmd.Flags().BoolVar(&o.debug, "debug", false, "use debug log level")
71+
cmd.Flags().BoolVar(&o.version, "version", false, "displays the olm version")
72+
cmd.Flags().BoolVar(&o.profiling, "profiling", false, "deprecated")
73+
cmd.Flags().MarkDeprecated("profiling", "profiling is now enabled by default")
74+
75+
cmd.Flags().StringVar(&o.tlsKeyPath, "tls-key", "", "path to use for private key (requires tls-cert)")
76+
cmd.Flags().StringVar(&o.tlsCertPath, "tls-cert", "", "path to use for certificate key (requires tls-key)")
77+
cmd.Flags().StringVar(&o.clientCAPath, "client-ca", "", "path to watch for client ca bundle")
78+
79+
cmd.Flags().DurationVar(&o.wakeupInterval, "interval", defaultWakeupInterval, "wakeup interval")
80+
cmd.Flags().DurationVar(&o.bundleUnpackTimeout, "bundle-unpack-timeout", 10*time.Minute, "The time limit for bundle unpacking, after which InstallPlan execution is considered to have failed. 0 is considered as having no timeout.")
81+
cmd.Flags().DurationVar(&o.installPlanTimeout, "install-plan-retry-timeout", 1*time.Minute, "time since first attempt at which plan execution errors are considered fatal")
82+
83+
return cmd
84+
}

0 commit comments

Comments
 (0)