0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-16 21:56:37 -05:00

build: split functionality into separate binaries

zot: registry server
zli: zot cli to interact with the zot registry
zui: zot ui (proposed)
zb: zot benchmark (proposed)

Signed-off-by: Ramkumar Chinchani <rchincha@cisco.com>
This commit is contained in:
Ramkumar Chinchani 2022-01-11 01:15:35 +00:00 committed by Ramkumar Chinchani
parent c4d34b7269
commit 4896adad1b
12 changed files with 136 additions and 46 deletions

View file

@ -60,7 +60,7 @@ jobs:
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: bin/zot*
file: bin/z*
tag: ${{ github.ref }}
overwrite: true
file_glob: true

View file

@ -14,7 +14,7 @@ OS ?= linux
ARCH ?= amd64
.PHONY: all
all: swagger binary binary-minimal binary-debug binary-arch binary-arch-minimal exporter-minimal verify-config test test-clean check
all: swagger binary binary-minimal binary-debug binary-arch binary-arch-minimal cli cli-arch exporter-minimal verify-config test test-clean check
.PHONY: binary-minimal
binary-minimal: swagger
@ -36,6 +36,14 @@ binary-arch-minimal: swagger
binary-arch: swagger
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zot-$(ARCH) -tags extended,containers_image_openpgp -v -trimpath -ldflags "-X zotregistry.io/zot/pkg/api/config.Commit=${COMMIT} -X zotregistry.io/zot/pkg/api/config.BinaryType=extended -X zotregistry.io/zot/pkg/api/config.GoVersion=${GO_VERSION} -s -w" ./cmd/zot
.PHONY: cli
cli:
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zli -tags extended,containers_image_openpgp -v -trimpath -ldflags "-X zotregistry.io/zot/pkg/api/config.Commit=${COMMIT} -X zotregistry.io/zot/pkg/api/config.BinaryType=extended -X zotregistry.io/zot/pkg/api/config.GoVersion=${GO_VERSION} -s -w" ./cmd/zli
.PHONY: cli-arch
cli-arch: swagger
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zli-$(ARCH) -tags extended,containers_image_openpgp -v -trimpath -ldflags "-X zotregistry.io/zot/pkg/api/config.Commit=${COMMIT} -X zotregistry.io/zot/pkg/api/config.BinaryType=extended -X zotregistry.io/zot/pkg/api/config.GoVersion=${GO_VERSION} -s -w" ./cmd/zli
.PHONY: exporter-minimal
exporter-minimal: swagger
env CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) go build -o bin/zot-exporter -tags minimal,containers_image_openpgp -v -trimpath ./cmd/exporter

13
cmd/zli/main.go Normal file
View file

@ -0,0 +1,13 @@
package main
import (
"os"
"zotregistry.io/zot/pkg/cli"
)
func main() {
if err := cli.NewCliRootCmd().Execute(); err != nil {
os.Exit(1)
}
}

23
cmd/zli/main_test.go Normal file
View file

@ -0,0 +1,23 @@
package main_test
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
"zotregistry.io/zot/pkg/api"
"zotregistry.io/zot/pkg/api/config"
"zotregistry.io/zot/pkg/cli"
)
func TestIntegration(t *testing.T) {
Convey("Make a new controller", t, func() {
conf := config.New()
c := api.NewController(conf)
So(c, ShouldNotBeNil)
cl := cli.NewCliRootCmd()
So(cl, ShouldNotBeNil)
So(cl.Execute(), ShouldBeNil)
})
}

View file

@ -7,7 +7,7 @@ import (
)
func main() {
if err := cli.NewRootCmd().Execute(); err != nil {
if err := cli.NewServerRootCmd().Execute(); err != nil {
os.Exit(1)
}
}

View file

@ -15,7 +15,7 @@ func TestIntegration(t *testing.T) {
c := api.NewController(conf)
So(c, ShouldNotBeNil)
cl := cli.NewRootCmd()
cl := cli.NewServerRootCmd()
So(cl, ShouldNotBeNil)
So(cl.Execute(), ShouldBeNil)

View file

@ -34,7 +34,7 @@ var (
ErrUnauthorizedAccess = errors.New("cli: unauthorized access. check credentials")
ErrCannotResetConfigKey = errors.New("cli: cannot reset given config key")
ErrConfigNotFound = errors.New("cli: config with the given name does not exist")
ErrNoURLProvided = errors.New("cli: no URL provided in argument or via config. see 'zot config -h'")
ErrNoURLProvided = errors.New("cli: no URL provided in argument or via config")
ErrIllegalConfigKey = errors.New("cli: given config key is not allowed")
ErrScanNotSupported = errors.New("search: scanning of image media type not supported")
ErrCLITimeout = errors.New("cli: Query timed out while waiting for results")

View file

@ -31,8 +31,8 @@ func NewConfigCommand() *cobra.Command {
configCmd := &cobra.Command{
Use: "config <config-name> [variable] [value]",
Example: examples,
Short: "Configure zot CLI",
Long: `Configure default parameters for CLI`,
Short: "Configure zot registry parameters for CLI",
Long: `Configure zot registry parameters for CLI`,
Args: cobra.ArbitraryArgs,
RunE: func(cmd *cobra.Command, args []string) error {
home, err := os.UserHomeDir()
@ -104,8 +104,8 @@ func NewConfigCommand() *cobra.Command {
func NewConfigAddCommand() *cobra.Command {
configAddCmd := &cobra.Command{
Use: "add <config-name> <url>",
Short: "Add configuration for a zot URL",
Long: `Configure CLI for interaction with a zot server`,
Short: "Add configuration for a zot registry",
Long: "Add configuration for a zot registry",
Args: cobra.ExactArgs(twoArgs),
RunE: func(cmd *cobra.Command, args []string) error {
home, err := os.UserHomeDir()
@ -405,16 +405,16 @@ func configNameExists(configs []interface{}, configName string) bool {
}
const (
examples = ` zot config add main https://zot-foo.com:8080
zot config main url
zot config main --list
zot config --list`
examples = ` zli config add main https://zot-foo.com:8080
zli config main url
zli config main --list
zli config --list`
supportedOptions = `
Useful variables:
url zot server URL
showspinner show spinner while loading data [true/false]
verify-tls verify TLS Certificate verification of the server [default: true]`
verify-tls enable TLS certificate verification of the server [default: true]`
nameKey = "_name"

View file

@ -22,8 +22,8 @@ func NewCveCommand(searchService SearchService) *cobra.Command {
cveCmd := &cobra.Command{
Use: "cve [config-name]",
Short: "Lookup CVEs in images hosted on zot",
Long: `List CVEs (Common Vulnerabilities and Exposures) of images hosted on a zot instance`,
Short: "Lookup CVEs in images hosted on the zot registry",
Long: `List CVEs (Common Vulnerabilities and Exposures) of images hosted on the zot registry`,
RunE: func(cmd *cobra.Command, args []string) error {
home, err := os.UserHomeDir()
if err != nil {

View file

@ -23,8 +23,8 @@ func NewImageCommand(searchService SearchService) *cobra.Command {
imageCmd := &cobra.Command{
Use: "images [config-name]",
Short: "List hosted images",
Long: `List images hosted on zot`,
Short: "List images hosted on the zot registry",
Long: `List images hosted on the zot registry`,
RunE: func(cmd *cobra.Command, args []string) error {
home, err := os.UserHomeDir()
if err != nil {
@ -145,6 +145,6 @@ func searchImage(searchConfig searchConfig) error {
const (
spinnerDuration = 150 * time.Millisecond
usageFooter = `
Run 'zot config -h' for details on [config-name] argument
Run 'zli config -h' for details on [config-name] argument
`
)

View file

@ -157,7 +157,8 @@ func newVerifyCmd(conf *config.Config) *cobra.Command {
return verifyCmd
}
func NewRootCmd() *cobra.Command {
// "zot" - registry server.
func NewServerRootCmd() *cobra.Command {
showVersion := false
conf := config.New()
@ -175,12 +176,39 @@ func NewRootCmd() *cobra.Command {
},
}
// "serve"
rootCmd.AddCommand(newServeCmd(conf))
rootCmd.AddCommand(newScrubCmd(conf))
// "verify"
rootCmd.AddCommand(newVerifyCmd(conf))
// "scrub"
rootCmd.AddCommand(newScrubCmd(conf))
// "version"
rootCmd.Flags().BoolVarP(&showVersion, "version", "v", false, "show the version and exit")
return rootCmd
}
// "zli" - client-side cli.
func NewCliRootCmd() *cobra.Command {
showVersion := false
rootCmd := &cobra.Command{
Use: "zli",
Short: "`zli`",
Long: "`zli`",
Run: func(cmd *cobra.Command, args []string) {
if showVersion {
log.Info().Str("distribution-spec", distspec.Version).Str("commit", config.Commit).
Str("binary-type", config.BinaryType).Str("go version", config.GoVersion).Msg("version")
}
_ = cmd.Usage()
cmd.SilenceErrors = false
},
}
// additional cmds
enableCli(rootCmd)
// "version"
rootCmd.Flags().BoolVarP(&showVersion, "version", "v", false, "show the version and exit")
return rootCmd

View file

@ -17,20 +17,38 @@ import (
. "zotregistry.io/zot/test"
)
func TestUsage(t *testing.T) {
func TestServerUsage(t *testing.T) {
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
Convey("Test usage", t, func(c C) {
os.Args = []string{"cli_test", "help"}
err := cli.NewRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
Convey("Test version", t, func(c C) {
os.Args = []string{"cli_test", "--version"}
err := cli.NewRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
}
func TestCliUsage(t *testing.T) {
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
Convey("Test usage", t, func(c C) {
os.Args = []string{"cli_test", "help"}
err := cli.NewCliRootCmd().Execute()
So(err, ShouldBeNil)
})
Convey("Test version", t, func(c C) {
os.Args = []string{"cli_test", "--version"}
err := cli.NewCliRootCmd().Execute()
So(err, ShouldBeNil)
})
}
@ -42,19 +60,19 @@ func TestServe(t *testing.T) {
Convey("Test serve help", t, func(c C) {
os.Args = []string{"cli_test", "serve", "-h"}
err := cli.NewRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
Convey("Test serve config", t, func(c C) {
Convey("unknown config", func(c C) {
os.Args = []string{"cli_test", "serve", path.Join(os.TempDir(), "/x")}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("non-existent config", func(c C) {
os.Args = []string{"cli_test", "serve", path.Join(os.TempDir(), "/x.yaml")}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("bad config", func(c C) {
@ -67,7 +85,7 @@ func TestServe(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "serve", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
})
}
@ -87,7 +105,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("Test verify storage driver different than s3", t, func(c C) {
@ -102,7 +120,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("Test verify subpath storage driver different than s3", t, func(c C) {
@ -118,7 +136,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("Test verify w/ authorization and w/o authentication", t, func(c C) {
@ -134,7 +152,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("Test verify w/ authorization and w/ authentication", t, func(c C) {
@ -151,7 +169,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldNotPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldNotPanic)
})
Convey("Test verify w/ sync and w/o filesystem storage", t, func(c C) {
@ -167,7 +185,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("Test verify with bad sync prefixes", t, func(c C) {
@ -184,7 +202,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("Test verify with bad authorization repo patterns", t, func(c C) {
@ -200,7 +218,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("Test verify sync config default tls value", t, func(c C) {
@ -217,7 +235,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
err = cli.NewRootCmd().Execute()
err = cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
@ -233,7 +251,7 @@ func TestVerify(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "verify", tmpfile.Name()}
err = cli.NewRootCmd().Execute()
err = cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
}
@ -252,19 +270,19 @@ func TestScrub(t *testing.T) {
Convey("Test scrub help", t, func(c C) {
os.Args = []string{"cli_test", "scrub", "-h"}
err := cli.NewRootCmd().Execute()
err := cli.NewServerRootCmd().Execute()
So(err, ShouldBeNil)
})
Convey("Test scrub config", t, func(c C) {
Convey("non-existent config", func(c C) {
os.Args = []string{"cli_test", "scrub", path.Join(os.TempDir(), "/x.yaml")}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("unknown config", func(c C) {
os.Args = []string{"cli_test", "scrub", path.Join(os.TempDir(), "/x")}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("bad config", func(c C) {
@ -277,7 +295,7 @@ func TestScrub(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "scrub", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("server is running", func(c C) {
@ -331,7 +349,7 @@ func TestScrub(t *testing.T) {
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "scrub", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
defer func(controller *api.Controller) {
ctx := context.Background()
@ -362,7 +380,7 @@ func TestScrub(t *testing.T) {
err = tmpfile.Close()
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "scrub", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
Convey("bad index.json", func(c C) {
@ -420,7 +438,7 @@ func TestScrub(t *testing.T) {
So(err, ShouldBeNil)
os.Args = []string{"cli_test", "scrub", tmpfile.Name()}
So(func() { _ = cli.NewRootCmd().Execute() }, ShouldPanic)
So(func() { _ = cli.NewServerRootCmd().Execute() }, ShouldPanic)
})
})
}