Signed-off-by: Daniel Nephin <dnephin@docker.com>
| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,69 +0,0 @@ |
| 1 |
-package bundlefile |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "encoding/json" |
|
| 5 |
- "fmt" |
|
| 6 |
- "io" |
|
| 7 |
-) |
|
| 8 |
- |
|
| 9 |
-// Bundlefile stores the contents of a bundlefile |
|
| 10 |
-type Bundlefile struct {
|
|
| 11 |
- Version string |
|
| 12 |
- Services map[string]Service |
|
| 13 |
-} |
|
| 14 |
- |
|
| 15 |
-// Service is a service from a bundlefile |
|
| 16 |
-type Service struct {
|
|
| 17 |
- Image string |
|
| 18 |
- Command []string `json:",omitempty"` |
|
| 19 |
- Args []string `json:",omitempty"` |
|
| 20 |
- Env []string `json:",omitempty"` |
|
| 21 |
- Labels map[string]string `json:",omitempty"` |
|
| 22 |
- Ports []Port `json:",omitempty"` |
|
| 23 |
- WorkingDir *string `json:",omitempty"` |
|
| 24 |
- User *string `json:",omitempty"` |
|
| 25 |
- Networks []string `json:",omitempty"` |
|
| 26 |
-} |
|
| 27 |
- |
|
| 28 |
-// Port is a port as defined in a bundlefile |
|
| 29 |
-type Port struct {
|
|
| 30 |
- Protocol string |
|
| 31 |
- Port uint32 |
|
| 32 |
-} |
|
| 33 |
- |
|
| 34 |
-// LoadFile loads a bundlefile from a path to the file |
|
| 35 |
-func LoadFile(reader io.Reader) (*Bundlefile, error) {
|
|
| 36 |
- bundlefile := &Bundlefile{}
|
|
| 37 |
- |
|
| 38 |
- decoder := json.NewDecoder(reader) |
|
| 39 |
- if err := decoder.Decode(bundlefile); err != nil {
|
|
| 40 |
- switch jsonErr := err.(type) {
|
|
| 41 |
- case *json.SyntaxError: |
|
| 42 |
- return nil, fmt.Errorf( |
|
| 43 |
- "JSON syntax error at byte %v: %s", |
|
| 44 |
- jsonErr.Offset, |
|
| 45 |
- jsonErr.Error()) |
|
| 46 |
- case *json.UnmarshalTypeError: |
|
| 47 |
- return nil, fmt.Errorf( |
|
| 48 |
- "Unexpected type at byte %v. Expected %s but received %s.", |
|
| 49 |
- jsonErr.Offset, |
|
| 50 |
- jsonErr.Type, |
|
| 51 |
- jsonErr.Value) |
|
| 52 |
- } |
|
| 53 |
- return nil, err |
|
| 54 |
- } |
|
| 55 |
- |
|
| 56 |
- return bundlefile, nil |
|
| 57 |
-} |
|
| 58 |
- |
|
| 59 |
-// Print writes the contents of the bundlefile to the output writer |
|
| 60 |
-// as human readable json |
|
| 61 |
-func Print(out io.Writer, bundle *Bundlefile) error {
|
|
| 62 |
- bytes, err := json.MarshalIndent(*bundle, "", " ") |
|
| 63 |
- if err != nil {
|
|
| 64 |
- return err |
|
| 65 |
- } |
|
| 66 |
- |
|
| 67 |
- _, err = out.Write(bytes) |
|
| 68 |
- return err |
|
| 69 |
-} |
| 70 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,77 +0,0 @@ |
| 1 |
-package bundlefile |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "bytes" |
|
| 5 |
- "strings" |
|
| 6 |
- "testing" |
|
| 7 |
- |
|
| 8 |
- "github.com/docker/docker/pkg/testutil/assert" |
|
| 9 |
-) |
|
| 10 |
- |
|
| 11 |
-func TestLoadFileV01Success(t *testing.T) {
|
|
| 12 |
- reader := strings.NewReader(`{
|
|
| 13 |
- "Version": "0.1", |
|
| 14 |
- "Services": {
|
|
| 15 |
- "redis": {
|
|
| 16 |
- "Image": "redis@sha256:4b24131101fa0117bcaa18ac37055fffd9176aa1a240392bb8ea85e0be50f2ce", |
|
| 17 |
- "Networks": ["default"] |
|
| 18 |
- }, |
|
| 19 |
- "web": {
|
|
| 20 |
- "Image": "dockercloud/hello-world@sha256:fe79a2cfbd17eefc344fb8419420808df95a1e22d93b7f621a7399fd1e9dca1d", |
|
| 21 |
- "Networks": ["default"], |
|
| 22 |
- "User": "web" |
|
| 23 |
- } |
|
| 24 |
- } |
|
| 25 |
- }`) |
|
| 26 |
- |
|
| 27 |
- bundle, err := LoadFile(reader) |
|
| 28 |
- assert.NilError(t, err) |
|
| 29 |
- assert.Equal(t, bundle.Version, "0.1") |
|
| 30 |
- assert.Equal(t, len(bundle.Services), 2) |
|
| 31 |
-} |
|
| 32 |
- |
|
| 33 |
-func TestLoadFileSyntaxError(t *testing.T) {
|
|
| 34 |
- reader := strings.NewReader(`{
|
|
| 35 |
- "Version": "0.1", |
|
| 36 |
- "Services": unquoted string |
|
| 37 |
- }`) |
|
| 38 |
- |
|
| 39 |
- _, err := LoadFile(reader) |
|
| 40 |
- assert.Error(t, err, "syntax error at byte 37: invalid character 'u'") |
|
| 41 |
-} |
|
| 42 |
- |
|
| 43 |
-func TestLoadFileTypeError(t *testing.T) {
|
|
| 44 |
- reader := strings.NewReader(`{
|
|
| 45 |
- "Version": "0.1", |
|
| 46 |
- "Services": {
|
|
| 47 |
- "web": {
|
|
| 48 |
- "Image": "redis", |
|
| 49 |
- "Networks": "none" |
|
| 50 |
- } |
|
| 51 |
- } |
|
| 52 |
- }`) |
|
| 53 |
- |
|
| 54 |
- _, err := LoadFile(reader) |
|
| 55 |
- assert.Error(t, err, "Unexpected type at byte 94. Expected []string but received string") |
|
| 56 |
-} |
|
| 57 |
- |
|
| 58 |
-func TestPrint(t *testing.T) {
|
|
| 59 |
- var buffer bytes.Buffer |
|
| 60 |
- bundle := &Bundlefile{
|
|
| 61 |
- Version: "0.1", |
|
| 62 |
- Services: map[string]Service{
|
|
| 63 |
- "web": {
|
|
| 64 |
- Image: "image", |
|
| 65 |
- Command: []string{"echo", "something"},
|
|
| 66 |
- }, |
|
| 67 |
- }, |
|
| 68 |
- } |
|
| 69 |
- assert.NilError(t, Print(&buffer, bundle)) |
|
| 70 |
- output := buffer.String() |
|
| 71 |
- assert.Contains(t, output, "\"Image\": \"image\"") |
|
| 72 |
- assert.Contains(t, output, |
|
| 73 |
- `"Command": [ |
|
| 74 |
- "echo", |
|
| 75 |
- "something" |
|
| 76 |
- ]`) |
|
| 77 |
-} |
| ... | ... |
@@ -1,48 +1,11 @@ |
| 1 | 1 |
package stack |
| 2 | 2 |
|
| 3 |
-import ( |
|
| 4 |
- "fmt" |
|
| 5 |
- "io" |
|
| 6 |
- "os" |
|
| 7 |
- |
|
| 8 |
- "github.com/docker/docker/cli/command/bundlefile" |
|
| 9 |
- "github.com/spf13/pflag" |
|
| 10 |
-) |
|
| 3 |
+import "github.com/spf13/pflag" |
|
| 11 | 4 |
|
| 12 | 5 |
func addComposefileFlag(opt *string, flags *pflag.FlagSet) {
|
| 13 | 6 |
flags.StringVar(opt, "compose-file", "", "Path to a Compose file") |
| 14 | 7 |
} |
| 15 | 8 |
|
| 16 |
-func addBundlefileFlag(opt *string, flags *pflag.FlagSet) {
|
|
| 17 |
- flags.StringVar(opt, "bundle-file", "", "Path to a Distributed Application Bundle file") |
|
| 18 |
-} |
|
| 19 |
- |
|
| 20 | 9 |
func addRegistryAuthFlag(opt *bool, flags *pflag.FlagSet) {
|
| 21 | 10 |
flags.BoolVar(opt, "with-registry-auth", false, "Send registry authentication details to Swarm agents") |
| 22 | 11 |
} |
| 23 |
- |
|
| 24 |
-func loadBundlefile(stderr io.Writer, namespace string, path string) (*bundlefile.Bundlefile, error) {
|
|
| 25 |
- defaultPath := fmt.Sprintf("%s.dab", namespace)
|
|
| 26 |
- |
|
| 27 |
- if path == "" {
|
|
| 28 |
- path = defaultPath |
|
| 29 |
- } |
|
| 30 |
- if _, err := os.Stat(path); err != nil {
|
|
| 31 |
- return nil, fmt.Errorf( |
|
| 32 |
- "Bundle %s not found. Specify the path with --file", |
|
| 33 |
- path) |
|
| 34 |
- } |
|
| 35 |
- |
|
| 36 |
- fmt.Fprintf(stderr, "Loading bundle from %s\n", path) |
|
| 37 |
- reader, err := os.Open(path) |
|
| 38 |
- if err != nil {
|
|
| 39 |
- return nil, err |
|
| 40 |
- } |
|
| 41 |
- defer reader.Close() |
|
| 42 |
- |
|
| 43 |
- bundle, err := bundlefile.LoadFile(reader) |
|
| 44 |
- if err != nil {
|
|
| 45 |
- return nil, fmt.Errorf("Error reading %s: %v\n", path, err)
|
|
| 46 |
- } |
|
| 47 |
- return bundle, err |
|
| 48 |
-} |