Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cmd/bundle): add new bundle build sub-commands #2334

Merged
merged 20 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f1eb8b2
refactor(oci): decouple store from config.OCI
GeorgeMac Nov 3, 2023
5519fd9
refactor(oci): move directory ensuring into store
GeorgeMac Nov 3, 2023
df16b85
feat(cmd/bundle): add new bundle build sub-commands
GeorgeMac Nov 3, 2023
cd79929
fix(cmd/bundle): correct typo in help message
GeorgeMac Nov 3, 2023
b6248a2
fix(oci): walk entire stream of documents
GeorgeMac Nov 3, 2023
706d9ca
chore(oci): remove debug println
GeorgeMac Nov 7, 2023
9bbe22a
test(oci): add more testdata to build case
GeorgeMac Nov 7, 2023
1956955
feat(cmd/flipt): implement bundle list
GeorgeMac Nov 7, 2023
1abc221
feat(cmd): add JSON support to import/export
GeorgeMac Nov 7, 2023
388b885
fix(storage/fs/oci): update source for new oci.Store interface
GeorgeMac Nov 7, 2023
1c8fffd
fix(sql/test): use new import encoding signature
GeorgeMac Nov 7, 2023
59f0d54
chore(oci): make constants for possible schemes
GeorgeMac Nov 7, 2023
9d3165a
chore(ext): remove unnecessary conversions
GeorgeMac Nov 7, 2023
60b57ee
chore(oci): remove uncessary context argument
GeorgeMac Nov 7, 2023
7c8ecdc
test(storage/fs): unknown extension returns an error
GeorgeMac Nov 8, 2023
86bb900
test(storage/fs): ensure count rules returns as expected
GeorgeMac Nov 8, 2023
720ad36
test(storage/fs): ensure walk documents returns expected count
GeorgeMac Nov 8, 2023
5ca0e60
test(storage/fs): add more cases around invalid formats
GeorgeMac Nov 8, 2023
31800d8
chore(bundle): add build use string
GeorgeMac Nov 8, 2023
fc59ef6
fix(storage/fs): dont index beyond slice bounds
GeorgeMac Nov 8, 2023
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 build/testing/testdata/cli.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ $ flipt --config /path/to/config.yml migrate


Available Commands:
bundle Manage Flipt bundles
config Manage Flipt configuration
export Export Flipt data to file/stdout
help Help about any command
Expand Down
106 changes: 106 additions & 0 deletions cmd/flipt/bundle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package main

import (
"fmt"
"os"
"text/tabwriter"

"github.com/spf13/cobra"
"go.flipt.io/flipt/internal/containers"
"go.flipt.io/flipt/internal/oci"
)

type bundleCommand struct{}

func newBundleCommand() *cobra.Command {
bundle := &bundleCommand{}

cmd := &cobra.Command{
Use: "bundle",
Short: "Manage Flipt bundles",
}

cmd.AddCommand(&cobra.Command{
Use: "build",
Short: "Build a bundle",
RunE: bundle.build,
Args: cobra.ExactArgs(1),
})

cmd.AddCommand(&cobra.Command{
Use: "list",
Short: "List all bundles",
RunE: bundle.list,
})

return cmd
}

func (c *bundleCommand) build(cmd *cobra.Command, args []string) error {
store, err := c.getStore()
if err != nil {
return err
}

ref, err := oci.ParseReference(args[0])
if err != nil {
return err
}

bundle, err := store.Build(cmd.Context(), os.DirFS("."), ref)
if err != nil {
return err
}

fmt.Println(bundle.Digest)

return nil
}

func (c *bundleCommand) list(cmd *cobra.Command, args []string) error {
store, err := c.getStore()
if err != nil {
return err
}

bundles, err := store.List(cmd.Context())
if err != nil {
return err
}

wr := writer()

fmt.Fprintf(wr, "DIGEST\tREPO\tTAG\tCREATED\t\n")
for _, bundle := range bundles {
fmt.Fprintf(wr, "%s\t%s\t%s\t%s\t\n", bundle.Digest.Hex()[:7], bundle.Repository, bundle.Tag, bundle.CreatedAt)
}

return wr.Flush()
}

func (c *bundleCommand) getStore() (*oci.Store, error) {
logger, cfg, err := buildConfig()
if err != nil {
return nil, err
}

var opts []containers.Option[oci.StoreOptions]
if cfg := cfg.Storage.OCI; cfg != nil {
if cfg.BundleDirectory != "" {
opts = append(opts, oci.WithBundleDir(cfg.BundleDirectory))
}

if cfg.Authentication != nil {
opts = append(opts, oci.WithCredentials(
cfg.Authentication.Username,
cfg.Authentication.Password,
))
}
}

return oci.NewStore(logger, opts...)
}

func writer() *tabwriter.Writer {
return tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
}
15 changes: 11 additions & 4 deletions cmd/flipt/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"time"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -87,6 +88,7 @@ func (c *exportCommand) run(cmd *cobra.Command, _ []string) error {
// default to stdout
out io.Writer = os.Stdout
logger = zap.Must(zap.NewDevelopment())
enc = ext.EncodingYML
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we give the user the ability to set this format via a CLI flag now that we support JSON? could default to yaml still

Copy link
Member Author

Choose a reason for hiding this comment

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

Ahh yeah I wondered about this. So it will support JSON if you specify a file with .json as the target.
However, for STDOUT, yeah we could have an actual flag. Same for import and STDIN.

)

// export to file
Expand All @@ -103,6 +105,11 @@ func (c *exportCommand) run(cmd *cobra.Command, _ []string) error {
fmt.Fprintf(fi, "# exported by Flipt (%s) on %s\n\n", version, time.Now().UTC().Format(time.RFC3339))

out = fi

if extn := filepath.Ext(c.filename); len(extn) > 0 {
// strip off the leading .
enc = ext.Encoding(extn[1:])
}
}

// Use client when remote address is configured.
Expand All @@ -111,7 +118,7 @@ func (c *exportCommand) run(cmd *cobra.Command, _ []string) error {
if err != nil {
return err
}
return c.export(cmd.Context(), out, client)
return c.export(cmd.Context(), enc, out, client)
}

// Otherwise, go direct to the DB using Flipt configuration file.
Expand All @@ -131,9 +138,9 @@ func (c *exportCommand) run(cmd *cobra.Command, _ []string) error {

defer cleanup()

return c.export(cmd.Context(), out, server)
return c.export(cmd.Context(), enc, out, server)
}

func (c *exportCommand) export(ctx context.Context, dst io.Writer, lister ext.Lister) error {
return ext.NewExporter(lister, c.namespaces, c.allNamespaces).Export(ctx, dst)
func (c *exportCommand) export(ctx context.Context, enc ext.Encoding, dst io.Writer, lister ext.Lister) error {
return ext.NewExporter(lister, c.namespaces, c.allNamespaces).Export(ctx, enc, dst)
}
10 changes: 8 additions & 2 deletions cmd/flipt/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (c *importCommand) run(cmd *cobra.Command, args []string) error {
var (
in io.Reader = os.Stdin
logger = zap.Must(zap.NewDevelopment())
enc = ext.EncodingYML
)

if !c.importStdin {
Expand All @@ -89,6 +90,11 @@ func (c *importCommand) run(cmd *cobra.Command, args []string) error {
defer fi.Close()

in = fi

if extn := filepath.Ext(importFilename); len(extn) > 0 {
// strip off leading .
enc = ext.Encoding(extn[1:])
}
}

// Use client when remote address is configured.
Expand All @@ -97,7 +103,7 @@ func (c *importCommand) run(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
return ext.NewImporter(client).Import(cmd.Context(), in)
return ext.NewImporter(client).Import(cmd.Context(), enc, in)
}

logger, cfg, err := buildConfig()
Expand Down Expand Up @@ -150,5 +156,5 @@ func (c *importCommand) run(cmd *cobra.Command, args []string) error {

return ext.NewImporter(
server,
).Import(cmd.Context(), in)
).Import(cmd.Context(), enc, in)
}
1 change: 1 addition & 0 deletions cmd/flipt/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ func exec() error {
rootCmd.AddCommand(newConfigCommand())
rootCmd.AddCommand(newCompletionCommand())
rootCmd.AddCommand(newDocCommand())
rootCmd.AddCommand(newBundleCommand())

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
Expand Down
11 changes: 7 additions & 4 deletions cmd/flipt/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/spf13/cobra"
"go.flipt.io/flipt/internal/cue"
"go.flipt.io/flipt/internal/storage/fs"
"go.uber.org/zap"
)

type validateCommand struct {
Expand Down Expand Up @@ -43,11 +42,15 @@ func newValidateCommand() *cobra.Command {
}

func (v *validateCommand) run(cmd *cobra.Command, args []string) error {
var err error
logger, _, err := buildConfig()
if err != nil {
return err
}

if len(args) == 0 {
_, err = fs.SnapshotFromFS(zap.NewNop(), os.DirFS("."))
_, err = fs.SnapshotFromFS(logger, os.DirFS("."))
} else {
_, err = fs.SnapshotFromPaths(os.DirFS("."), args...)
_, err = fs.SnapshotFromPaths(logger, os.DirFS("."), args...)
}

errs, ok := cue.Unwrap(err)
Expand Down
14 changes: 0 additions & 14 deletions internal/config/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package config
import (
"errors"
"fmt"
"os"
"path/filepath"
"time"

"github.com/spf13/viper"
Expand Down Expand Up @@ -63,18 +61,6 @@ func (c *StorageConfig) setDefaults(v *viper.Viper) error {
}
case string(OCIStorageType):
v.SetDefault("store.oci.insecure", false)

configDir, err := Dir()
if err != nil {
return fmt.Errorf("setting oci default: %w", err)
}

bundlesDir := filepath.Join(configDir, "bundles")
if err := os.MkdirAll(bundlesDir, 0755); err != nil {
return fmt.Errorf("creating image directory: %w", err)
}

v.SetDefault("store.oci.bundles_directory", bundlesDir)
default:
v.SetDefault("storage.type", "database")
}
Expand Down
Loading
Loading