-
Notifications
You must be signed in to change notification settings - Fork 205
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #146 from carolynvs/manifest-schema
Add porter schema root command
- Loading branch information
Showing
23 changed files
with
555 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/deislabs/porter/pkg/porter" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func buildSchemaCommand(p *porter.Porter) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "schema", | ||
Short: "Print the JSON schema for the Porter manifest", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return p.PrintManifestSchema() | ||
}, | ||
} | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,38 @@ | ||
package config | ||
|
||
import "fmt" | ||
import ( | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
type Action string | ||
|
||
const ( | ||
ActionInstall Action = "install" | ||
ActionUpgrade Action = "upgrade" | ||
ActionUninstall Action = "uninstall" | ||
ActionInstall Action = "install" | ||
ActionUpgrade Action = "upgrade" | ||
ActionUninstall Action = "uninstall" | ||
ErrInvalidAction string = "invalid action" | ||
) | ||
|
||
// IsSupportedAction determines if the value is an action supported by Porter. | ||
func IsSupportedAction(value string) bool { | ||
_, err := ParseAction(value) | ||
return err == nil | ||
} | ||
|
||
// ParseAction converts a string into an Action, or returns an error message. | ||
func ParseAction(value string) (Action, error) { | ||
action := Action(value) | ||
switch action { | ||
case ActionInstall, ActionUpgrade, ActionUninstall: | ||
return action, nil | ||
default: | ||
return "", fmt.Errorf("invalid action %q", value) | ||
return "", fmt.Errorf("%s %q", ErrInvalidAction, value) | ||
} | ||
} | ||
|
||
// IsInvalidActionError determines if an error is the error returned by ParseAction when | ||
// a value isn't a valid action. | ||
func IsInvalidActionError(err error) bool { | ||
return strings.HasPrefix(err.Error(), ErrInvalidAction) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package config | ||
|
||
import "testing" | ||
|
||
func TestIsSupportedAction(t *testing.T) { | ||
testcases := map[string]bool{ | ||
"install": true, | ||
"upgrade": true, | ||
"uninstall": true, | ||
"status": false, | ||
"INSTALL": false, | ||
} | ||
|
||
for action, wantSupported := range testcases { | ||
t.Run(action, func(t *testing.T) { | ||
gotSupported := IsSupportedAction(action) | ||
if wantSupported != gotSupported { | ||
t.Fatalf("IsSupportedAction(%q) failed, want %t, got %t", action, wantSupported, gotSupported) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
//go:generate packr2 | ||
|
||
package exec | ||
|
||
import ( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package exec | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/deislabs/porter/pkg/test" | ||
) | ||
|
||
// sad hack: not sure how to make a common test main for all my subpackages | ||
func TestMain(m *testing.M) { | ||
test.TestMainWithMockedCommandHandlers(m) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package mixin | ||
|
||
// Metadata about a mixin | ||
type Metadata struct { | ||
// Mixin Name | ||
Name string | ||
// Mixin Directory | ||
Dir string | ||
// Path to the client executable | ||
ClientPath string | ||
// Version | ||
// Repository or Source (where did it come from) | ||
// Author | ||
// Is it up to date | ||
// etc | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package mixinprovider | ||
|
||
import ( | ||
"bytes" | ||
"io/ioutil" | ||
"path/filepath" | ||
|
||
"github.com/deislabs/porter/pkg/config" | ||
"github.com/deislabs/porter/pkg/context" | ||
"github.com/deislabs/porter/pkg/mixin" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
func NewFileSystem(config *config.Config) *FileSystem { | ||
return &FileSystem{ | ||
Config: config, | ||
} | ||
} | ||
|
||
type FileSystem struct { | ||
*config.Config | ||
} | ||
|
||
func (p *FileSystem) GetMixins() ([]mixin.Metadata, error) { | ||
mixinsDir, err := p.GetMixinsDir() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
files, err := p.FileSystem.ReadDir(mixinsDir) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "could not list the contents of the mixins directory %q", mixinsDir) | ||
} | ||
|
||
mixins := make([]mixin.Metadata, 0, len(files)) | ||
for _, file := range files { | ||
if !file.IsDir() { | ||
continue | ||
} | ||
|
||
mixinDir := filepath.Join(mixinsDir, file.Name()) | ||
mixins = append(mixins, mixin.Metadata{ | ||
Name: file.Name(), | ||
ClientPath: filepath.Join(mixinDir, file.Name()), | ||
Dir: mixinDir, | ||
}) | ||
} | ||
|
||
return mixins, nil | ||
} | ||
|
||
func (p *FileSystem) GetMixinSchema(m mixin.Metadata) (string, error) { | ||
r := mixin.NewRunner(m.Name, m.Dir, false) | ||
r.Command = "schema" | ||
|
||
// Copy the existing context and tweak to pipe the output differently | ||
mixinSchema := &bytes.Buffer{} | ||
var mixinContext context.Context | ||
mixinContext = *p.Context | ||
mixinContext.Out = mixinSchema | ||
if !p.Debug { | ||
mixinContext.Err = ioutil.Discard | ||
} | ||
r.Context = &mixinContext | ||
|
||
err := r.Run() | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return mixinSchema.String(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package mixinprovider | ||
|
||
import ( | ||
"io/ioutil" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/deislabs/porter/pkg/config" | ||
"github.com/deislabs/porter/pkg/mixin" | ||
"github.com/spf13/afero" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestFileSystem_GetMixins(t *testing.T) { | ||
// Do this in a temp directory so that we can control which mixins show up in the list | ||
os.Setenv(config.EnvHOME, os.TempDir()) | ||
defer os.Unsetenv(config.EnvHOME) | ||
|
||
c := config.NewTestConfig(t) | ||
c.FileSystem = &afero.Afero{Fs: afero.NewOsFs()} // Hit the real file system for this test | ||
|
||
mixinsDir, err := c.GetMixinsDir() | ||
require.Nil(t, err) | ||
|
||
// Just copy in the exec and helm mixins | ||
srcMixinsDir := filepath.Join(c.TestContext.FindBinDir(), "mixins") | ||
c.CopyDirectory(filepath.Join(srcMixinsDir, "helm"), mixinsDir, true) | ||
c.CopyDirectory(filepath.Join(srcMixinsDir, "exec"), mixinsDir, true) | ||
|
||
p := NewFileSystem(c.Config) | ||
mixins, err := p.GetMixins() | ||
|
||
require.Nil(t, err) | ||
require.Len(t, mixins, 2) | ||
assert.Equal(t, mixins[0].Name, "exec") | ||
assert.Equal(t, mixins[1].Name, "helm") | ||
|
||
dir, err := os.Stat(mixins[0].Dir) | ||
require.NoError(t, err) | ||
assert.True(t, dir.IsDir()) | ||
assert.Equal(t, dir.Name(), "exec") | ||
|
||
binary, err := os.Stat(mixins[0].ClientPath) | ||
require.NoError(t, err) | ||
assert.True(t, binary.Mode().IsRegular()) | ||
assert.Equal(t, binary.Name(), "exec") | ||
} | ||
|
||
func TestFileSystem_GetMixinSchema(t *testing.T) { | ||
c := config.NewTestConfig(t) | ||
// Hit the real file system for this test | ||
c.FileSystem = &afero.Afero{Fs: afero.NewOsFs()} | ||
c.NewCommand = exec.Command | ||
|
||
// bin is my home now | ||
binDir := c.TestContext.FindBinDir() | ||
os.Setenv(config.EnvHOME, binDir) | ||
defer os.Unsetenv(config.EnvHOME) | ||
|
||
p := NewFileSystem(c.Config) | ||
mixins, err := p.GetMixins() | ||
require.NoError(t, err) | ||
|
||
var e *mixin.Metadata | ||
for _, m := range mixins { | ||
if m.Name == "exec" { | ||
e = &m | ||
break | ||
} | ||
} | ||
require.NotNil(t, e) | ||
|
||
gotSchema, err := p.GetMixinSchema(*e) | ||
require.NoError(t, err) | ||
|
||
wantSchema, err := ioutil.ReadFile("../../exec/testdata/schema.json") | ||
require.NoError(t, err) | ||
|
||
assert.Equal(t, string(wantSchema), string(gotSchema)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.