-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
143 lines (124 loc) · 3.86 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"bytes"
"context"
"fmt"
"io"
"log"
"os"
"github.com/google/ko/pkg/publish"
yqcmd "github.com/mikefarah/yq/v4/cmd"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
type Registry interface {
Init(context.Context) error
URL() string
}
type CreateRepoRegistry interface {
Registry
RepositoryExists(ctx context.Context, repo string) (bool, error)
CreateRepository(ctx context.Context, repo string) error
}
type SelfAuthRegistry interface {
Registry
GetAuthOption() publish.Option
}
const (
defaultBaseImage = "cgr.dev/chainguard/busybox:latest"
configFileName = "ippon"
configEnvPrefix = "IPPON"
)
var (
outputBuffer bytes.Buffer // easier debugging in case of errors, buffer to store output when running in non verbose mode
)
func tryCallParentPersistentPreRun(cmd *cobra.Command, args []string) error {
if parent := cmd.Parent(); parent != nil {
if parent.PersistentPreRunE != nil {
return parent.PersistentPreRunE(parent, args)
}
}
return nil
}
func buildRegistryCommand(cmdName string) (*cobra.Command, error) {
ctx := context.Background()
registryCmd := &cobra.Command{
Use: cmdName,
Args: cobra.MinimumNArgs(1),
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return tryCallParentPersistentPreRun(cmd, args)
},
}
releaseCmd := &cobra.Command{
Use: "release",
Short: "Build, tag and push an image",
RunE: func(cmd *cobra.Command, args []string) error {
return registryCommand(ctx, cmd, args, cmdName)
},
}
releaseCmd.Flags().Int("max-go-routines", 5, "Maximum number of go routines to use for building and pushing images concurrently. Default is 5.")
releaseCmd.Flags().String("namespace", "", "Okteto namespace to update the kustomization file with the new image digests")
releaseCmd.Flags().String("config", "ippon.yaml", "Path to ippon config file")
registryCmd.AddCommand(releaseCmd)
createMissingCmd := &cobra.Command{
Use: "create-missing-repos",
Short: "Create required and missing repositories in the registry",
RunE: func(cmd *cobra.Command, args []string) error {
return createMissingReposCommand(ctx, cmd, args, cmdName)
},
}
createMissingCmd.Flags().String("namespace", "", "Okteto namespace to use for the missing repositories")
createMissingCmd.Flags().String("config", "ippon.yaml", "Path to ippon config file")
registryCmd.AddCommand(createMissingCmd)
return registryCmd, nil
}
func finishWithError(msg string, err error) {
fmt.Print(outputBuffer.String())
log.SetOutput(os.Stdout)
log.Fatalf("%s: %v\n", msg, err)
}
func init() {
viper.SetConfigName(configFileName)
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.SetDefault("base_image", defaultBaseImage)
viper.SetEnvPrefix(configEnvPrefix)
viper.AutomaticEnv()
}
func main() {
oktetoCommand, err := buildRegistryCommand("okteto")
if err != nil {
finishWithError("failed creating okteto command", err)
}
releaseCommand, err := buildRegistryCommand("prod")
if err != nil {
finishWithError("failed creating release command", err)
}
// so we don't require everyone to install yq directly
// thankfully it's written in Go and with cobra!
yqCmd := yqcmd.New()
rootCmd := &cobra.Command{
Use: "ippon",
Short: "Ippon build and release Go images",
Long: "Ippon make it easy to handle Go images release in a micro-services architecture",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
verbose, err := cmd.Flags().GetBool("verbose")
if err != nil {
return errors.Wrap(err, "failed getting verbose flag")
}
if verbose {
log.SetOutput(os.Stdout)
} else {
log.SetOutput(io.Discard)
}
return nil
},
}
rootCmd.PersistentFlags().Bool("verbose", false, "verbose output")
rootCmd.AddCommand(oktetoCommand, releaseCommand, yqCmd)
err = rootCmd.Execute()
if err != nil {
finishWithError("failed executing command", err)
}
}