From 686b1870675337f8f2ac71be767e3385c9bef5de Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Fri, 9 Jan 2015 12:13:25 +0000 Subject: [PATCH 1/5] contrib/podex: remove logging --- contrib/podex/podex.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/contrib/podex/podex.go b/contrib/podex/podex.go index 5f0ee3679fa..ab69f7708f9 100644 --- a/contrib/podex/podex.go +++ b/contrib/podex/podex.go @@ -28,11 +28,9 @@ limitations under the License. package main import ( - "bytes" "encoding/json" "flag" "fmt" - "io/ioutil" "log" "net/http" "os" @@ -215,11 +213,8 @@ func getImageMetadata(host, namespace, repo, tag string) (*imageMetadata, error) if err != nil { return nil, fmt.Errorf("error getting json for image %q: %v", imageID, err) } - data, _ := ioutil.ReadAll(resp.Body) - buf := bytes.NewBuffer(data) - log.Print(string(data)) var image imageMetadata - if err := json.NewDecoder(buf).Decode(&image); err != nil { + if err := json.NewDecoder(resp.Body).Decode(&image); err != nil { return nil, fmt.Errorf("error decoding image %q metadata: %v", imageID, err) } return &image, nil From 1f0d0cdc31dd9152353cbf8927d219238168fef4 Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Fri, 9 Jan 2015 14:54:54 +0000 Subject: [PATCH 2/5] contrib/podex: switch to go-yaml to manage ordering --- contrib/podex/podex.go | 85 ++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/contrib/podex/podex.go b/contrib/podex/podex.go index ab69f7708f9..2039370a26f 100644 --- a/contrib/podex/podex.go +++ b/contrib/podex/podex.go @@ -37,15 +37,17 @@ import ( "strconv" "strings" - "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/ghodss/yaml" + goyaml "gopkg.in/v2/yaml" ) -const usage = "usage: podex [-json|-yaml] [-id PODNAME] IMAGES" +const usage = "usage: podex [-yaml|-json] [-pod|-container] [-id PODNAME] IMAGES..." -var generateJSON = flag.Bool("json", false, "generate json manifest") var generateYAML = flag.Bool("yaml", false, "generate yaml manifest") -var podName = flag.String("id", "", "set pod name") +var generateJSON = flag.Bool("json", false, "generate json manifest") +var pod = flag.Bool("pod", false, "generate pod manifest") +var container = flag.Bool("container", false, "generate container manifest") +var id = flag.String("id", "", "set id") type image struct { Host string @@ -60,26 +62,26 @@ func main() { if flag.NArg() < 1 { log.Fatal(usage) } - if *podName == "" { + if *id == "" { if flag.NArg() > 1 { log.Print(usage) log.Fatal("podex: -id arg is required when passing more than one image") } - _, _, *podName, _ = splitDockerImageName(flag.Arg(0)) + _, _, *id, _ = splitDockerImageName(flag.Arg(0)) } - if (!*generateJSON && !*generateYAML) || (*generateJSON && *generateYAML) { + if (!*generateYAML && !*generateJSON) || (*generateYAML && *generateJSON) || (!*pod && !*container) || (*pod && *container) { log.Fatal(usage) } - podContainers := []v1beta1.Container{} + podContainers := []goyaml.MapSlice{} for _, imageName := range flag.Args() { host, namespace, repo, tag := splitDockerImageName(imageName) - container := v1beta1.Container{ - Name: repo, - Image: imageName, + container := goyaml.MapSlice{ + {Key: "name", Value: repo}, + {Key: "image", Value: imageName}, } img, err := getImageMetadata(host, namespace, repo, tag) @@ -87,44 +89,63 @@ func main() { if err != nil { log.Fatalf("failed to get image metadata %q: %v", imageName, err) } + portSlice := []goyaml.MapSlice{} for p := range img.ContainerConfig.ExposedPorts { port, err := strconv.Atoi(p.Port()) if err != nil { log.Fatalf("failed to parse port %q: %v", p.Port(), err) } - container.Ports = append(container.Ports, v1beta1.Port{ - Name: strings.Join([]string{repo, p.Proto(), p.Port()}, "-"), - ContainerPort: port, - Protocol: v1beta1.Protocol(strings.ToUpper(p.Proto())), - }) + portEntry := goyaml.MapSlice{{ + Key: "name", Value: strings.Join([]string{repo, p.Proto(), p.Port()}, "-")}, {Key: "containerPort", Value: port}} + portSlice = append(portSlice, portEntry) + if p.Proto() != "tcp" { + portEntry = append(portEntry, goyaml.MapItem{Key: "protocol", Value: strings.ToUpper(p.Proto())}) + } + } + if len(img.ContainerConfig.ExposedPorts) > 0 { + container = append(container, goyaml.MapItem{Key: "ports", Value: portSlice}) } podContainers = append(podContainers, container) } // TODO(proppy): add flag to handle multiple version - manifest := v1beta1.ContainerManifest{ - Version: "v1beta1", - ID: *podName + "-pod", - Containers: podContainers, - RestartPolicy: v1beta1.RestartPolicy{ - Always: &v1beta1.RestartPolicyAlways{}, - }, + containerManifest := goyaml.MapSlice{ + {Key: "version", Value: "v1beta1"}, + {Key: "containers", Value: podContainers}, } - if *generateJSON { - bs, err := json.MarshalIndent(manifest, "", " ") - if err != nil { - log.Fatalf("failed to render JSON container manifest: %v", err) + var data interface{} + + switch { + case *container: + containerManifest = append(goyaml.MapSlice{ + {Key: "id", Value: *id}, + }, containerManifest...) + data = containerManifest + case *pod: + data = goyaml.MapSlice{ + {Key: "id", Value: *id}, + {Key: "kind", Value: "Pod"}, + {Key: "apiVersion", Value: "v1beta1"}, + {Key: "desiredState", Value: goyaml.MapSlice{ + {Key: "manifest", Value: containerManifest}, + }}, } - os.Stdout.Write(bs) } - if *generateYAML { - bs, err := yaml.Marshal(manifest) + + bs, err := goyaml.Marshal(data) + if err != nil { + log.Fatalf("failed to marshal container manifest: %v", err) + } + + switch { + case *generateJSON: + bs, err = yaml.YAMLToJSON(bs) if err != nil { - log.Fatalf("failed to render YAML container manifest: %v", err) + log.Fatalf("failed to marshal container manifest into JSON: %v", err) } - os.Stdout.Write(bs) } + os.Stdout.Write(bs) } // splitDockerImageName split a docker image name of the form [HOST/][NAMESPACE/]REPOSITORY[:TAG] From f133c118cfd68a9f05647b725ba7b7fe846e3af4 Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Fri, 9 Jan 2015 15:03:12 +0000 Subject: [PATCH 3/5] contrib/podex: make flags optional --- contrib/podex/podex.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/contrib/podex/podex.go b/contrib/podex/podex.go index 2039370a26f..b416107161e 100644 --- a/contrib/podex/podex.go +++ b/contrib/podex/podex.go @@ -43,10 +43,10 @@ import ( const usage = "usage: podex [-yaml|-json] [-pod|-container] [-id PODNAME] IMAGES..." -var generateYAML = flag.Bool("yaml", false, "generate yaml manifest") +var generateYAML = flag.Bool("yaml", true, "generate yaml manifest (default)") var generateJSON = flag.Bool("json", false, "generate json manifest") -var pod = flag.Bool("pod", false, "generate pod manifest") -var container = flag.Bool("container", false, "generate container manifest") +var generatePod = flag.Bool("pod", true, "generate pod manifest (default)") +var generateContainer = flag.Bool("container", false, "generate container manifest") var id = flag.String("id", "", "set id") type image struct { @@ -70,8 +70,11 @@ func main() { _, _, *id, _ = splitDockerImageName(flag.Arg(0)) } - if (!*generateYAML && !*generateJSON) || (*generateYAML && *generateJSON) || (!*pod && !*container) || (*pod && *container) { - log.Fatal(usage) + if *generateJSON { + *generateYAML = false + } + if *generateContainer { + *generatePod = false } podContainers := []goyaml.MapSlice{} @@ -117,12 +120,12 @@ func main() { var data interface{} switch { - case *container: + case *generateContainer: containerManifest = append(goyaml.MapSlice{ {Key: "id", Value: *id}, }, containerManifest...) data = containerManifest - case *pod: + case *generatePod: data = goyaml.MapSlice{ {Key: "id", Value: *id}, {Key: "kind", Value: "Pod"}, @@ -138,8 +141,7 @@ func main() { log.Fatalf("failed to marshal container manifest: %v", err) } - switch { - case *generateJSON: + if *generateJSON { bs, err = yaml.YAMLToJSON(bs) if err != nil { log.Fatalf("failed to marshal container manifest into JSON: %v", err) From 8655d7cd07c5023a3f5ef7a9d5dfd7136f118091 Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Wed, 14 Jan 2015 01:52:55 +0000 Subject: [PATCH 4/5] contrib/podex: switch bool flags to strings --- contrib/podex/podex.go | 68 +++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/contrib/podex/podex.go b/contrib/podex/podex.go index b416107161e..5b41a72058e 100644 --- a/contrib/podex/podex.go +++ b/contrib/podex/podex.go @@ -28,9 +28,11 @@ limitations under the License. package main import ( + "bytes" "encoding/json" "flag" "fmt" + "io" "log" "net/http" "os" @@ -41,13 +43,18 @@ import ( goyaml "gopkg.in/v2/yaml" ) -const usage = "usage: podex [-yaml|-json] [-pod|-container] [-id PODNAME] IMAGES..." +const usage = "podex [-format=yaml|json] [-type=pod|container] [-id NAME] IMAGES..." -var generateYAML = flag.Bool("yaml", true, "generate yaml manifest (default)") -var generateJSON = flag.Bool("json", false, "generate json manifest") -var generatePod = flag.Bool("pod", true, "generate pod manifest (default)") -var generateContainer = flag.Bool("container", false, "generate container manifest") -var id = flag.String("id", "", "set id") +var manifestFormat = flag.String("format", "yaml", "manifest format to output, `yaml` or `json`") +var manifestType = flag.String("type", "pod", "manifest type to output, `pod` or `container`") +var manifestId = flag.String("id", "", "manifest id, default to image base name") + +func init() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage: %s\n", usage) + flag.PrintDefaults() + } +} type image struct { Host string @@ -60,21 +67,15 @@ func main() { flag.Parse() if flag.NArg() < 1 { - log.Fatal(usage) + flag.Usage() + log.Fatal("pod: missing image argument") } - if *id == "" { + if *manifestId == "" { if flag.NArg() > 1 { - log.Print(usage) + flag.Usage() log.Fatal("podex: -id arg is required when passing more than one image") } - _, _, *id, _ = splitDockerImageName(flag.Arg(0)) - } - - if *generateJSON { - *generateYAML = false - } - if *generateContainer { - *generatePod = false + _, _, *manifestId, _ = splitDockerImageName(flag.Arg(0)) } podContainers := []goyaml.MapSlice{} @@ -113,41 +114,54 @@ func main() { // TODO(proppy): add flag to handle multiple version containerManifest := goyaml.MapSlice{ - {Key: "version", Value: "v1beta1"}, + {Key: "version", Value: "v1beta2"}, {Key: "containers", Value: podContainers}, } var data interface{} - switch { - case *generateContainer: + switch *manifestType { + case "container": containerManifest = append(goyaml.MapSlice{ - {Key: "id", Value: *id}, + {Key: "id", Value: *manifestId}, }, containerManifest...) data = containerManifest - case *generatePod: + case "pod": data = goyaml.MapSlice{ - {Key: "id", Value: *id}, + {Key: "id", Value: *manifestId}, {Key: "kind", Value: "Pod"}, {Key: "apiVersion", Value: "v1beta1"}, {Key: "desiredState", Value: goyaml.MapSlice{ {Key: "manifest", Value: containerManifest}, }}, } + default: + flag.Usage() + log.Fatalf("unsupported manifest type %q", *manifestType) } - bs, err := goyaml.Marshal(data) + yamlBytes, err := goyaml.Marshal(data) if err != nil { log.Fatalf("failed to marshal container manifest: %v", err) } - if *generateJSON { - bs, err = yaml.YAMLToJSON(bs) + switch *manifestFormat { + case "yaml": + os.Stdout.Write(yamlBytes) + case "json": + jsonBytes, err := yaml.YAMLToJSON(yamlBytes) if err != nil { log.Fatalf("failed to marshal container manifest into JSON: %v", err) } + var jsonPretty bytes.Buffer + if err := json.Indent(&jsonPretty, jsonBytes, "", " "); err != nil { + log.Fatalf("failed to indent json %q: %v", string(jsonBytes), err) + } + io.Copy(os.Stdout, &jsonPretty) + default: + flag.Usage() + log.Fatalf("unsupported manifest format %q", *manifestFormat) } - os.Stdout.Write(bs) } // splitDockerImageName split a docker image name of the form [HOST/][NAMESPACE/]REPOSITORY[:TAG] From 363ce1b39a516b9d1c4e42500b1ab0752ab7df23 Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Fri, 16 Jan 2015 11:54:11 +0100 Subject: [PATCH 5/5] contrib: fix name and readability, exclude from test --- contrib/podex/podex.go | 17 +++++++++++------ hack/test-go.sh | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/contrib/podex/podex.go b/contrib/podex/podex.go index 5b41a72058e..9c9110af215 100644 --- a/contrib/podex/podex.go +++ b/contrib/podex/podex.go @@ -47,7 +47,7 @@ const usage = "podex [-format=yaml|json] [-type=pod|container] [-id NAME] IMAGES var manifestFormat = flag.String("format", "yaml", "manifest format to output, `yaml` or `json`") var manifestType = flag.String("type", "pod", "manifest type to output, `pod` or `container`") -var manifestId = flag.String("id", "", "manifest id, default to image base name") +var manifestName = flag.String("name", "", "manifest name, default to image base name") func init() { flag.Usage = func() { @@ -70,12 +70,12 @@ func main() { flag.Usage() log.Fatal("pod: missing image argument") } - if *manifestId == "" { + if *manifestName == "" { if flag.NArg() > 1 { flag.Usage() log.Fatal("podex: -id arg is required when passing more than one image") } - _, _, *manifestId, _ = splitDockerImageName(flag.Arg(0)) + _, _, *manifestName, _ = splitDockerImageName(flag.Arg(0)) } podContainers := []goyaml.MapSlice{} @@ -100,7 +100,12 @@ func main() { log.Fatalf("failed to parse port %q: %v", p.Port(), err) } portEntry := goyaml.MapSlice{{ - Key: "name", Value: strings.Join([]string{repo, p.Proto(), p.Port()}, "-")}, {Key: "containerPort", Value: port}} + Key: "name", + Value: strings.Join([]string{repo, p.Proto(), p.Port()}, "-"), + }, { + Key: "containerPort", + Value: port, + }} portSlice = append(portSlice, portEntry) if p.Proto() != "tcp" { portEntry = append(portEntry, goyaml.MapItem{Key: "protocol", Value: strings.ToUpper(p.Proto())}) @@ -123,12 +128,12 @@ func main() { switch *manifestType { case "container": containerManifest = append(goyaml.MapSlice{ - {Key: "id", Value: *manifestId}, + {Key: "id", Value: *manifestName}, }, containerManifest...) data = containerManifest case "pod": data = goyaml.MapSlice{ - {Key: "id", Value: *manifestId}, + {Key: "id", Value: *manifestName}, {Key: "kind", Value: "Pod"}, {Key: "apiVersion", Value: "v1beta1"}, {Key: "desiredState", Value: goyaml.MapSlice{ diff --git a/hack/test-go.sh b/hack/test-go.sh index e82a70edebb..ba767adb437 100755 --- a/hack/test-go.sh +++ b/hack/test-go.sh @@ -34,6 +34,7 @@ kube::test::find_dirs() { -o -wholename './target' \ -o -wholename '*/third_party/*' \ -o -wholename '*/Godeps/*' \ + -o -wholename '*/contrib/podex/*' \ \) -prune \ \) -name '*_test.go' -print0 | xargs -0n1 dirname | sed 's|^\./||' | sort -u )